How to disable certain items in a JComboBox

后端 未结 2 697
无人共我
无人共我 2021-01-25 07:12

I have a ComboBox in which I have 8 Items out of which I want to display all but on a certain condition, the user should only be able to select the first two of the

2条回答
  •  别那么骄傲
    2021-01-25 07:35

    First of all...

    This is going to require some hand coding. The GUI Builder is not going to help you out here.

    As for the rendering...

    You can implement your own BasicComboBoxRenderer, where you pass to it a ListSelectionModel. Based on the model you pass to it, only the selected interval will get rendered with the standard renderer. The remaining indices will get rendered in a disable fashion, by change the foreground color and it's selection background.

    Note: this is only going to affect the rendering of the items, not the actual selection events

    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.JList;
    import javax.swing.ListSelectionModel;
    import javax.swing.UIManager;
    import javax.swing.plaf.basic.BasicComboBoxRenderer;
    
    public class EnabledComboBoxRenderer extends BasicComboBoxRenderer {
    
        private ListSelectionModel enabledItems;
    
        private Color disabledColor = Color.lightGray;
    
        public EnabledComboBoxRenderer() {}
    
        public EnabledComboBoxRenderer(ListSelectionModel enabled) {
            super();
            this.enabledItems = enabled;
        }
    
        public void setEnabledItems(ListSelectionModel enabled) {
            this.enabledItems = enabled;
        }
    
        public void setDisabledColor(Color disabledColor) {
            this.disabledColor = disabledColor;
        }
    
        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
    
            Component c = super.getListCellRendererComponent(list, value, index,
                    isSelected, cellHasFocus);
    
            if (!enabledItems.isSelectedIndex(index)) {// not enabled
                if (isSelected) {
                    c.setBackground(UIManager.getColor("ComboBox.background"));
                } else {
                    c.setBackground(super.getBackground());
                }
    
                c.setForeground(disabledColor);
    
            } else {
                c.setBackground(super.getBackground());
                c.setForeground(super.getForeground());
            }
            return c;
        }
    }
    

    enter image description here

    As for selecting items...

    You can use two separate listeners. One for when the items are enabled and one for when the items are disabled. When the items are enabled, you can 1. Change the selection model 2. Add the enabled listener 3. Remove the disabled listener

    private class EnabledListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(((JComboBox) e.getSource()).getSelectedItem());
        }
    }
    
    private class DisabledListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[0]
                    && ((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[1]) {
                JOptionPane.showMessageDialog(null,
                        "You can't Select that Item", "ERROR",
                        JOptionPane.ERROR_MESSAGE);
            } else {
                System.out.println(((JComboBox) e.getSource())
                        .getSelectedItem());
            }
        }
    }
    
    protected void enableItemsInComboBox() {
        comboBox.removeActionListener(disabledListener);
        comboBox.addActionListener(enabledListener);
        model.setSelectionInterval(SELECTION_INTERVAL[0], comboBox.getModel()
            .getSize() - 1);
    }
    

    And vice versa

    protected void disableItemsInComboBox() {
        comboBox.removeActionListener(enabledListener);
        comboBox.addActionListener(disabledListener);
        model.setSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
    }
    

    enter image description here

    Here's a complete running example, using EnabledComboBoxRenderer from above

    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    
    import javax.swing.DefaultListSelectionModel;
    import javax.swing.JCheckBox;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;
    
    public class ComboBoxDisabledItemsDemo {
        private static final int[] SELECTION_INTERVAL = { 0, 1 };
    
        private JComboBox comboBox;
        private JCheckBox disableCheckBox;
        private DefaultListSelectionModel model = new DefaultListSelectionModel();
        private EnabledComboBoxRenderer enableRenderer = new EnabledComboBoxRenderer();
    
        private EnabledListener enabledListener = new EnabledListener();
        private DisabledListener disabledListener = new DisabledListener();
    
        public ComboBoxDisabledItemsDemo() {
            comboBox = createComboBox();
    
            disableCheckBox = createCheckBox();
            disableCheckBox.setSelected(true); // this adds the action listener to
                                                // the
                                                // to the combo box
    
            JFrame frame = new JFrame("Disabled Combo Box Items");
            frame.setLayout(new GridBagLayout());
            frame.add(comboBox);
            frame.add(disableCheckBox);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(300, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        private JComboBox createComboBox() {
            String[] list = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5",
                    "Item 6", "Item 7" };
            JComboBox cbox = new JComboBox(list);
            model.addSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
            enableRenderer.setEnabledItems(model);
            cbox.setRenderer(enableRenderer);
            return cbox;
        }
    
        private class EnabledListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(((JComboBox) e.getSource()).getSelectedItem());
            }
        }
    
        private class DisabledListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[0]
                        && ((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[1]) {
                    JOptionPane.showMessageDialog(null,
                            "You can't Select that Item", "ERROR",
                            JOptionPane.ERROR_MESSAGE);
                } else {
                    System.out.println(((JComboBox) e.getSource())
                            .getSelectedItem());
                }
            }
        }
    
        protected void disableItemsInComboBox() {
            comboBox.removeActionListener(enabledListener);
            comboBox.addActionListener(disabledListener);
            model.setSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
        }
    
        protected void enableItemsInComboBox() {
            comboBox.removeActionListener(disabledListener);
            comboBox.addActionListener(enabledListener);
            model.setSelectionInterval(SELECTION_INTERVAL[0], comboBox.getModel()
                    .getSize() - 1);
        }
    
        private JCheckBox createCheckBox() {
            JCheckBox checkBox = new JCheckBox("diabled");
            checkBox.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if (e.getStateChange() == ItemEvent.SELECTED) {
                        disableItemsInComboBox();
                    } else if (e.getStateChange() == ItemEvent.DESELECTED) {
                        enableItemsInComboBox();
                    }
                }
            });
            return checkBox;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new ComboBoxDisabledItemsDemo();
                }
            });
        }
    }
    

提交回复
热议问题