我目前有一个 JFrame,在它的内容窗格上我以每秒 60 帧的速度从游戏循环中绘制图像。这工作正常,但在右侧,我现在有更多 Swing 元素,当选择内容窗格的某些部分时,我想在这些元素上显示一些信息。该部分是静态 GUI,不使用游戏循环。
我以这种方式更新它:(
public class InfoPanel extends JPanel implements Runnable {
private String titelType = "type: ";
private String type;
private JLabel typeLabel;
private ImageIcon icon;
public void update() {
if (this.icon != null)
this.typeLabel.setIcon(this.icon);
if(this.type != null || this.type != "")
this.typeLabel.setText(this.titelType + this.type);
else
this.typeLabel.setText("");
}
public void run() {
try {
Thread.sleep(150);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.update();
}
此方法仅在玩家实际移动时调用,因此仅调用一次 - 而不是每秒 60 次)
我注意到,当从游戏循环中调用此 update() 方法时,我得到了闪烁的效果。我认为这是因为更新 UI 需要一些时间,所以我决定将其放在一个新线程中。这减少了闪烁,但没有解决问题。
接下来,我决定给予新线程低优先级,因为每秒重绘 60 次的屏幕部分要重要得多。这又减少了闪烁,但它仍然发生。然后,我决定在调用 update() 方法之前在新线程中使用 Thread.sleep(150); ,这完全解决了系统上的闪烁效果。
然而,当在其他系统上运行时,它仍然会发生。不像以前那么频繁(也许每 20 秒一次),但它仍然很烦人。显然,仅在另一个线程中更新 UI 并不能解决问题。
有什么想法可以完全消除闪烁吗?
I currently have a JFrame where on it's content pane I draw images on from a game loop at 60 frames per second. This works fine, but at the right side, I now have more Swing elements on which I want to display some info on when selecting certain parts of the content pane. That part is a static GUI and does not make use of a game loop.
I'm updating it this way:
public class InfoPanel extends JPanel implements Runnable {
private String titelType = "type: ";
private String type;
private JLabel typeLabel;
private ImageIcon icon;
public void update() {
if (this.icon != null)
this.typeLabel.setIcon(this.icon);
if(this.type != null || this.type != "")
this.typeLabel.setText(this.titelType + this.type);
else
this.typeLabel.setText("");
}
public void run() {
try {
Thread.sleep(150);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.update();
}
(this method is only called when the player has actually moved, so it's just called once - not 60 times per second)
I noticed that, when calling this update()-method from the game loop, I get flickering effects. I assume this is because updating the UI takes some time, so I decided to put it in a new thread. This reduced the flickering, but didn't solve it.
Next, I decided to give the new thread low priority as the part of the screen which is redrawed 60 times a second is far more important. This reduced the flickering again, but it still happened. Then, I decided to use Thread.sleep(150);
in the new thread before calling the update()-method, which solved the flickering effect on my system completely.
However, when running it on other systems, it still happens. Not as often as before (maybe one time per 20 seconds), but it's still pretty annoying. Apparantly, just updating the UI in another thread doesn't solve the problem.
Any ideas how to completely eleminate the flickering?
发布评论
评论(2)
调用
SwingUtilities.invokeAndWait()
中的update()
来停止线程并更新 EDT 中的 UI。Call the
update()
inSwingUtilities.invokeAndWait()
which stops the thread and updates UI in EDT.问题是您正在使用 Thread.sleep(int),它会在 EventDispatchTread 期间停止并冻结 GUI。 com/javase/tutorial/uiswing/concurrency/index.html" rel="nofollow noreferrer">Swing 中的并发, 示例使用
Thread.sleep(int 演示冻结 GUI )
, Runnable#Thread 的示例如果你想延迟 Swing 中的任何内容,那么最好的方法是是实现 javax.swing.Timer
Problem is that you are use
Thread.sleep(int)
, that stop and freeze GUI duringEventDispatchTread
more in the Concurency in Swing, example demonstrating freeze GUI by usingThread.sleep(int)
, example for Runnable#ThreadIf you want to delay whatever in Swing then the best way is implements javax.swing.Timer