javavectorjcomboboxjcheckboxitemlistener

How to hide elements with in a JComboBox?


Say I have a JComboBox which contains elements that are in a vector...

 public class Shade(){
       //code for creating panels etc and other components/containers
       JCheckBox primary = new JCheckBox("Primary", false);           
       Vector<String> colours = new Vector<String>();
}
public Shade(){
//setTitle, look&feel, defaultCloseOperation, Layouts etc etc...

 colours.add(0, "Purple);
 colours.add(1, "Red");
 colours.add(2, "Blue");
 colours.add(3, "Magenta");

JComboBox<String> colourSelector = new JComboBox<String>(colours);

}

If the JCheckBox primary is selected I want to 'hide' the colours purple and magneta from the JComboBox, once the primary JCheckBox has been deselected I would like to reveal the hidden elements, so that the original list pertains.

I tried doing this...

   public class eventHandler implements itemListener(){

   Shade refObj;
public eventHandler(Shade rinseFM){
refObj = rinseFM;
}

#Overriding abstract implemented method...
public void itemStateChanged(ItemEvent event){

if(refObj.primary.isSelected() == true){
refObj.colours.hide(// index of colours required to hide))
}
}
}

The hide method doesn't actually exist, is there anything analogous to this.


Solution

  • Try this:

    private JFrame frame = new JFrame("JComboExample");
    private JCheckBox primary = new JCheckBox("Primary");
    private JComboBox<String> colorSelector;
    
    private String[] colorsToHide = { "Purple", "Magenta" };
    
    public JComboExample() {
        SwingUtilities.invokeLater(() -> {
            setupFrame();
            setupCheckbox();
            initJComboBox("Purple", "Red", "Blue", "Magenta");
            frame.add(primary, BorderLayout.NORTH);
            frame.add(colorSelector, BorderLayout.CENTER);
        });
    }
    
    private void setupFrame() {
        frame.setSize(300, 100);
        frame.setLocationByPlatform(true);
        frame.setDefaultCloseOperation(3);
        frame.setLayout(new BorderLayout());
    }
    
    private void setupCheckbox() {
        primary.addActionListener(event -> {
            if(primary.isSelected()) {
                for(String color: colorsToHide) {
                    colorSelector.removeItem(color);
                }
    
            } else {
                for(String color: colorsToHide) {
                    colorSelector.addItem(color);
                }
            }
        });
    }
    
    private void initJComboBox(String... colors) {
        colorSelector = new JComboBox<String>(colors);
    }
    
    public void setVisbility(boolean visibility) {
        frame.setVisible(visibility);
    }
    
    public static void main(String[] args) {
        JComboExample example = new JComboExample();
        example.setVisbility(true);
    }
    

    This class implements a callback(adds an ActionListener) when the checkbox is clicked. In the callback, when the checkbox is activated, we simply remove the colors in the array colorsToHide. If the checkbox is not activated, we add them back.

    Side notes:

    In Java, you should not be using a vector for this purpose. Vectors are largely considered obsolete. See this post: Why is Java Vector class considered obsolete or deprecated?

    You should also create all GUI / handle all GUI state changes on the EDT. Swing is not thread-safe and although in most cases it may appear un-needed, it is good practice to call SwingUtilities.invokeLater or SwingUtilities.invokeAndWait before handling the GUI.