简体   繁体   English

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

[英]Force a full Java applet refresh (AWT)

I have a Java Applet that uses AWT. 我有一个使用AWT的Java Applet。 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. 我可以移动或最小化/最大化窗口,看到我的applet正确刷新。 I am looking for code that will give me the fullest possible applet screen repaint, simulating the behaviour of a minimize/maximize. 我正在寻找代码,它将为我提供最全面的applet屏幕重绘,模拟最小化/最大化的行为。

I've tried calling various combinations of paint()/repaint()/invalidate()/update() on the parent containers and recursing on various children. 我已经尝试在父容器上调用paint()/ repaint()/ invalidate()/ update()的各种组合,并在各种子代上进行递归。 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. 我正在寻找完全刷新applet的技术,即使它们可能会引起一些轻微的闪烁,因为我将仅在有问题的平台上调用此代码。

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 Refresh问题Mac OS X 10.4

Edit: Investigation in threading did not solve this problem. 编辑:线程调查没有解决这个问题。 Marking best answer as the good one. 将最佳答案标记为好的答案。

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. 其次,当您在AWT线程上获得事件时,请务必快速返回。 Never sleep or execute a long operation. 永远不要睡觉或执行长时间操作。

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. 第三,(这是“First”的扩展,如果你得到一个尚未在AWT工作线程上的回调,请确保在对GUI进行任何操作之前将其放在AWT线程上。

Generally, any event generated by an AWT component will be on the correct thread. 通常,AWT组件生成的任何事件都将位于正确的线程上。 Events generated by timers, manually created threads, or the one handed to main() are not. 由计时器,手动创建的线程或者传递给main()的事件生成的事件不是。

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". 用于“dispose”的java / awt / SequencedEvent中的注释指向“AWT线程问题”和“自动关闭”。

I'm thinking that this bit of info serves at least to focus the problem. 我认为这一点信息至少可以解决问题。

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. 您可能会看到正在使用的JVM存在问题。 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. 我建议使用不同版本的Sun JVM甚至MS VM for IE来查看这是否与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. 我以前没有尝试过这个,但是围绕这一点的创造性方式(即讨厌的黑客)可能是从applet执行javascript来调用DOM方法来执行窗口的模拟调整大小或者可能将焦点调用到主体上试图导致外部重新绘制画布。

I was able to fix 99% of my AWT Applet redraw issues by switching to Swing. 通过切换到Swing,我能够修复99%的AWT Applet重绘问题。 Swing seems to be more reliable on refreshing. 刷新似乎更可靠。

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. 之前我在我的applet代码中有很多手动重绘(),但是使用Swing这些被删除了,applet现在更快,特别是在终端服务器/ 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);
    }

}

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. 经过一些测试,我发现这可能与Aero和Intel Graphics适配器有关。 In my case, the application stopped repainting only when used in notebooks without AC adapters, powered by batteries. 在我的情况下,应用程序仅在没有由电池供电的AC适配器的笔记本电脑中使用时才停止重新涂漆。 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. 如果禁用英特尔驱动程序配置中的某些省电功能(特别是旧驱动程序版本中的英特尔2D显示技术),Java将再次正常重新绘制。

In my case I found also ways to disable this option via registry. 在我的情况下,我发现了通过注册表禁用此选项的方法。 It's not documented, but it works. 它没有记录,但它的工作原理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM