melar melar - 4 months ago 13
Java Question

Why do the GUI Elements are doubled after each call on repaint() method?

im having a problem with my GUI. im building a grid on my jpanel which is a separate class than the class that extends jframe. when i click a button and choose to open grid which is handled in the jframe class and then click on that grid generated in the jpanel class, a second grid appears. that means: another grid shifted 1 centimeter to the south of the original one. im guessing it has to do with the repaint() method as is the case with flickering problems. im calling that method in both the jframe and jpanel classes. still i cant wrap my head around it. Where is the problem here? funny though, the second grid disappears as soon as i click on the shortcut top right of my gui window to minimise the window and then maximise it. Im Providing two methods, that i think are related to my problem. Right below is the openFile method which reacts to a buttonlistener in my jframe class

public void openFile() {
final JFileChooser chooser = new JFileChooser();
add(chooser);
if (selectedFilePath != null) {
chooser.setCurrentDirectory(new File(selectedFilePath));
} else {
chooser.setCurrentDirectory(new File(System
.getProperty("user.home")));
}
int result = chooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = chooser.getSelectedFile();
selectedFilePath = selectedFile.getAbsolutePath();
BGSRead bgs = new BGSRead();
bgs.readString(selectedFilePath);
bgs.readFile();
width = bgs.getWidth();
height = bgs.getHeight();
numberOfIslands = bgs.getNumberOfIslands();
islandsListInAscendingOrder = bgs.getIslandsOrder();
bridgeList=bgs.getBridgeList();
if (grid != null) {
remove(grid);
}
grid = new GameField(width, height,
islandsListInAscendingOrder,bridgeList);
add(grid);
grid.setVisible(true);
validate();
repaint();
}
}


and here is the paintComponent() method in my jpanel class:

protected void paintComponent(Graphics g) {
// draw grid

/*
* for (int i = 0; i < height; i++) { g.drawLine(GameMain.GAP, i *
* GameMain.GAPBETWEENPOINTS + GameMain.GAP, (width - 1) *
* GameMain.GAPBETWEENPOINTS + GameMain.GAP, i *
* GameMain.GAPBETWEENPOINTS + GameMain.GAP); } for (int i = 0; i <
* width; i++) { g.drawLine(i * GameMain.GAPBETWEENPOINTS +
* GameMain.GAP, GameMain.GAP, i * GameMain.GAPBETWEENPOINTS +
* GameMain.GAP, (height - 1) * GameMain.GAPBETWEENPOINTS +
* GameMain.GAP); }
*/
// draw circles
if (islandListInAscendingOrder.size() > 0) {
for (int i = 0; i < islandListInAscendingOrder.size(); i++) {
x = islandListInAscendingOrder.get(i).getIslandCoordinate().x
* GameMain.GAPBETWEENPOINTS + GameMain.GAP
- (GameMain.R / 2);
y = islandListInAscendingOrder.get(i).getIslandCoordinate().y
* GameMain.GAPBETWEENPOINTS + GameMain.GAP
- (GameMain.R / 2);
g.drawOval(x, y, GameMain.R, GameMain.R);
}
}
}

Answer
protected void paintComponent(Graphics g) {

Should instead be:

protected void paintComponent(Graphics g) {
    super.paintComponent(g); // clear previous drawing!

Calling the super method paints the component background, hence erasing earlier drawings.