Search code examples
javaswinganimationgraphics2d

Java Graphics: setClip vs clipRect vs repaint(int,int,int,int)


Similar to my last post apologies, but a lot less long winded. Basically I am wondering what is the best option for optimising redrawing to a JFrame/JPanel when each repaint call only a small part of the screen would be redrawn.

Also apart from overloading repaint I am not 100% on how to implement setClip or clipRect. My understanding they are used when overriding paint or update? See below for some code:

public class AquaSim extends JPanel {
//variables
//other methods...
    public void paint (Graphics g) {
       super.paintComponent(g); //needed?
       Graphics2D g2d = (Graphics2D) g;

        //Draws the land area for penguins.
        g2d.setColor(new Color(121,133,60));
        g2d.fill(land);
        g2d.setColor(Color.BLUE);
        g2d.fill(sea);

        drawCreatures(g2d);
}
    public void drawCreatures(Graphics2D g2d) {
        for (Creature c : crlist) //a list of all alive creatures {
            //each creature object stores its image and coords.
            g2d.drawImage(c.createImage(txs,tys), c.getPos(1).width, c.getPos(1).height, this);
        }
    }
}

Ideally I would prefer not to have to loop though each creature object each repaint request, which is part of the reason for this post. I dont know if there would be a way of sending the current creature being drawn to paint or overriding paint in the Creature class to get it draw itself on to the graphics object in the main class. A bit more code...

private class Creature implements ActionListener {
//variables & other methods
        @Override
        public void actionPerformed(ActionEvent e) {
            if (getState()!=State.DEAD) {
                move();
                repaint(); //<---Would rather set clipping area in paint/update. x,y,w,h needs to include ICON & INFO BOX.
                //repaint(gx,gy,getPos(1).width,getPos(1).height);
            }
            else anim.stop();
        }
//...


  public void move() {
    //Determines how it will move and sets where to here by updating its position that is used in drawCreatures.
    }
}

So any suggestions as which would be the most efficient method to use? Baring in mind repaint will be called a lot by many objects/creatures i.e. many times a second, hence why I dont want it redrawing everythin on the screen each repaint request.


Solution

  • only a small part of the screen would be redrawn.

    Use repaint(....).

    The RepaintManager will worry about what needs to be painted and will set the clip of the Graphics object for you.