我正在使用 Java Swing 编写一个游戏。我想在每次循环执行时进行绘制,中间有一个小的延迟,以在屏幕上创建级联效果。我相信系统中的效率例程将对
repaint()
的调用折叠成单个调用。无论如何,在完全延迟之后,所有变化都会立即发生。是否有某种方法可以强制系统立即重新绘制,然后延迟循环的每次迭代?
我的代码:
for(int i=0;i<10;i++){
JButton[i].setBackground(Color.WHITE);
JButton[i].repaint();
Thread.sleep(2000);
JButton[i].setBackground(Color.GRAY);
JButton[i].repaint();
}
您可以使用
JComponent.paintImmediately
强制立即重新绘制。
编辑:再次阅读您的问题后,我发现您可能正在事件分派线程上执行逻辑。这意味着重绘请求只有在您的方法返回后才会执行。如果您将代码放入另一个线程中,那么这可能会解决问题,并且比使用
paintImmediately
要好得多。
void uiFunction() {
new Thread() {
public void run() {
for(int i = 0; i < 10; i++) {
final JButton b = buttons[i];
SwingUtilities.invokeLater(new Runnable() {
b.setBackground(Color.WHITE);
b.repaint();
}
Thread.sleep(2000);
SwingUtilities.invokeLater(new Runnable() {
b.setBackground(Color.GRAY);
b.repaint();
}
}
}
}.run();
}
这有点混乱,但希望它能让您知道从哪里开始。
不确定我是否走在正确的轨道上,但这是一个线程问题吗?因为 sleep 将使当前线程进入睡眠状态。因此,如果重绘是在当前线程上,那么您将有效地对重绘进行排队,保持,然后对另一个重绘进行排队。然后该方法结束,图形线程的事件处理循环触发,执行两次重绘(折叠),使所有事情同时发生。
基于这个想法,我认为你可能有两种选择:
将代码放在第二个线程上,这样它就不会停止主图形线程,也因为这意味着图形线程可以在睡眠发生的同时进行重新绘制。
在睡觉之前(我认为不太推荐),触发事件循环以强制重新绘制发生。我得查一下这个。我一时想不起怎么做。 :-)
我可能会将#1 视为最佳选择。
我在 Swing 中做了一些动画,并且使用了计时器。有 java.util.Timer 和 javax.swing.Timer。看看两者,看看哪一个最能满足您的需求。