Search code examples
javaswingjpaneljcheckboxnetbeans-8

add jPanels by selecting jCheckBoxes


As you can see from layout I want to add (or show) jPanels by selecting checkBoxes. panelWindow is enclosed in jScrollPane.

 + checkBox1  |            jPanel1  |
-------------------------------------
 + checkBox2  |            jPanel2  |
-------------------------------------
 + checkBox3  |            jPanel3  |
-------------------------------------
      ^                       ^
      |                       |
 checkBoxPanel            panelWindow

In the case when selected checkBox2 and checkBox3, panelWindow shows jPanel2 and jPanel3, so the position of jPanel1 will be replaced by jPanel2 and the position of jPanel2 by jPanel3.

 + checkBox2  |            jPanel2  |
-------------------------------------
 + checkBox3  |            jPanel3  |
------------------------------------- 
      ^                       ^
      |                       |
 checkBoxPanel            panelWindow

Right now I don't have any idea how to achieve this goal. I tried to use CardLayout, but in that case panelWindow just switches jPanels.

The goal I want to achieve is by selecting several checkBoxes show the selected jPanels in panelWindow. And if the any checkBoxes doesn't selected, in that case panelWindow is empty.

Thank you in advance.


Solution

  • As suggested by @StanislavL, I created a Map between the JCheckBoxes and the JPanels with an ItemListener for showing and hiding the panels.

    public class PanelShower extends JFrame {
    
        Map<JCheckBox, JPanel> boxPanelMap = new HashMap<>();
        final int size = 5;
    
        public PanelShower() {
    
            JPanel boxesPanel = new JPanel();
            boxesPanel.setLayout(new BoxLayout(boxesPanel, BoxLayout.PAGE_AXIS));
    
            JPanel panelsPanel = new JPanel();
            panelsPanel.setLayout(new BoxLayout(panelsPanel, BoxLayout.PAGE_AXIS));
    
            for (int i = 0; i < size; i++) {
                JCheckBox checkBox = new JCheckBox("Box " + i);
                checkBox.addItemListener(new SelectionListener());
                boxesPanel.add(checkBox);
    
                JPanel panel = new JPanel();
                panel.setPreferredSize(new Dimension(200, 75));
                panel.setBackground(new Color( (int) (Math.random() * (Math.pow(2, 24) - 1) ) ));
                panel.add(new JLabel("Panel " + i));
                panel.setVisible(false);
                panelsPanel.add(panel);
    
                boxPanelMap.put(checkBox, panel);
            }
    
            getContentPane().add(boxesPanel, BorderLayout.LINE_START);
            getContentPane().add(panelsPanel, BorderLayout.CENTER);
    
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            pack();
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        private class SelectionListener implements ItemListener {
    
            @Override
            public void itemStateChanged(ItemEvent e) {
    
                (boxPanelMap.get(e.getSource())).setVisible(e.getStateChange() == ItemEvent.SELECTED);
                pack();
            }
        }
    
        public static void main(String args[]) {
    
            new PanelShower();
        }
    }
    

    Notes:

    • The pack() call inside the ItemListener is necessary just for respecting the preferred size I set for the panels.
    • You might want to have the ItemListener to be more "type safe" by passing the JCheckBox to it in construction:

      private class SelectionListener implements ItemListener {
      
          JCheckBox checkBox;
      
          SelectionListener(JCheckBox checkBox) {
      
              this.checkBox = checkBox;
          }
      
          @Override
          public void itemStateChanged(ItemEvent e) {
      
              (boxPanelMap.get(checkBox)).setVisible(e.getStateChange() == ItemEvent.SELECTED);
              pack();
          }
      }