JComboBox: Comportamiento en ItemStateChange

Así que tengo el requisito de que, en función de la selección de un elemento de un JComboBox, necesito presentarle al usuario un cuadro de diálogo de confirmación de selección. lo que hice fue agregar un ItemListener y según cierta lógica, abro este cuadro de diálogo.

El problema bastante molesto al que me enfrento es que el cuadro de diálogo aparece primero (incluso cuando la selección de elementos de ComboBox está abierta) y tengo que hacer clic dos veces para confirmar mi selección. El primero es para cerrar la ventana emergente de ComboBox y el segundo es el actual en el cuadro de diálogo de confirmación.

Aquí hay un SSCCE que destaca mi problema:

import java.awt.event.ItemEvent;
import javax.swing.JOptionPane;

public class TestFrame extends javax.swing.JFrame {

    /**
     * Creates new form TestFrame
     */
    public TestFrame() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        selectCombo = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("Select Option");

        selectCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Option 1", "Option 2", "Option 3", "Option 4" }));
        selectCombo.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                selectComboItemStateChanged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(selectCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(168, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(22, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(selectCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(19, 19, 19))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void selectComboItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_selectComboItemStateChanged
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            String selectedItem = (String) selectCombo.getSelectedItem();
            if (selectedItem == null || selectedItem.equals("Option 1")) {
                return;
            } else {
                JOptionPane.showConfirmDialog(this, "Do you want to change option to - " + selectedItem + " ?", "Confirm Option Selection", JOptionPane.YES_NO_OPTION);
            }
        }
    }//GEN-LAST:event_selectComboItemStateChanged

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        try {
             javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new TestFrame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JComboBox selectCombo;
    // End of variables declaration//GEN-END:variables
}

¿Alguien puede decirme qué estoy haciendo mal? Quiero que aparezca el cuadro de diálogo de confirmación una vez que el usuario haya terminado de seleccionar su opción y se cierre la ventana emergente ComboBox.

preguntado el 27 de julio de 12 a las 20:07

Me olvidaría de esta idea de confirmación inmediata. Hace la aplicación molesto cuando usa el teclado para cambiar la selección emergente: cada vez que presiona la tecla de flecha hacia arriba o hacia abajo para recorrer las opciones, muestra la ventana emergente de confirmación. Considere pedir confirmación cuando se presiona algún botón OK, o al menos cuando se pierde el enfoque. -

@JBNizet - Gracias por el consejo. En realidad, esto tiene más sentido, no tomé en cuenta los cambios usando el teclado. Creo que voy a ir con la confirmación basada en la pérdida de atención. -

1 Respuestas

Lo haría invocando el método apropiado:

else {
            selectCombo.setPopupVisible(false);
            JOptionPane.showConfirmDialog(this, "Do you want to change option to - " + selectedItem
                    + " ?", "Confirm Option Selection", JOptionPane.YES_NO_OPTION);
        }

Respondido 27 Jul 12, 20:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.