views:

245

answers:

3

I'm doing a simple grid which each square is highlighted by the cursor: alt text

They are a couple of JPanels, mapgrid and overlay inside a JLayeredPane, with mapgrid on the bottom. Mapgrid just draws on initialization the grid, its paint metodh is:

public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            g2d.setColor(new Color(128, 128, 128, 255));
            g2d.drawRect(tileSize * j, i * tileSize, tileSize, tileSize);

        }
    }

In the overlay JPanel is where the highlighting occurs, this is what is repainted when the mouse is moved:

    public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);


    g2d.setColor(new Color(255, 255, 128, 255));
    g2d.drawRect((pointerX/tileSize)*tileSize,(pointerY/ tileSize)*tileSize, tileSize, tileSize);

}

I noticed that even though the base layer (mapgrid) is NOT repainted when the mouse moves, just the transparent overlay layer, the performance is lacking. If i give the overlay JPanel a background, its way faster. If i remove the mapgrid Antialiasing, its a bit faster too.

I don't know why giving a background to the overlay layer (and thus, hiding the mapgrid) or disabling antialiasing in the mapgrid leads to much better performance.

Is there a better way to do this? Why does this happen?

+2  A: 

Instead of drawRect your could drawLine. You should get the same visual result but I think it will be much faster.

Also, if the background is always the same I would recommend drawing to a buffered image at initialization (or when the frame is resized) and then just draw that image. That should speed up the drawing.

Manuel Darveau
Why i should change the way I draw the grid? The bottom layer is repainted as well even though i did not specified to do so?
Gabriel A. Zorrilla
@Gabriel The whole window gets buffered. If you repaint a section of it, then everything contributing to that section will need to be repainted. There isn't per-component buffering (by default).
Tom Hawtin - tackline
+1  A: 

If all of your Mapgrid is the same color, pull the setColor up out of the loop. Right now each call to paint is creating w*h new Color objects.

Devon_C_Miller
+1  A: 

I noticed that even though the base layer (mapgrid) is NOT repainted when the mouse moves, just the transparent overlay layer, the performance is lacking.

That doesn't make sense to me. Since your overlay panel only does a drawRect(...) for the grid the mouse is currently over, how does the previous grid get reset? I would guess when you repaint your overlay panel it is not opaque, to the mapgrid would have to repaint the entire grid first before you redraw the grid on your overlay panel.

Is there a better way to do this?

Keep track of the last painted grid. Then you can invoke repaint(Rectangle) to only repaint that grid on the map grid panel. Then you can also invoke repaint(Rectangle) on your overlay panel to redraw the grid on the overlay panel.

If you need more help post your SSCCE that demonstrates the problem.

camickr