问题
We have a Java Applet built using AWT. This applet lets you select pictures from your hard drive and upload them to a server. The applet includes a scrollable list of pictures, which works fine in Windows, Linux and Mac OS X 10.5. We launch this applet via Java Web Start or within a web page.
Our applet does not behave properly in Mac OS X 10.4, regardless of the version of Java (1.4 or 1.5). You can find a screenshot of the incorrect behaviour, when scrolling, here:
http://www.lavablast.com/tmp/ui_error.png
Simply put, sometimes when scrolling the pictures end up overlapping the header or footer of the application. This behaviour does not occur on other platforms. On Mac OS X 10.4, it shows the pictures in the incorrect location when scrolling, which would not be so bad if it refreshed the screen after painting the image at that location. However, it does not appear that the application knows it painted it incorrectly and thus does not refresh.
If the window is minimized, resized or even moved, the application is refreshed and the incorrectly positioned elements vanish and the application resumes normally. I spent quite some time trying to force a refresh of the background image unsuccessfully. (the repaint the image directly, repaint all children of a few panels, etc. ) Thus, I am looking for any tips that would help me resolve this problem under Mac OS X 10.4 or, in the worst case, simply simulate a full applet refresh.
Until recently, everything was compatible with Java 1.1 but this has changed in a few locations which now require 1.4. I don't feel these changes created the issue, I am just providing this as extra information. If you are interested in implementation details of the scroll panel, I will investigate, but I am assuming this is a common platform bug for which workarounds must be known.
To replicate the problem, open the following Java Web Start application: http://www.lavablast.com/tmp/opal-webstart.php.jnlp
Select a folder containing lots of images and play with the scrollbar. At some point (fairly quickly), you should get the refresh problem.
Edit: I followed the first suggestion here and replaced all my controls that feature background images with a Swing equivalent and the issue is still there. (Plus, there are numerous other fixes I would need to do to do a complete change). Any other ideas? A simple one line of code that forces a full refresh would be great :)
Edit2: The main thread creates the panels and launches X threads. Using an observer/notifier pattern, the threads complete and notify the main control, which adds a panel to the page. This is done via an EventQueue.invokeLater which, unless I am mistaken, should run on the right thread. The issue is at its most severe when scrolling even if no extra threads are running (as during the loading).
回答1:
It does look like mixing lightweight (usually Swing) and heavyweight (AWT) components together. Moving to Swing you need to replace every last AWT component Swing equivalents (hint: avoid import java.awt.*).
Threading is often a potential problem for odd bugs. Swing components must always be used on the EDT (use java.awt.EventQueue.invokeLater
). AWT is thread-safe is theory, but not in practice - also restrict usage to the EDT.
回答2:
As you already require Java 1.4 you should consider some small changes to take into use SWING GUI instead, it solved our Applet refresh issues with AWT. (Mac, Linux etc)
If you have e.g. Panel, you need to replace it with JPanel etc.
You need this:
import javax.swing.*;
来源:https://stackoverflow.com/questions/184491/java-applet-awt-refresh-issue-on-mac-os-x-10-4