diff options
Diffstat (limited to 'javax/swing/RepaintManager.java')
-rw-r--r-- | javax/swing/RepaintManager.java | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java index 2d29e9076..fa374a34f 100644 --- a/javax/swing/RepaintManager.java +++ b/javax/swing/RepaintManager.java @@ -38,13 +38,18 @@ exception statement from your version. */ package javax.swing; +import gnu.java.awt.LowPriorityEvent; + import java.applet.Applet; import java.awt.Component; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.Window; +import java.awt.event.InvocationEvent; import java.awt.image.VolatileImage; import java.util.ArrayList; import java.util.HashMap; @@ -72,6 +77,32 @@ import java.util.WeakHashMap; public class RepaintManager { /** + * An InvocationEvent subclass that implements LowPriorityEvent. This is used + * to defer the execution of RepaintManager requests as long as possible on + * the event queue. This way we make sure that all available input is + * processed before getting active with the RepaintManager. This allows + * for better optimization (more validate and repaint requests can be + * coalesced) and thus has a positive effect on performance for GUI + * applications under heavy load. + */ + private static class RepaintWorkerEvent + extends InvocationEvent + implements LowPriorityEvent + { + + /** + * Creates a new RepaintManager event. + * + * @param source the source + * @param runnable the runnable to execute + */ + public RepaintWorkerEvent(Object source, Runnable runnable) + { + super(source, runnable); + } + } + + /** * The current repaint managers, indexed by their ThreadGroups. */ static WeakHashMap currentRepaintManagers; @@ -340,7 +371,7 @@ public class RepaintManager if (! repaintWorker.isLive()) { repaintWorker.setLive(true); - SwingUtilities.invokeLater(repaintWorker); + invokeLater(repaintWorker); } } @@ -405,7 +436,7 @@ public class RepaintManager if (! repaintWorker.isLive()) { repaintWorker.setLive(true); - SwingUtilities.invokeLater(repaintWorker); + invokeLater(repaintWorker); } } } @@ -693,13 +724,18 @@ public class RepaintManager root = root.getParent(); } - Graphics g = root.getGraphics(); - Image buffer = (Image) offscreenBuffers.get(root); - - // Make sure we have a sane clip at this point. - g.clipRect(x, y, w, h); - g.drawImage(buffer, 0, 0, root); - g.dispose(); + if (root != null) + { + Graphics g = root.getGraphics(); + Image buffer = (Image) offscreenBuffers.get(root); + if (buffer != null) + { + // Make sure we have a sane clip at this point. + g.clipRect(x, y, w, h); + g.drawImage(buffer, 0, 0, root); + g.dispose(); + } + } } /** @@ -791,4 +827,18 @@ public class RepaintManager { return "RepaintManager"; } + + /** + * Sends an RepaintManagerEvent to the event queue with the specified + * runnable. This is similar to SwingUtilities.invokeLater(), only that the + * event is a low priority event in order to defer the execution a little + * more. + */ + private void invokeLater(Runnable runnable) + { + Toolkit tk = Toolkit.getDefaultToolkit(); + EventQueue evQueue = tk.getSystemEventQueue(); + InvocationEvent ev = new RepaintWorkerEvent(this, runnable); + evQueue.postEvent(ev); + } } |