更新GUI给出了闪烁效果

发布于 2024-12-17 15:22:33 字数 1249 浏览 1 评论 0 原文

我目前有一个 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凑诗 2024-12-24 15:22:33

调用 SwingUtilities.invokeAndWait() 中的 update() 来停止线程并更新 EDT 中的 UI。

Call the update() in SwingUtilities.invokeAndWait() which stops the thread and updates UI in EDT.

对你再特殊 2024-12-24 15:22:33

问题是您正在使用 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 during EventDispatchTread more in the Concurency in Swing, example demonstrating freeze GUI by using Thread.sleep(int), example for Runnable#Thread

If you want to delay whatever in Swing then the best way is implements javax.swing.Timer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文