Как найти исходный компонент, который сгенерировал DocumentEvent

Можно ли обнаружить, какой из объектов сгенерировал DocumentEvent? Что-то вроде я могу сделать с ActionListener:

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

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

}

Я хотел бы сделать то же самое с DocumentEvent, но, похоже, не работает одинаково:

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(); 
  }
}

Андерсер должен учитывать следующие моменты:

  • Для моих целей знание типа объекта, сгенерировавшего событие, недостаточно, но мне нужна ссылка на него во время выполнения.
  • Обычно события генерируются из расширения объекта swing (myComp public JTextField). Эти объекты хранят дополнительную информацию, которая должна быть извлечена во время выполнения внутри метода слушателя (например, insertUpdate)
  • DocumentListener реализуется из класса, который не знает полей, которые генерировали события. Дифференциальные поля разных типов могут быть привязаны к слушателю во время выполнения.

Ответы

Ответ 1

Вы можете установить свойство в документе, чтобы указать, к какому текстовому компоненту принадлежит документ:

Например:

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);

В качестве альтернативы:

Получить документ, связанный с событием, и сравнить его с документом текстового поля.

Пример:

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");
    }
}

Ответ 2

Вместо добавления нескольких полей к тому же слушателю. Создайте пользовательский прослушиватель, который при создании получает ссылку на текстовое поле. Затем создайте новый экземпляр слушателя каждый раз, когда вы добавите его в поле.