1

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

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

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

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

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

4

5 回答 5

2

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

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

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

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

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

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

于 2008-10-13T22:30:23.513 回答
1

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

我之前实际上没有尝试过这个,但是一个创造性的方法(即讨厌的黑客)可能是从小程序执行 javascript 来调用 DOM 方法来模拟调整窗口的大小,或者可能调用焦点在身体上试图导致画布的外部重新绘制。

于 2008-10-13T22:10:40.777 回答
1

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

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

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

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

我认为这一点信息至少可以解决问题。

于 2009-11-06T16:46:52.650 回答
0

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

早些时候,我的 applet 代码中有很多手动 repaints(),但是在 Swing 中,这些都被删除了,applet 现在更快了,尤其是在终端服务器/LTSP 下。

我在其中放置了关键的东西:

public class VeryFastPanel extends JPanel {



    /**
         *
         */
        private static final long serialVersionUID = 1L;

        public void update(Graphics g) {

      paint(g);
    }

}
于 2008-10-14T13:03:02.677 回答
0

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

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

于 2011-05-23T17:30:11.617 回答