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); + } } /**
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil