0

I have a JFrame and two JPanels. First of them has "go on" button and the second one has "go back" button. When the program starts, the first panel is added to the frame. When I press "go on" button, I want to replace panels - the same with "go back".

public class Main extends JFrame {

    private final int width = 320;
    private final int height = 640;

    private JPanel firstPanel;
    private JPanel secondPanel;

    private JButton goOn;
    private JButton goBack;


    public Main() {

        firstPanel = new JPanel();
        firstPanel.setBackground(Color.yellow);
        firstPanel.setOpaque(true);
        firstPanel.setPreferredSize(new Dimension(width, height));
        goOn = new JButton("Go on");
        goOn.setPreferredSize(new Dimension(width/2, height/2));
        firstPanel.add(goOn);

        secondPanel = new JPanel();
        secondPanel.setBackground(Color.green);
        secondPanel.setOpaque(true);
        secondPanel.setPreferredSize(new Dimension(width, height));
        goBack = new JButton("Go back");
        goBack.setPreferredSize(new Dimension(width/2, height/2));
        secondPanel.add(goBack);

        showFirstPanel();

        setResizable(false);
        pack();

        setLocationRelativeTo(null);
        setVisible(true);

        addButtonsListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("Go on"))
                    showSecondPanel();
                else
                    showFirstPanel();
            }
        });
    }

    public void showFirstPanel() {
        remove(secondPanel);
        add(firstPanel);
    }

    public void showSecondPanel() {
        remove(firstPanel);
        add(secondPanel);
    }

    public void addButtonsListener(ActionListener listener) {
        goOn.addActionListener(listener);
        goBack.addActionListener(listener);
    }

    public static void main (String[] args) {
        new Main();
    }
}

The problem is when I press the first button, the program hangs. Sometimes it works after 10-20 seconds. The same situation happens with "go back" button.

Wojtek
  • 1,288
  • 11
  • 16
  • 1
    `revalidate` and `repaint` the JPanel when adding items to an already visible container. Also consider using a [CardLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) rather than removing/adding Components to an already visible Container. – copeg Sep 21 '16 at 21:24
  • 1
    Why not use a [Card layout](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)? – Frakcool Sep 21 '16 at 21:25
  • I'll second adding the repaints... and perhaps a doLayout. Your program isn't hanging, it just appears as though it is. – slambeth Sep 21 '16 at 21:38
  • Revalidating and repainting helped, thanks for advices! – Wojtek Sep 21 '16 at 21:42
  • 1) Agree with @Frakcool - a `CardLayout` is the best approach here. 2) See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Sep 22 '16 at 00:06

1 Answers1

0

I advice you to forget about remove() and replace it with setVisible() so your code will be

    public class Main extends JFrame {

       private final int width = 320;
       private final int height = 640;

       private JPanel firstPanel;
       private JPanel secondPanel;

       private JButton goOn;
       private JButton goBack;


       public Main() {

           firstPanel = new JPanel();
           firstPanel.setBackground(Color.yellow);
           firstPanel.setOpaque(true);
           firstPanel.setPreferredSize(new Dimension(width, height));
           goOn = new JButton("Go on");
           goOn.setPreferredSize(new Dimension(width/2, height/2));
           firstPanel.add(goOn);

           secondPanel = new JPanel();
           secondPanel.setBackground(Color.green);
           secondPanel.setOpaque(true);
           secondPanel.setPreferredSize(new Dimension(width, height));
           goBack = new JButton("Go back");
           goBack.setPreferredSize(new Dimension(width/2, height/2));
           secondPanel.add(goBack);

           add(firstPanel);
           add(secondPanel);

           showFirstPanel();
           setResizable(false);
           pack();

           setLocationRelativeTo(null);
           setVisible(true);

           addButtonsListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                    if (e.getActionCommand().equals("Go on"))
                       showSecondPanel();
                    else
                       showFirstPanel();
              }
          });
       }

       public void showFirstPanel() {
               secondPanel.setVisible(false);
               firstPanel.setVisible(true);
        }

        public void showSecondPanel() {
             firstPanel.setVisible(false);
             secondPanel.setVisible(false);
        }

        public void addButtonsListener(ActionListener listener) {
              goOn.addActionListener(listener);
              goBack.addActionListener(listener);
        }

        public static void main (String[] args) {
            new Main();
       }
     }
  • 2
    (1-) What if you have more than two panels? This code does not scale. Instead the proper solution is to use a `CardLayout` as has already been suggested in the first two comments to this question. – camickr Sep 22 '16 at 02:28