Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java swing - Repaint is duplicating components (JButtons and JLabels) when re-sized

I am having this weird problem. My professor can't seem to duplicate it and the help he offers is minimal at best. So to the point. This code produces a JButton on a panel and adds to the Content Pane of the JFrame:

public myPanel extends JPanel {
    static final long serialVersionUID = 1;
    public myPanel() {
        this.setPreferredSize(new Dimension(600, 40));
    }
    public void paintComponent(Graphics graphicsDrawer) {
        super.paintComponent(graphicsDrawer);
        this.add(new JButton("A Button"));
    }
}

Here is the GUI code

public class myGUI {
    public myGUI() {
    }
    public void showGUI() {
        JFrame frame = new JFrame("Issues!!!");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new myPanel());
        frame.pack();
        frame.setVisible(true);
    }
}

The GUI is then run by this class

// It is unnecessary to show here but I made a class that
// implements runnable that creates a myGUI object and calls
// showGUI
public static void main(String[] args) {
    RunnableGUI runGUI = new RunnableGUI();
    javax.swing.SwingUtilities.invokeLater(runGUI);
}

This is my code at bare minimum. However I have isolated this and the issue still persists even with the bare essentials. Below is a photo I am having the issue with.

Initial Frame w/ 1 button

Vertical Re-size creates extra buttons

I have tried literally everything I could find and think of.

I think the frame repaints the button each time it is re-sized. However the frame must be able to be re-sized because of the assignment requirements.

Running Windows 8 w/ JRE 7, 8 (I will download 6 but I do not think that will help)

like image 951
pdean Avatar asked Dec 09 '25 05:12

pdean


2 Answers

NEVER do this:

public void paintComponent(Graphics graphicsDrawer) {
    super.paintComponent(graphicsDrawer);
    this.add(new JButton("A Button"));  // ***** yikes! ****
}

The paintComponent method is for painting only. You don't have full control over whether or even if it will be called, and it can be called multiple times, meaning lots of buttons being added. Also, you want to avoid component creational code or any code that slows down program flow within a painting method since these methods partly determine the perceived responsiveness of your GUI, and so you will want the painting methods (paint and paintComponent) to be lean, mean and fast.

Add your button in your constructor or an initialization method so that you control how often that code gets called.

like image 121
Hovercraft Full Of Eels Avatar answered Dec 10 '25 19:12

Hovercraft Full Of Eels


public myPanel extends JPanel {
    static final long serialVersionUID = 1;
    public myPanel() {

        this.setPreferredSize(new Dimension(600, 40));
        this.add(new JButton("A Button"));
    }
    public void paintComponent(Graphics graphicsDrawer) {
        super.paintComponent(graphicsDrawer);

    }

}
like image 43
Ace McCloud Avatar answered Dec 10 '25 18:12

Ace McCloud



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!