【问题标题】:Force a full Java applet refresh (AWT)强制完整的 Java 小程序刷新 (AWT)
【发布时间】:2010-09-16 23:34:43
【问题描述】:

我有一个使用 AWT 的 Java Applet。在某些(罕见)情况下,平台无法正确刷新屏幕。我可以移动或最小化/最大化窗口并查看我的小程序是否正确刷新。我正在寻找代码,它将给我尽可能完整的小程序屏幕重绘,模拟最小化/最大化的行为。

我尝试在父容器上调用paint()/repaint()/invalidate()/update() 的各种组合并在各种子容器上递归。但是,没有任何组合(我发现)可以清除我遇到的框架错误。我正在寻找完全刷新小程序的技术,即使它们可能会导致一些轻微的闪烁,因为我只会在有问题的平台上调用此代码。

在我的测试中,迁移到 Swing 并没有帮助解决我的问题。

顺便说一下,这是对我之前(更复杂的)帖子的简化:Java Applet, AWT Refresh problem Mac OS X 10.4

编辑:对线程的调查并没有解决这个问题。将最佳答案标记为好答案。

【问题讨论】:

    标签: java macos applet refresh awt


    【解决方案1】:

    如果您没有在 AWT/Swing 中仔细编程,这种情况总是会发生。

    首先,您应该在事件线程上完成所有工作。这意味着您不能在主语句(或它直接调用的任何内容)中执行任何操作。我知道曾经发明的每一个 Java GUI 应用程序都违反了这条规则,但这就是规则。

    在大多数情况下,他们过去常说您可以使用非 awt 线程,直到窗口“实现”(pack/setVisible),但 Sun 发现这并不总是有效。

    其次,当你在 AWT 线程上得到一个事件时,一定要快速返回它。永远不要休眠或执行长时间的操作。

    第三,(这是“First”的扩展,如果您得到一个尚未在 AWT 工作线程上的回调,请确保在对 GUI 执行任何操作之前将其放在 AWT 线程上。

    通常,AWT 组件生成的任何事件都将在正确的线程上。由计时器、手动创建的线程或传递给 main() 的事件生成的事件不是。

    【讨论】:

    • 我将研究这个场景中使用的各种线程。您是否听说过 Mac OS X 10.4 上更常见的线程问题?
    • 他们当然可以,因为线程问题在很大程度上取决于重绘的完成方式和一般时间。我遇到过这样的问题,我不得不从一些非常简单的东西重新开始,并且一次添加/测试一个步骤。
    • 你应该在事件线程上调用 JDialog.setVisible(true) 吗?好像会阻塞事件线程,直到对话框关闭?
    【解决方案2】:

    正如您所提到的,用于解决此类问题的方法是重绘。您可能会看到正在使用的 JVM 存在问题。我建议使用不同版本的 Sun JVM,甚至是用于 IE 的 MS VM,看看这是否是与 VM 相关的问题 - 它实际上可能与您的代码无关。

    我之前实际上没有尝试过这个,但是解决这个问题的一种创造性方法(即讨厌的 hack)可能是从小程序执行 javascript 以调用 DOM 方法来模拟调整窗口大小或调用 focus on身体试图引起画布的外部重新绘制。

    【讨论】:

    • - 这是 Mac OS X 10.4 上的 Java 的问题,无论 Java 的版本是什么(1.4 或 1.5 或其他)。 - 我在 Java Web Start 中运行时无法使用 JavaScript。 - 你会如何重新粉刷?仅顶层容器还是深度优先搜索中的所有子容器? - 你先作废吗?
    • 通常我希望在顶层容器上重绘就足够了。但是,这听起来可能是与线程相关的时间问题(不幸的是),正如 Bill K 所建议的那样。
    【解决方案3】:

    不确定这是否与您所看到的有关,但如果您遇到 AWT 事件队列的性能,java 2d + 3d 世界(图形管道人员)将指向线程策略,然后您'将进入 dispose 问题。

    本次讨论一直在关注使用 AWT 事件队列的图形设计,如使用“重绘”。

    在线程方法中,存在关闭问题。

    java/awt/SequencedEvent 中关于“dispose”的注释将我们指向“AWT 线程问题”和“Autoshutdown”。

    我认为这一点信息至少有助于解决问题。

    【讨论】:

      【解决方案4】:

      通过切换到 Swing,我能够修复 99% 的 AWT Applet 重绘问题。 Swing 在刷新时似乎更可靠。

      之前,我的小程序代码中有很多手动 repaints(),但在 Swing 中,这些已被删除,小程序现在更快,尤其是在终端服务器/LTSP 下。

      我在里面放了一些重要的东西:

      public class VeryFastPanel extends JPanel {
      
      
      
          /**
               *
               */
              private static final long serialVersionUID = 1L;
      
              public void update(Graphics g) {
      
            paint(g);
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        我发现了一个与您遇到的相同的问题。经过一些测试,我发现这可能与 Aero 和 Intel 图形适配器有关。在我的例子中,该应用程序只有在没有交流适配器、由电池供电的笔记本电脑中使用时才会停止重新绘制。如果您在 Intel 驱动程序配置中禁用某些节能功能(尤其是旧驱动程序版本中的 Intel 2D 显示技术),Java 将再次正常重新绘制。

        就我而言,我还找到了通过注册表禁用此选项的方法。它没有记录在案,但它有效。

        【讨论】:

        • 那些无证的方式是什么?
        猜你喜欢
        • 1970-01-01
        • 2019-02-14
        • 2010-12-06
        • 1970-01-01
        • 2011-12-25
        • 2022-12-12
        • 2011-06-29
        • 2012-05-03
        相关资源
        最近更新 更多