Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to find source component that generated a DocumentEvent

Is it possible to discover which oject generated a DocumentEvent? Something like i can do with ActionListener:

JTextField field = new JTextField("");
field.addActionListener(actionListener);

//inside ActionListener
public void actionPerformed(ActionEvent arg0) {
  if (arg0.getSource() instanceof JTextField) //true

}

I would like to do the same with DocumentEvent but seems not to work the same way:

JTextField field = new JTextField("");
field.getDocument.addDocumentListener(documentListener);
//inside documentListener
public void insertUpdate(DocumentEvent){
  if (arg0.getSource() instanceof JTextField) //false: class is javax.swing.text.PlainDocument
  if (arg0.getSource() instanceof MyComponent){
      MyComponent comp = (MyComponent)arg0.getSource();
      comp.callSpecificMethodUponMyComp(); 
  }
}

The answser should take in consideration the following points:

  1. For my purposes knowing the object type that generated the event isn't enough, but i need a reference to it at runtime.
  2. Typically the events are generated from extension of the swing object (myComp public JTextField). These objects store additional information that should be retrieved at runtime inside the listener method (es. insertUpdate)
  3. DocumentListener is implemented from a class that is unaware of the fields that generated the events. Differents fields of differents types can be attacched to the listener at runtime.
like image 743
Heisenbug Avatar asked Mar 07 '11 10:03

Heisenbug


2 Answers

You can set a property in the document to tell you which textcomponent the document belongs to:

For example:

final JTextField field = new JTextField("");
field.getDocument().putProperty("owner", field); //set the owner

final JTextField field2 = new JTextField("");
field2.getDocument().putProperty("owner", field2); //set the owner

DocumentListener documentListener = new DocumentListener() {

     public void changedUpdate(DocumentEvent documentEvent) {}

     public void insertUpdate(DocumentEvent documentEvent) {

         //get the owner of this document
         Object owner = documentEvent.getDocument().getProperty("owner");
         if(owner != null){
             //owner is the jtextfield
             System.out.println(owner);
         }
     }

     public void removeUpdate(DocumentEvent documentEvent) {}

     private void updateValue(DocumentEvent documentEvent) {}
};

field.getDocument().addDocumentListener(documentListener);
field2.getDocument().addDocumentListener(documentListener);

Alternatively:

Get the document that sourced the event and compare it to the document of the textfield.

Example:

public void insertUpdate(DocumentEvent documentEvent) {
    if (documentEvent.getDocument()== field.getDocument()){
        System.out.println("event caused by field");
    }
    else if (documentEvent.getDocument()== field2.getDocument()){
        System.out.println("event caused by field2");
    }
}
like image 169
dogbane Avatar answered Sep 21 '22 21:09

dogbane


Rather than add multiple fields to the same listener. Create a custom listener that upon creation takes a reference to the text field. Then create a new instance of the listener each time you add it to a field.

like image 41
jzd Avatar answered Sep 23 '22 21:09

jzd