我正在尝试用Java编写一个简单的2d动画引擎,用于可视化以后的编程项目。但是,我在窗口刷新时遇到问题。在运行时,框架有时会显示空白面板而不是所需图像。这开始时会以明显随机的间隔一次开始几帧,随着程序继续运行而恶化,直到实际图像偶尔闪烁进入视图。运行处理每个帧的代码,但实际上不显示帧中的任何内容。我相信问题可能来自我的电脑而不是我的代码(当然不是来自糟糕的规格),但我不确定。非常感谢。
三节课。代码在这里:
package animator;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.AudioClip;
public class APanel extends JPanel
{
public APanel(int l, int h){
setPreferredSize(new Dimension(l,h));
setLocation(80, 80);
setVisible(true);
setFocusable(true);
}
public Graphics renderFrame(Graphics g){
return g;
}
public void paintComponent(Graphics g) {
requestFocusInWindow();
renderFrame(g);
}
}
package animator;
import java.awt.*;
public class Animator extends APanel
//extending the APanel class allows you to code for different animations
//while leaving the basic functional animator untouched
{
public static final int SCREEN_X = 700;
public static final int SCREEN_Y = 700;
int frameNum;
public Animator() {
super(SCREEN_X, SCREEN_Y);
frameNum = 0;
}
public Graphics renderFrame(Graphics g) {
frameNum++;
g.drawString(""+frameNum,5,12);
return g;
}
}
package animator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Runner {
int framerate = 30;
Animator a = new Animator();
JFrame j = new JFrame();
public Runner(){
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.add(a);
start();
j.setSize(a.getPreferredSize());
j.setVisible(true);
}
public void start() {
Timer t = new Timer(1000/framerate, new ActionListener() {
public void actionPerformed(ActionEvent e){
j.getComponent(0).paint(j.getComponent(0).getGraphics());
//The following line of code keeps the window locked to a preferred size
// j.setSize(j.getComponent(0).getPreferredSize());
}
});
t.start();
}
public static void main(String[] args){
Runner r = new Runner();
}
}
答案 0 :(得分:0)
您的代码中存在一些严重错误,可能是您的问题的原因或因素......
j.setSize(a.getPreferredSize());
无关紧要,只需使用JFrame#pack
即可获得更好的结果,因为它会考虑到框架装饰j.setSize(j.getComponent(0).getPreferredSize());
使用JFrame#setResizable
并将其传递给false
而不是...... j.getComponent(0).paint(j.getComponent(0).getGraphics());
这个!您不负责在Swing中绘制组件,这是RepaintManager
的决定。只需致电j.repaint()
super(SCREEN_X, SCREEN_Y);
...只需覆盖getPreferredSize
方法并返回您想要的尺寸。setLocation(80, 80);
无关紧要,因为该组件受布局管理器控制setVisible(true);
(在APanel
内)...默认情况下,Swing组件已经可见,但窗口和JInternalFrame
s 最后......
public void paintComponent(Graphics g) {
requestFocusInWindow();
renderFrame(g);
}
永远不需要制作这种方法public
,你永远不希望有人能够调用它,这会破坏油漆链,并可能对组件绘制的能力产生严重影响本身就好了。
你必须在执行任何自定义绘画之前调用super.paintComponent
,否则你可能会得到各种精彩的绘画文物和问题
永远不要在paint
方法中修改组件的状态......当它"可能"在您的requestFocusInWindow();
中调用paintComponent
可能会产生您不了解的副作用......
相反,它应该看起来更像......
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
renderFrame(g);
}