Slow painting performance (6 dukes)

Hi!

I really, really need help...

I've made a drawing applet where I can draw with a pencil and different shapes like rectangles, roundrectangles, circles etc on a JPanel (like a drawing board)

All drawingobjects that are completed are saved to a model. The JPanel is then drawing all these objects onto its surface.

I have a JScrollPane to which I add my JPanel:

My JPanel is a big JPanel with dimensions (1500, 1500).

PROBLEM: Slow performance when drawing a rectangle (all other shapes aswell). After I've drawn a few objects it can get really slow WHEN im drawing an object (the object are seen while drawing) and uses up to 50% of my 3.06ghz processor while im drawing one rectangle or similar.

THEORY: I belieave the problem is that im drawing for example an rectangle (MyRectangle) and invokes repaint(areaForThisRectangle) it still repaints the entire JPanel. I think it still repaints entire JPanel because if I make alot of drawings which are saved to the JPanels model and then scroll down the JPanel(or the scrollpane rather) (Where nothing has been drawn before) and draw a shape. It uses up 50% of the CPU here aswell. And since Im trying to update only the area where im drawing the rectangle it must repaint entire JPanel since it gets as slow as if I would try to repaint on top of the other drawings.

This is from my mouseDragged method in the JPanel

repaint((int)rectangle.getX(), (int)rectangle.getY(), (int)(rectangle.getWidth()+1), (int)(rectangle.getHeight()+1));

rectangle.mouseDragged(e);

repaint((int)rectangle.getX(), (int)rectangle.getY(), (int)(rectangle.getWidth()+1), (int)(rectangle.getHeight()+1));

This is from my class MyRectangle which is a rectangle Im drawing

publicvoid paint(Graphics2D g)

{

g.setColor(color);

g.setStroke(StrokeLibrary.getDrawingStrokeSize(strokeSize));

if(filled)

g.fillRect((int)x, (int)y, (int)width, (int)height);

else

g.drawRect((int)x, (int)y, (int)width, (int)height);

}

publicvoid mousePressed(MouseEvent e)

{

start = e.getPoint();

}

publicvoid mouseDragged(MouseEvent e)

{

stop = e.getPoint();

//down and to the right

if(stop.x > start.x && stop.y > start.y)

{

setFrame(start.x, start.y, stop.x - start.x, stop.y - start.y);

}

//up and to the left

elseif(stop.x < start.x && stop.y < start.y)

{

setFrame(stop.x, stop.y, start.x - stop.x, start.y - stop.y);

}

//down and to the left

elseif(stop.x > start.x && stop.y < start.y)

{

setFrame(start.x, stop.y, stop.x - start.x, start.y - stop.y);

}

//up and to the right

else

{

setFrame(stop.x, start.y, start.x - stop.x, stop.y - start.y);

}

}

publicvoid mouseReleased(MouseEvent e)

{

stop = e.getPoint();

}

Here is the paintComponent code for my JPanel

/*

PaintComponent retrieves a list of all objects saved in the model

then it invokes a painting function for all of them (paint).

After the while loop there are temporary objects (if they aren't null they are currently being painted) that are painted if they are currently drawn

*/

publicvoid paintComponent(Graphics gx)

{

if(status==1)

{

super.paintComponent(gx);

Graphics2D g = (Graphics2D) gx;

LinkedList listOfDrawingObjects = controller.getListOfDrawingObjects();

LinkedList currentDrawingObjects =new LinkedList(listOfDrawingObjects);//make a copy to avoid ConcurrentModificationException

ListIterator it = currentDrawingObjects.listIterator();

while(it.hasNext())

{

DrawingObject ob = (DrawingObject) it.next();

ob.paint(g);

}

if(rectangle!=null && rectangle.getStart()!=null && rectangle.getStop()!=null)

{

rectangle.paint(g);

}

elseif(freeDraw!=null && freeDraw.getSize()>=2)

{

freeDraw.paint(g);

}

g.dispose();//release the copy of the graphics object

}

}

[6606 byte] By [CbbLea] at [2007-11-27 5:41:55]
# 1

This is my pencil class, I figured that it might be that this one takes so long time to draw out (when it has been saved into the model) since its alot of points (lines) to draw out!

How can I make the paint method faster?

/*

* MyFreeDraw.java

*

* Created on den 26 mars 2007, 00:54

*

*/

package graphic;

