简体   繁体   中英

Efficient way to draw paint using mouse on canvas

I have a Brush class

 final class Brush
 {
  private final int size;
  private final Color color;
  private final Ellipse2D.Double blob=new Ellipse2D.Double();

  private Brush(int size,Color color)
  {
   this.size=size;
   this.color=color;
  }

  void paint(Graphics2D g2d,Point location)
  {
   g2d.setColor(color);    
   blob.setFrame(location.x-(size/2.0),location.y-(size/2.0),size,size);//Translate ecllipse so that the centre of it's bounding box is exactly at the cursor location for more accurate blobs  
   g2d.fill(blob);
  }
 }

I have a Blob class which keeps track of the user's current brush settings and where the user previously dragged his mouse so as to remember to draw a blob there.

final class Blob
{
 final Brush brush;
 final Point location;

 private Blob(Brush brush,Point location)
 {
  this.brush=brush;
  this.location=location;
 }

 private void paint(Graphics2D g){brush.paint(g,location);}
}

Finally my paint logic which is very simple.

Whenever the user drags his mouse add a blob at that current location with the current brush settings and inside paint() loop through all blobs and redraw them.

final class Painter extends Canvas
{
 private Brush brush=new Brush(5,Color.red);//Can Change
 private final ArrayList<Blob> blobs=new ArrayList(); 

 private Painter(){addMouseMotionListener(new Dragger());}

 @Override
 public void paint(Graphics g)
 {
  super.paint(g);

  blobs.forEach(blob->blob.paint(g));
 }

 private final class Dragger extends MouseAdapter
 {
  @Override
  public void mouseDragged(MouseEvent m)
  {
   blobs.add(brush,m.getPoint());

   repaint();
  }    
 }
}

You can already see the problem here. The size of the list grows exponentially and my app quickly slows down. Is there an more efficient way to do this?

The much more efficient way to do this is to use a BufferedImage for your drawing, and than painting the BufferedImage in paintComponent

Code taken from PaintArea :

public void paintComponent(Graphics g) {
    if (mSizeChanged) {
        handleResize();
    }
    g.drawImage(mImg, 0, 0, null);
}

protected class MListener extends MouseAdapter implements MouseMotionListener {
    Point mLastPoint;
    public void mouseDragged(MouseEvent me) {
        Graphics g = mImg.getGraphics();
        if ((me.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
            g.setColor(mColor1);
        } else {
            g.setColor(mColor2);
            
        }
        Point p = me.getPoint();
        if (mLastPoint == null) {
            g.fillOval(p.x - mBrushSize / 2, p.y - mBrushSize / 2, mBrushSize, mBrushSize);
            //g.drawLine(p.x, p.y, p.x, p.y);
        }
        else {
            g.drawLine(mLastPoint.x, mLastPoint.y, p.x, p.y);
            //g.fillOval(p.x - mBrushSize / 2, p.y - mBrushSize / 2, mBrushSize, mBrushSize);
            double angle = MathUtils.angle(mLastPoint, p);
            if (angle < 0) {
                angle += 2 * Math.PI;
            }
            @SuppressWarnings("unused")
            double distance = MathUtils.distance(mLastPoint, p) * 1.5;
            if (angle < Math.PI / 4 || angle > 7 * Math.PI / 4 || Math.abs(Math.PI - angle) < Math.PI / 4) {
                for (int i = 0; i < mBrushSize / 2; i ++) {
                    g.drawLine(mLastPoint.x, mLastPoint.y + i, p.x, p.y + i);
                    g.drawLine(mLastPoint.x, mLastPoint.y - i, p.x, p.y - i);
                }
            }
            else {
                for (int i = 0; i < mBrushSize / 2; i ++) {
                    g.drawLine(mLastPoint.x + i, mLastPoint.y, p.x + i, p.y);
                    g.drawLine(mLastPoint.x  - i, mLastPoint.y, p.x - i, p.y);
                }                   
            }
        }
        mLastPoint = p;
        g.dispose();
        repaint();
    }
    
    public void mouseMoved(MouseEvent me) {}
    
    public void mouseReleased(MouseEvent me) {
        mLastPoint = null;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM