Java paintComponent()仅在最小化屏幕时调用
我正在尝试开发一个游戏,在其中我需要画一个网格。为此,我使用了Java paintComponent()仅在最小化屏幕时调用,java,swing,paintcomponent,repaint,event-dispatch-thread,Java,Swing,Paintcomponent,Repaint,Event Dispatch Thread,我正在尝试开发一个游戏,在其中我需要画一个网格。为此,我使用了paintComponent(Graphics g)方法,该方法由repaint()方法调用 问题是repaint方法在无限While循环中,除非最小化和最大化屏幕,否则它从不调用paintComponent()方法。之后,它工作正常,并在while循环中完美地调用paintComponent() 简而言之,我需要通过最小化最大化屏幕来触发它 有人能帮我吗 在代码中可以看到3个类,即Frame.java、MenuHandler.jav
paintComponent(Graphics g)
方法,该方法由repaint()
方法调用
问题是repaint方法在无限While循环中,除非最小化和最大化屏幕,否则它从不调用paintComponent()
方法。之后,它工作正常,并在while循环中完美地调用paintComponent()
简而言之,我需要通过最小化最大化屏幕来触发它
有人能帮我吗
在代码中可以看到3个类,即Frame.java、MenuHandler.java和Screen.java。代码从Frame类中的main方法开始,并在Screen扩展JPanel时将Screen类添加到自身中。但是,只有当用户在菜单上选择“创建地图”时,控件才会转到Screen类。然后MenuHandler类将控件传递给Screen类,在createMap方法中调用run方法,我在这个run方法中调用repaint方法。
如此包装
public class Screen extends JPanel implements Runnable {
Frame frame;
public Screen(Frame frame) {
this.frame = frame;
}
public void createMap() {
thread.start();
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
}
@Override
public void run() {
System.out.println("Success******");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
}
运行方法中的计时器代码:
public void run() {
System.out.println("Success");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
System.out.println("before repaint");
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
repaint();
}
};
new Timer(200, taskPerformer).start();
System.out.println("after repaint");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
我解决了这个问题。这只是一行代码,我必须添加它来触发paintComponent方法,而不是通过最小化最大化窗口来实现 Frame是我的顶级容器,我正在向Frame添加Screen组件(它扩展了JPanel并实现了paintComponent)。所以,在添加时,早些时候我正在做
frame.add(screen);
我将此更改为:
frame.getContentPane().add(screen);
frame.getContentPane().validate();
添加后调用validate方法为我做到了这一点。我不知道这是否有意义,但是的,这是唯一一条适合我的路线
希望有帮助。“repaint()方法在无限While循环中”
repaint()
应该由Swing计时器触发。这代码似乎阻止了EDT。但是为了更快地获得更好的帮助,发布一个(最小完整可验证示例)。我已经用代码和解释更新了问题。好的,因为它使用了另一个线程,所以它没有阻止EDT,但是它正在尝试从EDT更新GUI,这是另一个禁忌。使用定时器
可确保在EDT上执行更新。我无法编译代码。首先,Frame类中的menubar
变量是什么?它来自哪里?请按照Andrew的建议发布MCVE,并验证即将发布的代码将按原样编译和运行。最好使用Timer,但也可以尝试在SwingUtilities.invokeAndWait()中包装repaint()调用