2009-08-10 13 views
18

Tengo un editable JComboBox donde quiero tomar alguna medida cada vez que se cambia el texto, ya sea escribiendo o seleccionando. En este caso, el texto es un patrón y quiero verificar que el patrón sea válido y mostrar las coincidencias que dan como resultado algunos datos de prueba.¿Cómo puedo saber cuándo se ha cambiado el texto de un JComboBox editable?

Después de haber hecho lo obvio, adjuntar un ActionHandler, he encontrado que, para tipear, el evento parece disparar de manera no confiable, en el mejor de los casos (la selección está bien). Y cuando hace disparar como resultado de tipear, el texto recuperado (usando getEditor(). GetItem(), ya que getSelectedItem() solo obtiene el texto cuando se seleccionó de la lista) parece ser el texto tal como era cuando se disparó el último evento, es decir, siempre falta, el personaje se tipeó inmediatamente antes de que se disparara el evento de acción.

Esperaba que el evento de acción se disparara después de un breve retraso (de 500 ms a 1 segundo), pero parece que se dispara inmediatamente después de la incrustación (si se dispara).

La única alternativa viable que puedo pensar es simplemente iniciar un temporizador de 1 segundo en el enfoque ganado, matándolo en foco perdido y haciendo el trabajo como la acción del temporizador si el contenido es diferente de la última vez.

¿Algún comentario o sugerencia?

Los fragmentos de código no son particularmente interesantes:

find.addActionListener(this); 
... 
public void actionPerformed(ActionEvent evt) { 
    System.out.println("Find: "+find.getEditor().getItem()); 
    } 

Respuesta

30

El oyente acción se disparó por lo general sólo cuando se pulsa enter, o mover el foco lejos del editor de la lista desplegable. La forma correcta para interceptar los cambios individuales al editor es registrar un documento oyente:

final JTextComponent tc = (JTextComponent) combo.getEditor().getEditorComponent(); 
tc.getDocument().addDocumentListener(this); 

El DocumentListener interface tiene métodos que son llamados cuando el soporte de documentos el editor se modifica (insertUpdate, removeUpdate, changeUpdate).

También puede utilizar una clase anónima para un control más preciso de donde los eventos son procedentes de:

final JTextComponent tcA = (JTextComponent) comboA.getEditor().getEditorComponent(); 
tcA.getDocument().addDocumentListener(new DocumentListener() { 
    ... code that uses comboA ... 
}); 

final JTextComponent tcB = (JTextComponent) comboB.getEditor().getEditorComponent(); 
tcB.getDocument().addDocumentListener(new DocumentListener() { 
    ... code that uses comboB ... 
}); 
+0

Gracias, voy a intentar esto. No me importa Swing como un todo, pero a veces averiguar cómo obtener cierto comportamiento o atrapar ciertos eventos es ** FAR ** obvio. –

+0

OK, así que dejando a un lado los "19" niveles de método de llamada ... Después de haber agregado un detector de documentos, cuando ocurre el evento no encuentro forma de vincularlo con cuál de los dos cuadros combinados se cambiaron. En este punto, un temporizador simple parece bastante atractivo. –

+0

Almacena el último texto conocido para los dos CB y lo uso para determinar cuál ha cambiado cuando se dispara el evento del documento. Si sabe cómo relacionar el evento con el componente que lo activó, esa información sería útil, ya que un DocumentEvent no es un evento AWT estándar o java.util.EventObject. –

0

Puede usar algo como esto:

JComboBox cbListText = new JComboBox(); 
cbListText.addItem("1"); 
cbListText.addItem("2"); 
cbListText.setEditable(true); 
final JTextField tfListText = (JTextField) cbListText.getEditor().getEditorComponent(); 
tfListText.addCaretListener(new CaretListener() { 
    private String lastText; 

    @Override 
    public void caretUpdate(CaretEvent e) { 
     String text = tfListText.getText(); 
     if (!text.equals(lastText)) { 
      lastText = text; 
      // HERE YOU CAN WRITE YOUR CODE 
     } 
    } 
}); 
-1

esto suena como la mejor solución

jComboBox.getEditor().getEditorComponent().addKeyListener(new java.awt.event.KeyAdapter() { 
public void keyReleased(java.awt.event.KeyEvent evt) { //add your hadling code here: 

} }); 
+1

Esto omite los cambios realizados sin usar el teclado (por ejemplo, pegar o eliminar texto usando el dispositivo señalador). – Martin

Cuestiones relacionadas