Reputation: 57
So I'm working on a game that consists of two grids. Each grid is a JPanel where I paint an object over (possibly) each space in the grid. I have found that PAINTING the object is slowing down the application, and I was wondering if there is a way to prevent this from happening.
The Details:
each grid is 6x12, so potentially 144 objects (extreme case) plus the background will be painted onto the entire frame at once.
each object that is painted is a 16x16 image file that gets scaled up depending on the size, don't know if this is relevant, but I have provided the constructor for the object class just in case it might have something to do with initializing the image?
Don't know how to explain this one but the Image is never saved in the object. The getImage() function creates and returns the Image when it is called by another class.
Currently the project is set up to have the Object array initialized when the game starts. It does not slow down until switching to the Board JPanel and the objects are painted.
The objects are only painted once when the Board JPanel is shown
paintComponent from the Board class:
//public Board extends JPanel
// boardManager holds an array of the objects
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 6; j++) {
if(boardManager.getVisibility(i, j)) {
g.drawImage(
boardManager.getImage(i, j),
boardManager.getX(i, j),
boardManager.getY(i, j),
this
);
}
}
}
}
getImage(int, int) from the BoardManager class:
public Image getImage(int x, int y) {
return grid[x][y].getImage();
}
Constructor from the Object class:
private int current;
public Object(Game frame, int x, int y, String c, Boolean vis) {
this.frame = frame;
xPos = x;
yPos = y;
color = c;
visible = vis;
current = 01;
imgPath = "/game/img/" + color + "/";
}
getImage() from the Object class:
public Image getImage() {
try {
BufferedImage img = ImageIO.read(this.getClass().getResource(imgPath + current + ".png"));
Image scaledImg = img.getScaledInstance(16 * frame.scale, 16 * frame.scale, Image.SCALE_FAST);
return scaledImg;
}
catch(IOException | IllegalArgumentException ex) {
System.err.println("Error: file not found " + imgPath + current + ".png");
}
return null;
}
My main concern is that as the boards get filled up, the game will start to slow down as it progresses, which might be a future issue. Right now the lag isn't very bad, but I've only been able to test what happens when only one board is filled up so far. I believe it will get even worse as both boards are filled.
Is there any issue with how my code is set up for this? Or is there a more effective way to deal with this?
Upvotes: 0
Views: 217
Reputation: 324118
From what I can tell your paintComponent() method ultimately invokes:
BufferedImage img = ImageIO.read(this.getClass().getResource(imgPath + current + ".png"));
Don't do IO in a painting method. This will slow down the painting.
The images should be read in the constructor of your class. Then the painting method can just access the image from you image cache.
Also you should scale the images once when you read them in.
Upvotes: 1