tags:

views:

1640

answers:

4

How can I draw something in JPanel that will stay the same and not be repainted, I am doing a traffic simulation program and I want the road to be drawn once because It will not change. Thanks

+2  A: 

To my knowledge, no, unless there is a trick with transparent overlays.

Most graphical applications I saw (and did) just re-draw the whole panel on each repaint. Now, you can do that once, in a graphic buffer, and then just paint the whole background at once, quickly, by copying the graphic buffer to the JPanel. It should be faster than calling all graphical primitives to draw the road.

Or, the way some 2D games do, perhaps paint it once and update the moving parts, like sprites: it needs to erase the old place used by the sprites (restore the background there) and re-draw the sprites at the new place. So you still have a copy of the road in a graphic buffer but instead of re-drawing it whole each time, you update only some small parts. Can be slightly faster.

PhiLho
+2  A: 

I'm not sure you actually want your road to never be repainted - repaint events fire (for example) when your window is resized, or when it becomes visible following another window obstructing it. If your panel never repaints then it'll look peculiar.

As far as I remember, Swing will only fire appropriate paint events for these circumstances, so you should be OK following the usual method of subclassing JPanel with a suitable override:

public class RoadPanel extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // your drawing code here
    }
}

If you cache your road into an image or another graphics format (to save calculating the display data multiple times) once drawn once, this might save you some time on subsequent paints.

Dan Vinton
+1  A: 

What I do is set a boolean value to whether or not a certain part needs to be redrawn. Then, in the paintComponent() method I can check the value and redraw the certain thing, or not.

protected void paintComponent(Graphics g){
    super.paintComponent(g);
    if (drawRoad) {
        drawRoadMethod(g);
    }
    drawTheRest(g);
}

Kinda like that.

jjnguy
+2  A: 

The component will need to be repainted every time that the panel is obscured (ie frame minimized/another window put on top). Therefore drawing something only once will not work as you want it to. To make parts that do not change be drawn more efficiently you can draw them once to a 'buffer' image, and then just draw this buffer each time that the panel or component needs to be redrawn.

// Field that stores the image so it is always accessible
private Image roadImage = null;
// ...
// ...
// Override paintComponent Method
public void paintComponent(Graphics g){

  if (roadImage == null) {
      // Create the road image if it doesn't exist
      roadImage = createImage(Width,Height);
      // draw the roads to the image
      Graphics roadG = roadImage.getGraphics();
      // Use roadG like you would any other graphics
      // object to draw the roads to an image
  } else {
      // If the buffer image exists, you just need to draw it.
      // Draw the road buffer image
      g.drawImage(roadImage, 0, 0, null);
      // Draw everything else ...
      // g.draw...
}
Ben Page