Jcombobox popup is visible until you click the arrow

Asked

Viewed 145 times

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 actually been marked, it is necessary to open again.

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

Frame with the 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;
        }
    }
}
}

1 answer

1


Following the tip of this reply from Soen, one of the ways to do this is by changing the method setPopupVisible() of one’s own class JComboBox, adding a condition for this popup to remain open.

Since the goal is to keep open only when there is a change of some selection, you can use a flag. Create a variable like selectedHasChangedin your combobox class and set your starting value to false, as it is not desirable for the popup to be visible when opening the screen, and the setPopupVisible() will be called during the construction of the component on the screen:

private boolean selectedHasChanged = false;

In the method InteSelected(), 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 the setPopupVisible() set the flag to set the visibility:

@Override
public void setPopupVisible(boolean v) {

    super.setPopupVisible(selectedHasChanged);
}

See the result:

inserir a descrição da imagem aqui

  • Thank you, it worked, very interesting.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.