import javax.swing.event.MouseInputListener;

import java.io.Serializable;

import java.awt.event.MouseEvent;

import java.awt.geom.Point2D;

import java.util.LinkedList;

import java.awt.Point;

import java.awt.Color;

import java.util.ListIterator;

import java.awt.Graphics2D;

import java.awt.Graphics;

/**

*

* @author Sebastian Gr鋘nby

*/

public class MyFreeDraw implements MouseInputListener, ShapeObject, Serializable

{

private LinkedList allPoints;

private Color color;

private Integer strokeSize;

private String userName;

private Point lastPoint;

private static final long serialVersionUID = 42; //needed to reduce errors that can arise ina weird way

public MyFreeDraw()

{

color = Color.BLACK;

allPoints = new LinkedList();

strokeSize = new Integer(1);

}

public MyFreeDraw(Color color, int strokeSize, String userName)

{

this.userName = userName;

this.color = color;

this.strokeSize = new Integer(strokeSize);

allPoints = new LinkedList();

}

public LinkedList getAllPoints()

{

return allPoints;

}

public int getSize()

{

return allPoints.size();

}

public Color getColor()

{

return color;

}

public int getStrokeSize()

{

return strokeSize.intValue();

}

public String getUserName()

{

return userName;

}

public void setColor(Color color)

{

this.color = color;

}

public void setStrokeSize(int strokeSize)

{

this.strokeSize = strokeSize;

}

public void paint(Graphics2D g)

{

g.setColor(color);

g.setStroke(StrokeLibrary.getDrawingStrokeSize(strokeSize));

LinkedList tempPoints = new LinkedList(allPoints); //avoids ConcurrentException

if(allPoints.size()>=2)

{

ListIterator it2 = tempPoints.listIterator(0);

ListIterator it3 = tempPoints.listIterator(1); //must be one step ahead since two points are needed to draw

while(it2.hasNext() && it3.hasNext())

{

Object ob2 = it2.next();

Object ob3 = it3.next();

if(ob2 instanceof Point)

{

Point p = (Point) ob2;

Point t = (Point) ob3;

g.drawLine(p.x, p.y, t.x, t.y);

}

}

}

}

public boolean equals(Object other) //needed because otherwise the same object will be saved twice in the model!

{

if(this == other)

return true;

else

{

if(other instanceof MyFreeDraw)

{

MyFreeDraw test = (MyFreeDraw) other;

if(this.userName.equals(test.userName) && this.color.equals(test.getColor()) && this.strokeSize.equals(test.getStrokeSize())&& this.allPoints.equals(test.getAllPoints()))

return true;

else

return false;

}

else

return false;

}

}

/*

public int hashCode() //not tested

{

int ret;

ret = userName.hashCode() +color.hashCode() + strokeSize.hashCode() +allPoints.hashCode();

return ret;

}

*/

public void mousePressed(MouseEvent e)

{

Point p = new Point(e.getPoint()); //Point p = new Point(e.getPoint());

allPoints.add(p);

lastPoint = p;

}

/*CALLED WHILE THE USER IS DRAWING WITH THE PENCIL (QUICK) */

/*Replaces mouseDragged!!!!!*/

public void drawTemporary(MouseEvent e, Graphics2D g)

{

Point p = new Point(e.getPoint());

int xx = (int)p.getX();

int yy = (int)p.getY();

int xxx = (int)lastPoint.getX();

int yyy = (int)lastPoint.getY();

lastPoint = p;

g.setColor(color);

g.setStroke(StrokeLibrary.getDrawingStrokeSize(strokeSize));

g.drawLine(xx, yy, xxx, yyy);

allPoints.add(p);

}

/*NOT USED (drawTemporary is used instead) */

public void mouseDragged(MouseEvent e)

{

Point p = new Point(e.getPoint());

allPoints.add(p);

lastPoint = p;

}

public void mouseReleased(MouseEvent e)

{

Point p = new Point(e.getPoint()); //Point p = new Point(e.getPoint());

allPoints.add(p);

}

public void mouseEntered(MouseEvent e) {};

public void mouseMoved(MouseEvent e) {};

public void mouseClicked(MouseEvent e) {};

public void mouseExited(MouseEvent e) {};

}

Message was edited by:

CbbLe

CbbLea at 2007-7-12 15:19:57 > top of Java-index,Security,Cryptography...