question about painting efficiently
Hello,
I'm experimenting with painting in swing, and I'm having some difficulty doing it as efficiently as I can (or I think is possible).
Let me show my paintComponent() method as it stands now:
Code:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
if (W1.redraw)
g.drawRect(W1.getX(), W1.getY(), Wall.LENGTH, Wall.THICKNESS);
if (W2.redraw)
g.drawRect(W2.getX(), W2.getY(), Wall.THICKNESS, Wall.LENGTH);
g.setColor(Color.RED);
g.drawOval(cx, cy, cw, ch);
}
and this is the result:
http://www.shahspace.com/java1.jpg
The difficulty I'm having is that I don't want to keep redrawing elements that don't need to be redrawn (I should say, in order to make sense of that, that I have a Timer object setup to call repaint() every 100 milliseconds). I'm doing this because the user can animate the red circle (you can hold down the arrow keys to move it around). This means that it must be consistently redrawn so long as the user holds down one of the arrow keys.
But the blue walls only need to be drawn once as a part of the first rendering of the JPanel they're on. That's why I have their drawRect() calls under an if statement (where W1.redraw and W2.redraw are booleans.
The problem is that since I have to set these booleans to false (elsewhere) once the walls have been drawn, the call to super.paintComponent() wipes them out completely (it seems to wipe out everything in the JPanel) and therefore only redraws the circle since that isn't under the condition of an if statement. But I can't just take the call to super.paintComponent() out, not only because I've been told to do this when working in swing (and to always use paintComponent() rather than paint()), but because if I comment it out, this turns out to be the result:
http://www.shahspace.com/java2.jpg
The circle is leaving a trail behind it as I move it around the JPanel. This is especially strange because my code that calls repaint() looks like this:
Code:
if (circle_moved) {
CAJP.repaint(OldCircle);
CAJP.repaint(CAJP.getCX()-1, CAJP.getCY()-1, CAJP.getCW()+2,
CAJP.getCH()+2);
}
CAJP is my JPanel, getCX() get's the circle's X position, and so on. Note the use of OldCirlce, a Rectangle whose dimensions were set before the circle's position was changed. I pass that into repaint() first (which is supposed to mark the area defined by the Rectangle as dirty, meaning it should be erased before the circle is redrawn) and then draw my circle. But this seems to be having no effect. Not to mention that the background is being repainted grey instead of the black I'd like.
Can anyone suggest what the issue might be? Do I really have to repaint everything any time something's changed?
Not clear if the old circle erased.
It looks like the old circle is not erased.
If the following code is supposed to
erase the old circle, something should
be done to ensure that the old circle
is repainted in blue, then the new circle
is repainted in red.
Code:
if (circle_moved) {
CAJP.repaint(OldCircle);
CAJP.repaint(CAJP.getCX()-1, CAJP.getCY()-1, CAJP.getCW()+2,
CAJP.getCH()+2);
}
Your snippet is not complete enough
to convince me that this is being
done.