macos 强制完整的 Java 小程序刷新 (AWT)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/199152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:56:41  来源:igfitidea点击:

Force a full Java applet refresh (AWT)

javamacosappletrefreshawt

提问by Jason Kealey

I have a Java Applet that uses AWT. In some (rare) circumstances, the platform does not refresh the screen properly. I can move or minimize/maximize the window and see that my applet refreshed properly. I am looking for code that will give me the fullest possible applet screen repaint, simulating the behaviour of a minimize/maximize.

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

I've tried calling various combinations of paint()/repaint()/invalidate()/update() on the parent containers and recursing on various children. However, no combination (that I've found) cleans up the framework bugs that I am encountering. I am looking for techniques to fully refresh the applet, even if they may cause some slight flickering, as I will be invoking this code only on the problematic platform.

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

In my tests, moving to Swing did not help resolve my problem.

在我的测试中,转向 Swing 并没有帮助解决我的问题。

By the way, this is a simplification of my previous (more complicated) post: Java Applet, AWT Refresh problem Mac OS X 10.4

顺便说一句,这是我之前(更复杂)的帖子的简化版:Java Applet,AWT 刷新问题 Mac OS X 10.4

Edit: Investigation in threading did not solve this problem. Marking best answer as the good one.

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

回答by Bill K

This happens all the time if you are not programming carefully in AWT/Swing.

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

First of all, you should do ALL work on the event thread. This means you can't do any of it in your main statement (or anything it calls directly). I know every Java GUI app ever invented violates this rule, but that's the rule.

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

For the most part, they used to say you could use a non-awt thread until the window was "Realized" (pack/setVisible), but Sun figured out that didn't always work.

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

Second, when you get an event on the AWT thread, be sure to return it quickly. Never sleep or execute a long operation.

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

Third, (and this is an extension of "First", if you get a callback that is NOT already on the AWT worker thread, be sure to put it on the AWT thread before doing anything with the GUI.

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

Generally, any event generated by an AWT component will be on the correct thread. Events generated by timers, manually created threads, or the one handed to main() are not.

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

回答by J c

The method to use for this kind of problem is repaint, as you've mentioned. It's possible you are seeing an issue with the JVM you are using. I'd recommend using different versions of the Sun JVM and even the MS VM for IE to see if this is a VM related problem - it may actually be unrelated to your code.

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

I haven't actually tried this before, but a creative way (ie. nasty hack) around this might be to execute javascript from the applet to call a DOM method to do a mock resize of the window or perhaps call focus on the body in an attempt to cause an external re-drawing of the canvas.

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

回答by J c

Not sure if this is related to what you've seen, but if you get up against the performance of the AWT Event Queue the java 2d + 3d world (graphics pipeline folks) will point into a threaded strategy and then you'll get into the dispose problem.

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

This discussion has been looking at designs employing the AWT Event Queue for graphics, as in using "repaint".

本次讨论着眼于将 AWT 事件队列用于图形的设计,如使用“重绘”。

In the threaded approach, there is a shutdown problem.

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

Notes in java/awt/SequencedEvent for "dispose" point us to "AWT Threading Issues" and "Autoshutdown".

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

I'm thinking that this bit of info serves at least to focus the problem.

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

回答by Vinicius Canto Xavier

I found an issue that appears to be the same you are experiencing. After some tests, I discovered that this can be related to Aero and Intel Graphics adapters. In my case, the application stopped repainting only when used in notebooks without AC adapters, powered by batteries. If you disable some power saving features in Intel driver configuration (notably Intel 2D Display Technology in old driver releases) Java will repaint normally again.

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

In my case I found also ways to disable this option via registry. It's not documented, but it works.

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

回答by Tom

I was able to fix 99% of my AWT Applet redraw issues by switching to Swing. Swing seems to be more reliable on refreshing.

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

Earlier I had a lot of manual repaints() in my applet code, but with Swing these were removed and applet is now faster especially under Terminal Server / LTSP.

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

I placed critical stuff inside this:

我把关键的东西放在里面:

public class VeryFastPanel extends JPanel {



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

        public void update(Graphics g) {

      paint(g);
    }

}