java 循环重绘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4120528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
repaint in a loop
提问by Eternal Noob
I am writing a game using Java Swing. I want to paint each time a loop executes with a small delay in between to create a cascade effect on screen. I believe that the efficiency routines in the system are collapsing the calls to repaint()
into a single call. At any rate, the changes all occur at once after the total delay. Is there some way to force the system to repaint immediately and then delay on each iteration of the loop?
我正在使用 Java Swing 编写游戏。我想在每次循环执行时进行绘制,中间有一个小的延迟,以在屏幕上创建级联效果。我相信系统中的效率例程正在将调用折叠repaint()
为单个调用。无论如何,在完全延迟之后,所有变化都会立即发生。有没有办法强制系统立即重新绘制,然后在循环的每次迭代中延迟?
My Code:
我的代码:
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();
}
回答by Cameron Skinner
You can use JComponent.paintImmediately
to force an immediate repaint.
您可以使用JComponent.paintImmediately
强制立即重绘。
EDIT: After reading your question again it occurs to me that you might be executing your logic on the event dispatch thread. This would mean that the repaint requests will not be executed until after your method returns. If you put your code into another thread then that will probably fix the problem and it will be a lot nicer than using 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();
}
It's a bit mucky but hopefully it gives you an idea of where to begin.
它有点脏,但希望它能让你知道从哪里开始。
回答by drekka
Not sure if I'm on the right track here, but is this a thread issue? Because the sleep will be putting the current thread to sleep. So if the repaint is on the current thread, you will be effectively queuing a repaint, holding, then queuing another repaint. Then the method ends and the event processing loop of the graphics thread fires, executing two repaints (collapsed) making everything happen at once.
不确定我在这里是否走在正确的轨道上,但这是一个线程问题吗?因为睡眠将使当前线程进入睡眠状态。因此,如果重绘在当前线程上,您将有效地排队重绘,保持,然后排队另一个重绘。然后该方法结束,图形线程的事件处理循环触发,执行两次重绘(折叠)使所有事情同时发生。
Based on that thought I think you might have two options:
基于这种想法,我认为您可能有两种选择:
Put the code on a second thread so that it doesn't halt the main graphics thread and also because it means that the graphics thread cando a repaint along side the sleep happening.
Before you sleep (not really recommended I would think), trigger the event loop to force the repaint to happen. I'd have to look this up. Cannot remember how to do it off the top of my head. :-)
将代码放在第二个线程上,这样它就不会停止主图形线程,也因为这意味着图形线程可以在睡眠发生的同时重新绘制。
在你睡觉之前(我认为不是真的推荐),触发事件循环以强制重绘发生。我得查一下这个。不记得如何做到这一点了。:-)
I'd probably be looking at #1 as the best option.
我可能会将 #1 视为最佳选择。