I implemented a facility for really fast dragging of components to
Swing. The idea is that when a component (like a JInternalFrame) is
dragged, then it doesn't need to repaint everything but only copy around
the component's rectangle. For this to accomplish we need a temporary
buffer where the component is drawn into at the beginning of the
dragging operation and this buffer is then copied around while dragging.

This is implemented in JComponent.paint() and turned on and off via a
client propery.

I added support for this to the JInternalFrame.

2006-03-15  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JComponent.java
        (dragBuffer): New field.
        (dragBufferInitialized): New field.
        (paint): Added facility for buffered dragging of components.
        (initializeDragBuffer): New method.
        (getConditionForKeyStroke): Removed deprecated flag. Adjusted
        API docs.
        * javax/swing/plaf/basic/BasicInternalFrameUI.java
        (BorderListener.mouseDragged): Turn on buffered dragging.
        (BorderListener.mouseReleased): Turn off buffered dragging.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.105
diff -u -r1.105 JComponent.java
--- javax/swing/JComponent.java	27 Feb 2006 12:52:05 -0000	1.105
+++ javax/swing/JComponent.java	15 Mar 2006 18:58:14 -0000
@@ -550,6 +550,16 @@
   private boolean paintingTile;
 
   /**
+   * A temporary buffer used for fast dragging of components.
+   */
+  private Image dragBuffer;
+
+  /**
+   * Indicates if the dragBuffer is already initialized.
+   */
+  private boolean dragBufferInitialized;
+
+  /**
    * A cached Rectangle object to be reused. Be careful when you use that,
    * so that it doesn't get modified in another context within the same
    * method call chain.
@@ -1556,20 +1566,57 @@
       }
     else
       {
+        if (getClientProperty("bufferedDragging") != null
+            && dragBuffer == null)
+          {
+            initializeDragBuffer();
+          }
+        else if (getClientProperty("bufferedDragging") == null
+            && dragBuffer != null)
+          {
+            dragBuffer = null;
+          }
+
         if (g.getClip() == null)
           g.setClip(0, 0, getWidth(), getHeight());
-        Graphics g2 = getComponentGraphics(g);
-        paintComponent(g2);
-        paintBorder(g2);
-        paintChildren(g2);
-        Rectangle clip = g2.getClipBounds();
-        if (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
-            && clip.height == getHeight())
-          RepaintManager.currentManager(this).markCompletelyClean(this);
+        if (dragBuffer != null && dragBufferInitialized)
+          {
+            g.drawImage(dragBuffer, 0, 0, this);
+          }
+        else
+          {
+            Graphics g2 = getComponentGraphics(g);
+            paintComponent(g2);
+            paintBorder(g2);
+            paintChildren(g2);
+            Rectangle clip = g2.getClipBounds();
+            if (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
+                && clip.height == getHeight())
+              RepaintManager.currentManager(this).markCompletelyClean(this);
+          }
       }
   }
 
   /**
+   * Initializes the drag buffer by creating a new image and painting this
+   * component into it.
+   */
+  private void initializeDragBuffer()
+  {
+    dragBufferInitialized = false;
+    // Allocate new dragBuffer if the current one is too small.
+    if (dragBuffer == null || dragBuffer.getWidth(this) < getWidth()
+        || dragBuffer.getHeight(this) < getHeight())
+      {
+        dragBuffer = createImage(getWidth(), getHeight());
+      }
+    Graphics g = dragBuffer.getGraphics();
+    paint(g);
+    g.dispose();
+    dragBufferInitialized = true;
+  }
+
+  /**
    * Paint the component's border. This usually means calling [EMAIL PROTECTED]
    * Border#paintBorder} on the [EMAIL PROTECTED] #border} property, if it is
    * non-<code>null</code>. You may override this if you wish to customize
@@ -1993,15 +2040,15 @@
    * Return the condition that determines whether a registered action
    * occurs in response to the specified keystroke.
    *
+   * As of 1.3 KeyStrokes can be registered with multiple simultaneous
+   * conditions.
+   *
    * @param ks The keystroke to return the condition of
    *
    * @return One of the values [EMAIL PROTECTED] #UNDEFINED_CONDITION}, [EMAIL PROTECTED]
    *     #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, [EMAIL PROTECTED] #WHEN_FOCUSED}, or [EMAIL PROTECTED]
    *     #WHEN_IN_FOCUSED_WINDOW}
    *
-   * @deprecated As of 1.3 KeyStrokes can be registered with multiple
-   *     simultaneous conditions.
-   *
    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)   
    * @see #unregisterKeyboardAction   
    * @see #resetKeyboardActions
@@ -2028,8 +2075,6 @@
    * @param ks The keystroke to retrieve the action of
    *
    * @return The action associated with the specified keystroke
-   *
-   * @deprecated Use [EMAIL PROTECTED] #getActionMap()}
    */
   public ActionListener getActionForKeyStroke(KeyStroke ks)
   {
Index: javax/swing/plaf/basic/BasicInternalFrameUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java,v
retrieving revision 1.29
diff -u -r1.29 BasicInternalFrameUI.java
--- javax/swing/plaf/basic/BasicInternalFrameUI.java	13 Mar 2006 22:06:47 -0000	1.29
+++ javax/swing/plaf/basic/BasicInternalFrameUI.java	15 Mar 2006 18:58:14 -0000
@@ -255,7 +255,7 @@
       else if (e.getSource() == titlePane)
         {
           Rectangle fBounds = frame.getBounds();
-
+          frame.putClientProperty("bufferedDragging", Boolean.TRUE);
           dm.dragFrame(frame, e.getX() - xOffset + b.x, e.getY() - yOffset
                                                         + b.y);
         }
@@ -326,7 +326,10 @@
       if (e.getSource() == frame && frame.isResizable())
         dm.endResizingFrame(frame);
       else if (e.getSource() == titlePane)
-        dm.endDraggingFrame(frame);
+        {
+          dm.endDraggingFrame(frame);
+          frame.putClientProperty("bufferedDragging", null);
+        }
     }
 
     /**

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

Reply via email to