Search code examples
javaswingjcombobox

Java: Make one item of a jcombobox unselectable(like for a sub-caption) and edit font of that item


How to make one item in a combobox unselectable because I need to separate items in a combobox with a sub-topic.

And is it possible to modify the font of that particular item individually?

        jComboBox_btech_course.setFont(new java.awt.Font("Tahoma", 0, 14));
        jComboBox_btech_course.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Select Course" }));
        jComboBox_btech_course.setName("");

private class theHandler implements ActionListener
{
    public void actionPerformed(ActionEvent evt) 
    {
        //BTech courses

        if(jComboBox_mtech_dept.getSelectedItem().equals("Civil Engineering"))
        {
            jComboBox_btech_course.removeAllItems();
            jComboBox_btech_course.addItem("Building Construction");
            jComboBox_btech_course.addItem("Principle And Practice");
            jComboBox_btech_course.addItem("Surveying");
            jComboBox_btech_course.addItem("Engineering Geology");
            jComboBox_btech_course.addItem("Structural Analysis");
            jComboBox_btech_course.addItem("Hydraulic Engineering");
            jComboBox_btech_course.addItem("Environmental Engineering");
            jComboBox_btech_course.addItem("Structural Design");
            jComboBox_btech_course.addItem("Geotechnical Engineering");
            /*This item has to be unselectable*/
            jComboBox_btech_course.addItem("***Sub-topic***");
            jComboBox_btech_course.addItem("Transportation Engineering");
            jComboBox_btech_course.addItem("Foundation Engineering");
            jComboBox_btech_course.addItem("Estimation & Valuation");
            jComboBox_btech_course.addItem("Hydrology & Flood Control");
            jComboBox_btech_course.addItem("System Analysis, Project Planning And Construction Management");
            jComboBox_btech_course.addItem("Irrigation Engineering");
            jComboBox_btech_course.addItem("Computer Application in Civil Engineering");
            jComboBox_btech_course.addItem("Planning, Design & Detailing");
        }
    }
}

Solution

  • Foreword: In the proposed solution I assume that you want to disable items that start with "**". You can change this logic to whatever you want to. In an improved version the MyComboModel class (see below) may even store which items are disabled allowing arbitrary items to be marked disabled.

    Solution to your question involves 2 things:

    1. Disallow selecting items which you want to be disabled

    For this you can use a custom ComboBoxModel, and override its setSelectedItem() method to do nothing if the item to be selected is a disabled one:

    class MyComboModel extends DefaultComboBoxModel<String> {
        public MyComboModel() {}
        public MyComboModel(Vector<String> items) {
            super(items);
        }
        @Override
        public void setSelectedItem(Object item) {
            if (item.toString().startsWith("**"))
                return;
            super.setSelectedItem(item);
        };
    }
    

    And you can set this new model by passing an instance of it to the JComboBox constructor:

    JComboBox<String> cb = new JComboBox<>(new MyComboModel());
    

    2. Display disabled items with different font

    For this you have to use a custom ListCellRenderer and in getListCellRendererComponent() method you can configure different visual appearance for disabled and enabled items:

    Font f1 = cb.getFont();
    Font f2 = new Font("Tahoma", 0, 14);
    
    cb.setRenderer(new DefaultListCellRenderer() {
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof JComponent)
                return (JComponent) value;
    
            boolean itemEnabled = !value.toString().startsWith("**"); 
    
            super.getListCellRendererComponent(list, value, index,
                    isSelected && itemEnabled, cellHasFocus);
    
            // Render item as disabled and with different font:
            setEnabled(itemEnabled);
            setFont(itemEnabled ? f1 : f2);
    
            return this;
        }
    });