2012-06-20 10 views
7

Tengo un campo de texto en mi aplicación que se iniciará mediante programación (textField.setText()) cuando el usuario hace clic en un elemento en JList. después, el usuario cambiará este valor manualmente. Me quedo atascado con el uso de document-listener para detectar cambios en este campo de texto. Cuando los cambios se producen de forma programática, no deben hacer nada, pero si se produce manualmente, debería cambiar el fondo a rojo.¿Cómo hacer la diferencia entre textField.setText() y agregar texto a textField manualmente en java?

Cómo detectar si textField se ha completado manualmente o mediante textField.setText()?

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
     public void insertUpdate(DocumentEvent e) { 
      if (!mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.red); 
     } 

     public void removeUpdate(DocumentEvent e) { 
      if (mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.white);    
     } 

     public void changedUpdate(DocumentEvent e) { 
      //To change body of implemented methods 
     } 
    }); 

Respuesta

8

hay dos maneras

  • eliminar DocumentListenersetText("...") antes de añadir DocumentListener volver si se hace

código

public void attachDocumentListener(JComponent compo){ 
     compo.addDocumentListener(someDocumentListener); 
} 

//similair void for remove.... 
  • utilizar boolean valor para inhabilitar "si es necesario", pero hay que cambiar contens de su DocumentListener

por ejemplo

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
    public void insertUpdate(DocumentEvent e) { 
     if (!mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.red); 
     } 
    } 

    public void removeUpdate(DocumentEvent e) { 
     if (mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.white); 
     } 
    } 

    public void changedUpdate(DocumentEvent e) { 
     //To change body of implemented methods 
    } 
}); 
+1

El problema aquí es que algunas veces el setText() es llamado por alguien que no es su propio código. Este es el problema contra el que estoy luchando en este momento, de todos modos. Ojalá pudieran haber tenido un wasTriggeredByUser() en cada evento. – Trejkaz

+0

@Trejkaz, por favor, cómo, dónde, por qué, hay alguna razón especial, por cierto, el documento es el modelo para JTextComponents, luego consume/dispara todos los cambios y eventos entre los que se puede ver el modelo y viceversa – mKorbel

4

Tenga en cuenta que todos los detectores de eventos se ejecutan en el subproceso de oscilación Evento . Entonces, las cosas pueden no ir en el orden exacto que tú quieras. En esta situación, cualquier solución será hack-ish porque no puede obtener el control total sobre el hilo de swing y quién publica eventos en él.

Lo que estoy tratando de decir es esto: supongamos que elige usar alguna bandera para que sus oyentes sepan que se trata de un cambio programático. Aquí está el posible escenario (supongo que está siguiendo la buena regla de hacer cualquier actualización de la interfaz de usuario de la rosca oscilación a través de invokeLater):

  1. establecer el indicador para saltar eventos
  2. setText bandera
  3. conjunto de falsa

si lo hace todo en una invocación, el setText activará los eventos de actualización publicados al final de la cola de eventos, por lo tanto, cuando se ejecuten, la bandera ya será falsa.

Así que debe hacer los pasos 1 y 2 en una llamada invokeLater, o incluso invokeAndWait, y luego publicar otro evento con invokeLater para desarmar la bandera. Y ore para que su usuario no sea tan rápido como para hacer algunos cambios entre estas dos invocaciones, de lo contrario, también se considerarían un cambio programático.

Cuestiones relacionadas