【问题标题】:Forcing Java to refresh the Java Swing GUI强制 Java 刷新 Java Swing GUI
【发布时间】:2011-12-25 19:21:45
【问题描述】:

我已经编写了两台计算机在黑白棋中相互播放,但是当它们相互播放时。棋盘仅在游戏结束后更新。

通过一些谷歌搜索,我知道它与 AWT 事件线程有关,但我仍然不知道如何强制 JFrame 刷新。

我的函数通过更改图标然后调用重新验证和重新绘制来工作。 任何指针都会很棒。

【问题讨论】:

  • 当你玩你的程序时它是否正确显示?如果是这样,您是否尝试过模拟单击事件而不是刷新图形,以使其就像计算机在板上单击一样?
  • 嗯,我没想到。但我不知道它是否会起作用。 GUI 由称为updateBoard() 的单独方法更新,该方法根据内部表示更改板。虽然与 while 循环有关意味着它在结束之前不会更新
  • 所以您没有使用模型-视图-控制器模式来实现您的 GUI?您的应用程序如何等待用户响应?它是使用循环还是事件完成的?由于 CPU 负载过重,您的应用程序 GUI 可能会被冻结,这就是为什么它在计算结束时没有更新的原因。如果你让下一个玩家暂停几秒钟会发生什么?如果 GUI 得到正确更新,那么我上面的假设应该是正确的。
  • 不,不幸的是它不是 MVC。这是我完成的第一个 GUI,当我了解 MVC 时,我已经基本完成了。该游戏确实适用于拥有 1 个或更多用户,但是当它的 AI 非常糟糕时它不会更新,可能是因为没有暂停。它有一段时间(gameNotOver)......
  • 所以尝试让线程在该循环内休眠。

标签: java multithreading swing events refresh


【解决方案1】:

如果您从 actionPerformed() 开始您的 AI 游戏,它将在 EDT 线程中执行。您应该通过启动一个新的Thread 将您的逻辑(以及您的sleep() 移到 EDT 线程之外,以允许 Swing 正确重绘 UI 并将更新发布到 UI,如下所示:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        myUI.update();  // repaint(), etc. according to changed states
    }
});

还可以考虑使用javax.swing.SwingWorkerjavax.swing.Timer 并查看Concurrency in Swing

【讨论】:

  • 鉴于 OP 提供的信息有限,这个答案可能是正确的。但是,我注意到我的应用程序中存在类似的行为,并且我没有在 EDT 上运行我的 CPU 密集型代码。因此,EDT(或其他低级 Java 代码)可能没有获得它需要绘制的 CPU 时间,因为应用程序已经占用了太多的 CPU 时间。
【解决方案2】:

听起来像是线程问题 - 事件线程没有机会执行。我将从逻辑/操作线程中的一些睡眠命令开始,以便为 UI 更新留出时间。

此外,您可以有一个“updateUI”线程并在 invokeAndWait 上运行它以强制它更新显示。在每次移动完成后调用它。

【讨论】:

  • -1 :即使其他线程很忙,如果 EDT 没有被阻塞,GUI 也会保持响应。其逻辑发生在 EDT 中的可能性为 99%。
【解决方案3】:

如果您需要强制应用程序重绘,您应该在包含游戏板的组件上调用repaint() 方法。这应该会导致 Swing 重新绘制电路板。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2012-04-02
    • 2011-11-05
    • 2017-11-10
    • 2011-04-08
    • 2015-11-17
    • 2015-09-29
    相关资源
    最近更新 更多