Search code examples
javaswingjbuttonlayout-manager

Buttons overlap or disappear


I have an example of a error in my program. I created 4 buttons: 1, 2, 3, 4. Button 2 overlaps button 4, and i just added events for 2 and 4.

If I click on Button 2, it will be hidden, and Button 4 will be displayed. And if I click on Button 4, Button 2 will be displayed, and Button 4 will be covered by Button 2 again. As if anything happened, but, when I click on Button 1 or Button 3 after doing the above, Button 4 will be displayed, when I point at it (not click), it will disappear.

public class UI extends JFrame {

    public UI(String title) {
        Container container = this.getContentPane();
        container.setLayout(null);

        JButton btn1 = new JButton("1");
        btn1.setBounds(10, 10, 50, 50);
        btn1.setBackground(Color.RED);

        JButton btn2 = new JButton("2");
        btn2.setBounds(10, 70, 50, 50);
        btn2.setBackground(Color.GREEN);

        JButton btn3 = new JButton("3");
        btn3.setBounds(10, 130, 50, 50);
        btn3.setBackground(Color.BLUE);
    
        JButton btn4 = new JButton("4");
        btn4.setBounds(10, 70, 50, 50);
        btn4.setBackground(Color.YELLOW);

        container.add(btn1);
        container.add(btn2);
        container.add(btn3);
        container.add(btn4);

        btn2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                btn2.setVisible(false);
            }
        });
        btn4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                btn2.setVisible(true);
            }
        });
        this.setSize(400, 500);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
}

Single column of colored buttons


Solution

  • You simply have an error in the actionPerformed() methods. You need to change the visibility of both JButtons, not just one.

    Here is your code. I only added two lines and they are indicated by the comment // ADDED THIS LINE

    public class UI extends JFrame {
    
        public UI(String title) {
            Container container = this.getContentPane();
            container.setLayout(null);
    
            JButton btn1 = new JButton("1");
            btn1.setBounds(10, 10, 50, 50);
            btn1.setBackground(Color.RED);
    
            JButton btn2 = new JButton("2");
            btn2.setBounds(10, 70, 50, 50);
            btn2.setBackground(Color.GREEN);
    
            JButton btn3 = new JButton("3");
            btn3.setBounds(10, 130, 50, 50);
            btn3.setBackground(Color.BLUE);
        
            JButton btn4 = new JButton("4");
            btn4.setBounds(10, 70, 50, 50);
            btn4.setBackground(Color.YELLOW);
            btn4.setVisible(false);  // Initially we only want to see 'btn2'.
    
            container.add(btn1);
            container.add(btn2);
            container.add(btn3);
            container.add(btn4);
    
            btn2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btn2.setVisible(false);
                    btn4.setVisible(true);  // ADDED THIS LINE
                }
            });
            btn4.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btn2.setVisible(true);
                    btn4.setVisible(false);  // ADDED THIS LINE
                }
            });
            this.setSize(400, 500);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> new UI("UI"));
        }
    }
    

    Note that although the code works without it, I think you should set the initial visibility of btn4 to false. I have also done this in the above code.