Popup of JComboBox is visible until you click the arrow

2

I have a JComboBox populated with JCheckBox's working normally, but when I click on an item, the JComboBox popup closes. To see if JCheckBox has really been checked, it is necessary to open it again.

I wanted to know if it's possible to make the popup close only when you click on that little set that is on the side again.

Frame with JComboBox:

package NewClass;

import javax.swing.JCheckBox;

public class NewJFrame1 extends javax.swing.JFrame {

    JCheckBox[] jcb1 = new JCheckBox[3];

    public NewJFrame1() {
        jcb1[0] = new JCheckBox("Inclusão");
        jcb1[1] = new JCheckBox("Alteração");
        jcb1[2] = new JCheckBox("Exclusão");
        initComponents();
        jComboBox1.insertItemAt("Opções", 0);
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jComboBox1 = new JComboCheckBox(jcb1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(84, 84, 84)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(202, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(62, 62, 62)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(218, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JComboBox<String> jComboBox1;
    // End of variables declaration                   
    }

Class that inserts JCheckBox's in JComboBox:

package NewClass;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JComboCheckBox extends JComboBox {

public JComboCheckBox() {
    addStuff();
}

public JComboCheckBox(JCheckBox[] items) {
    super(items);
    addStuff();
}

private void addStuff() {
    setRenderer(new ComboBoxRenderer());
    addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            itemSelected();
        }
    });
}

private void itemSelected() {
    if (getSelectedItem() instanceof JCheckBox) {
        JCheckBox jcb = (JCheckBox) getSelectedItem();
        jcb.setSelected(!jcb.isSelected());
        setSelectedIndex(0);
    }

}

class ComboBoxRenderer implements ListCellRenderer {

    private JLabel defaultLabel;

    public ComboBoxRenderer() {
        setOpaque(true);
    }

    public Component getListCellRendererComponent(JList list, Object value, int index,
            boolean isSelected, boolean cellHasFocus) {
        if (value instanceof Component) {
            Component c = (Component) value;
            if (isSelected) {
                c.setBackground(Color.WHITE);
                c.setForeground(Color.BLACK);
            } else {
                c.setBackground(Color.WHITE);
                c.setForeground(Color.BLACK);
            }
            return c;
        } else {
            if (defaultLabel == null) {
                defaultLabel = new JLabel(value.toString());
            } else {
                defaultLabel.setText(value.toString());
            }
            return defaultLabel;
        }
    }
}
}
    
asked by anonymous 25.06.2018 / 20:20

1 answer

1

Following the hint of this SOEn response , one way to do this is by changing the method setPopupVisible() of the class JComboBox itself, adding a condition for this popup to remain open.

Since the goal is to keep open only when a selection is changed, you can use a flag. Create a variable such as selectedHasChanged in your combobox class and set its initial value to false , since it is not desirable for the popup to be visible when you open the screen, and setPopupVisible() will be called during component build on the screen :

private boolean selectedHasChanged = false;
In the InteSelected() method, you change the flag to true :

private void itemSelected() {
    if (getSelectedItem() instanceof JCheckBox) {
        JCheckBox jcb = (JCheckBox) getSelectedItem();
        jcb.setSelected(!jcb.isSelected());
        setSelectedIndex(0);
    }
    selectedHasChanged = true;
}

And in% w / o% set the flag to set the visibility:

@Override
public void setPopupVisible(boolean v) {

    super.setPopupVisible(selectedHasChanged);
}

See the result:

    
25.06.2018 / 20:54