2011-03-04 15 views
11

Tengo un componente JComboBox en el panel y ItemListener conectado a él. Pero se dispara después de cada pulsación arriba/abajo (cuando se desplaza a través de la lista emergente abierta). Deseo cambiar el valor seleccionado después de que el usuario acepte la selección presionando, por ejemplo, la tecla Intro.Cómo hacer que el elemento seleccionado de JComboBox no cambie al desplazarse por su lista emergente usando el teclado

Esto no es un caso cuando se utiliza el mouse. Cuando muevo el mouse sobre la lista del cuadro combinado, el resaltado sigue al puntero del mouse, pero el elemento seleccionado no cambia hasta que presiono el botón del mouse. Me gustaría tener el mismo comportamiento para el teclado, es decir, mover el resaltado mediante la flecha hacia arriba o hacia abajo no cambia el elemento seleccionado, pero presionar Enter sí lo hace.

Respuesta

17

creo que debería ser capaz de hacer:

comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); 

después de haber creado la instancia comboBox a get this functionality

+0

Sí, esto es exactamente lo que quería lograr. Muchas gracias. – toomyem

+0

Parece que esto no funciona para PgUp/PgDn. –

0

Su comportamiento esperado con el ItemListener. cada vez que el valor visualizado cambia, el evento se dispara. Para su requerimiento use un ActionListener.

+0

No, esto es lo mismo. actionPerformed se activa con cada pulsación de tecla arriba/abajo. – toomyem

1

el método JComboBox.isTableCellEditor funciona para el movimiento de flecha a través de la lista, pero no funciona para escritura anticipada compatible con KeySelectionManager. es decir, usted todavía obtiene ActionEvents para cada tecla que no sea de navegación que el usuario escriba, ya que JComboBox interpreta esos caracteres para buscar, aunque el modelo, moverse a (o acercarse a) la selección deseada por el usuario.

esta solución tiene el inconveniente de que cambie el comando de acción para los clics del ratón, que era un compromiso bien para mí, ya que el flujo de la interfaz gráfica de usuario obliga al usuario a cambiar el foco en el cuadro combinado

Terminé creando un KeyListener especial, que se basa en cambiar el comando de acción predeterminado del cuadro combinado de comboBoxChanged a comboBoxMovement. Aquí está la línea de código que necesito después de mi cuadro combinado es todo inicializado:

setExplicitSelectionManager(myComboBox); 

... y aquí está el método y su clase contenidos que haga todo el trabajo:

private void setExplicitSelectionManager(JComboBox comboBox) { 

    class ExplicitSelectionManager implements KeyListener, FocusListener { 

     private JComboBox src; 
     private KeyListener superKeyListener; 

     ExplicitSelectionManager(JComboBox src) { 
      this.src = src; 

      // we like what the default key listener does, but not the action command 
      // it uses for ActionEvents it fires for plain text type-ahead characters 
      this.superKeyListener = src.getKeyListeners()[0]; // we only have one 
      src.removeKeyListener(superKeyListener); // will be replace right away, below 
     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      // basic combo box has no code in keyTyped 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 

      // in the default JComboBox implementation, the KeySelectionManager is 
      // called from keyPressed. I'm fine with the implementation of 
      // the default, but I don't want it firing ActionEvents that will cause 
      // model updates 
      src.setActionCommand("comboBoxMovement"); 
      this.superKeyListener.keyPressed(e); 
      src.setActionCommand("comboBoxChanged"); 

      if (e.getKeyCode() == 10) { 
       src.setSelectedIndex(src.getSelectedIndex()); 
      } 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // basic combo box has no code in keyReleased 
     } 

     @Override 
     public void focusGained(FocusEvent e) { 
     } 

     @Override 
     // this will also give us the event we want, if the user decides to Tab out of 
     // the combo box, instead of hitting Enter 
     public void focusLost(FocusEvent e) { 
      src.setSelectedIndex(src.getSelectedIndex()); 
     } 
    } 

    ExplicitSelectionManager newSelectionManager = new ExplicitSelectionManager(comboBox); 

    comboBox.addKeyListener(newSelectionManager); 
    comboBox.addFocusListener(newSelectionManager); 

} 

... y aquí está el método de acción realizada

private void comboBoxActionPerformed(java.awt.event.ActionEvent evt) {             

    JComboBox source = (JComboBox) evt.getSource(); 

    //  "comboBoxChanged" is the default, 
    // so any normal JComboBox can also use this action listener 
    if (evt.getActionCommand().equals("comboBoxChanged")) { 
     updateModel(source.getName(), (String) source.getSelectedItem()); 
    } 
}            
1

En Java 8 se han fijado este comportamiento, pero sólo si u desencadenar establecer una propiedad de interfaz de usuario

UIManager.getLookAndFeelDefaults().put("ComboBox.noActionOnKeyNavigation", true); 
Cuestiones relacionadas