I can think at two methods:
1. During the drag operation draw only the objects that are moving
with a XOR operation. It can look like this (selectedObjects can be a
List of your graphic objects):
public void mouseDragged( MouseEvent e ) {
if (selectedObjects.size() == 0)
return;
Graphics g = getGraphics();
g.setXORMode(Color.white);
drawObjects(selectedObjects, g);
updatePosition(selectedObjects, e.getX(), e.getY());
drawObjects(selectedObjects, g);
g.dispose();
}
I think it is obvious what drawObjects and updatePosition methods are
supposed to do.
2. You can draw the fixed objects in an BufferedImage.
3. The Graphics2D accepts a Shape for the clipping area. So you can
compute the outline of your selected objects and update only the
inside of this shape. I am not sure if this brings much or just slow
everything down. Probably it depends on the complexity of the graphic
objects you want to draw.
I am also interested to find out more ideas.
-Iulian
David Eisner wrote:
> Attached is a toy program that draws a thousand colored
> rectangles, and allows the user to drag them around
> with the mouse.
>
> Initially, I didn't pass any arguments to repaint(), so
> that all the rectangles were wastefully re-rendered.
> This made dragging very slow -- the dragged rectangle
> would lag the mouse, and only catch up at the end.
>
> By calculating a sensible clip bound and re-rendering
> only the rectangles in that region, the performance
> was much better.
>
> Now I've added two rectangles at the bottom of the window that
> are connected by a line. As a linked rectangle is dragged
> such that the line intersects the field of rectangles,
> the repaint region becomes larger and the performance
> is poor again -- the rectangle lags behind the mouse
> (try dragging the blue rectangle up the right side
> of the window).
>
> This isn't a real-world program, but I'm wondering how one
> would improve the performance -- with the hope that any such
> improvements might be applicable elsewhere.
>
> Thanks.
>
> -David
>
>
> ------------------------+--------------------------+
> David Eisner | E-mail: [EMAIL PROTECTED] |
> CALCE EPSC | Phone: 301-405-5341 |
> University of Maryland | Fax: 301-314-9269 |
> ------------------------+--------------------------+
>
>
> ------------------------------------------------------------------------
>
> import java.awt.*;
> import java.awt.event.*;
> import javax.swing.*;
>
>
> /**
> * Toy app to demonstrate performance issue.
> */
> public class RectangleTest extends JFrame {
>
> GraphPanel main_panel;
>
>
> public RectangleTest() {
> super("RectangleTest v0.01");
>
>
> addWindowListener( new WindowAdapter() {
> public void windowClosing( WindowEvent e) {
> System.exit(0);
> }
>
> });
>
> main_panel = new GraphPanel();
> main_panel.setPreferredSize( new Dimension( Constants.WIN_WIDTH,
> Constants.WIN_HEIGHT ));
> main_panel.setBackground( Color.white );
> getContentPane().add( main_panel, BorderLayout.CENTER );
> }
>
>
>
> public static void
> main( String args[] ) {
>
> RectangleTest app = new RectangleTest();
>
> app.pack();
> app.setVisible(true);
> }
> }
>
>
>
> class Constants {
> final static int WIN_WIDTH = 650;
> final static int WIN_HEIGHT = 450;
> }
>
>
> ------------------------------------------------------------------------
>
>
> import java.awt.*;
> import java.awt.event.*;
> import java.awt.geom.*;
> import java.util.*;
>
> import javax.swing.*;
> import javax.swing.event.*;
>
> /**
> * JPanel that can display a bunch of colored rectangles.
> */
> public class GraphPanel extends JPanel {
>
> Random rg = new Random();
>
> Vector rects = new Vector(); // list of ColoredRectangles
> Link link;
>
> Rectangle2D selectedRect = null;
> Point dragStartPt = null;
> Point rectStartPt = new Point();
>
> final static int NUM_RECTS = 1000;
>
> /**
> * Rectangle with a color.
> */
> class ColoredRectangle extends Rectangle2D.Double {
>
> private Color color;
>
> ColoredRectangle( int x, int y, int w, int h ) {
> this(x, y, w, h, Color.white );
> }
>
> ColoredRectangle( int x, int y, int w, int h, Color c ) {
> super( x, y, w, h );
> color = c;
>
> }
>
> public void
> setColor( Color c ) {
> color = c;
> }
>
> public Color
> getColor() {
> return color;
> }
>
> }
>
>
> /**
> * A simple link between two rectangles.
> */
> class Link {
>
> Rectangle2D r1;
> Rectangle2D r2;
>
> Link( Rectangle2D rect1, Rectangle2D rect2 ) {
> r1 = rect1;
> r2 = rect2;
> }
> }
>
>
> public GraphPanel() {
> super();
>
> Rectangle2D rect;
>
> rect = new ColoredRectangle( 20, Constants.WIN_HEIGHT - 50,
> 25, 25, Color.red );
> rects.add( rect );
>
> rect = new ColoredRectangle( Constants.WIN_WIDTH - 50,
> Constants.WIN_HEIGHT - 50,
> 25, 25, Color.blue );
> rects.add( rect );
>
>
> for (int i= rects.size(); i < NUM_RECTS; i++) {
> rect = new ColoredRectangle( rg.nextInt( Constants.WIN_WIDTH - 100),
> rg.nextInt( Constants.WIN_HEIGHT -100),
> 5 + rg.nextInt( 40 ),
> 5 + rg.nextInt( 40 ),
> new Color( rg.nextInt( 256 ),
> rg.nextInt( 256 ),
> rg.nextInt( 256 ) ));
> rects.add( rect );
> }
>
> link = new Link( (Rectangle2D) rects.get(0),
> (Rectangle2D) rects.get(1) );
>
>
> MouseInputAdapter adapter = new MouseInputAdapter() {
> public void mousePressed( MouseEvent e ) {
>
> Point pt = e.getPoint();
>
> selectedRect = pickRectangle( pt );
> if (selectedRect != null) {
> dragStartPt = pt;
> rectStartPt.setLocation( selectedRect.getX(),
> selectedRect.getY() );
> }
> }
>
> public void mouseDragged( MouseEvent e ) {
> if (selectedRect != null) {
> double deltaX = e.getX() - dragStartPt.getX();
> double deltaY = e.getY() - dragStartPt.getY();
>
> // Calculate bounds for repaint
> Rectangle bounds = selectedRect.getBounds();
>
> selectedRect.setRect( rectStartPt.getX() + deltaX,
> rectStartPt.getY() + deltaY,
> selectedRect.getWidth(),
> selectedRect.getHeight() );
> bounds.add( selectedRect );
>
> // Make sure bounds includes Link line
> if (link.r1 == selectedRect)
> bounds.add( link.r2 );
> else if (link.r2 == selectedRect)
> bounds.add( link.r1 );
>
> bounds.width += 1;
> bounds.height += 1;
> repaint( bounds );
> }
> }
>
>
> public void mouseReleased( MouseEvent e ) {
> selectedRect = null;
> dragStartPt = null;
> }
> };
>
> addMouseListener( adapter );
> addMouseMotionListener( adapter );
> }
>
>
> public void
> paintComponent( Graphics g ) {
> Graphics2D g2 = (Graphics2D) g;
> Rectangle cb = g2.getClipBounds();
> cb.x -= 1;
> cb.y -= 1;
> cb.width += 1;
> cb.height += 1;
>
> super.paintComponent( g2 );
>
> Line2D.Double line = new Line2D.Double( link.r1.getCenterX(),
> link.r1.getCenterY(),
> link.r2.getCenterX(),
> link.r2.getCenterY() );
>
> g2.setColor( Color.black );
> g2.draw( line );
> for (int i=0; i < rects.size(); i++) {
> ColoredRectangle rect = (ColoredRectangle) rects.get(i);
>
> if ( rect.intersects( cb )) {
> g2.setColor( rect.getColor() );
> g2.fill( rect );
> g2.setColor( Color.black );
> g2.draw( rect );
> }
> }
>
> }
>
> /**
> * Return rectangle that contains pt, if any, or null otherwise.
> */
> private Rectangle2D
> pickRectangle( Point pt ) {
>
> double x = pt.getX();
> double y = pt.getY();
>
> for (int i=rects.size() - 1; i >= 0; i--) {
> Rectangle2D rect = (Rectangle2D) rects.get(i);
> if (rect.contains( x, y))
> return rect;
> }
> return null;
> }
>
> }
>
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".