Java 如何查找生成DocumentEvent的源组件

Java 如何查找生成DocumentEvent的源组件,java,swing,properties,document,jtextfield,Java,Swing,Properties,Document,Jtextfield,是否可以发现哪个项目生成了DocumentEvent?类似于我可以用ActionListener做的事情: JTextField field = new JTextField(""); field.addActionListener(actionListener); //inside ActionListener public void actionPerformed(ActionEvent arg0) { if (arg0.getSource() instanceof JTextFiel

是否可以发现哪个项目生成了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(); 
  }
}
answser应考虑以下几点:

  • 出于我的目的,仅仅知道生成事件的对象类型是不够的,但我需要在运行时对其进行引用
  • 通常,事件是从swing对象的扩展(myComp public JTextField)生成的。这些对象存储在侦听器方法(es.insertUpdate)中运行时应检索的附加信息
  • DocumentListener是从一个不知道生成事件的字段的类实现的。可以在运行时将不同类型的不同字段附加到侦听器

  • 您可以在文档中设置属性,以告知文档属于哪个textcomponent:

    例如:

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

    而不是向同一侦听器添加多个字段。创建一个自定义侦听器,该侦听器在创建时引用文本字段。然后,每次将侦听器添加到字段时,都创建一个新的侦听器实例。

    尝试使用document属性相当于一个独立的侦听器实例

    Map<javax.swing.text.Document, javax.swing.JTextField> textFields;
    

    谢谢你的回复。非常有用,但对我的设计来说还不够。我编辑了我的问题,试图更好地解释哪些是我需要的。这个答案的第一个版本,设置了一个“所有者”属性,似乎非常适合这个问题(顺便说一句,很酷,我不知道!)。你能更具体地解释一下为什么这不能满足你的需要吗?@Jesse Barnum:我想你是对的。事实上,我误解了罗布麻的第一个答案,那是完美的。事实上,如果我想直接引用类型MyComponent,我可以做一些类似field.putProperty(“MyComponent”,一个InstanceOfMyComponent)的事情,对吗?(我现在觉得有点傻:(,也许这些天太多的代码让我困惑)是的..也许是一个很好的解决方案谢谢。但是我的侦听器很多,它们都是非常大的对象..拥有多个实例可能不是一个好主意。你可以将侦听器分成自己的类,调用大对象。
    public void bind(JTextField tf)
    {
        final Document doc = tf.getDocument();
        textfields.put(doc, tf);
        doc.addDocumentListener(this);
    }