【问题标题】:how to find source component that generated a DocumentEvent如何找到生成 DocumentEvent 的源组件
【发布时间】:2011-07-10 06:38:56
【问题描述】:

是否可以发现哪个对象生成了 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(); 
  }
}

回答者应考虑以下几点:

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

【问题讨论】:

    标签: java swing properties document jtextfield


    【解决方案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");
        }
    }
    

    【讨论】:

    • 感谢您的回复。非常有用,但对我的设计来说还不够。我编辑了我的问题,试图更好地解释我的需求
    • 这个答案的第一个版本,它设置了一个“所有者”属性,似乎完全符合这个问题(很酷的提示顺便说一句,我不知道!)。您能否更具体地解释一下为什么这不能满足您的需求?
    • @Jesse Barnum:我认为你是对的。实际上,我误解了完美的第一个答案。事实上,如果我想直接引用 MyComponent 类型,我可以执行类似 field.putProperty("MyComponent", anInstanceOfMyComponent) 的操作,对吗? (我现在感觉有点傻 :( ,也许这些天太多的代码让我感到困惑)
    【解决方案2】:

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

    【讨论】:

    • 是的..也许是一个很好的解决方案,谢谢。但是我的听众很多,而且它们都是相当大的对象。拥有多个实例可能不是一个好主意。
    • 你可以将你的听众分成他们自己的类来调用大对象。
    【解决方案3】:

    与document属性的尝试等价于独立

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

    监听器的建议扩展可以是

    public void bind(JTextField tf)
    {
        final Document doc = tf.getDocument();
        textfields.put(doc, tf);
        doc.addDocumentListener(this);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-08
      • 2022-01-05
      • 1970-01-01
      • 2013-05-13
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多