在java中,如何区分textField.setText()和手动向textField添加文本?

在java中,如何区分textField.setText()和手动向textField添加文本?,java,swing,jtextfield,documentlistener,Java,Swing,Jtextfield,Documentlistener,我的应用程序中有一个textField,当用户单击JList中的某个项目时,它将以编程方式启动(textField.setText())。 稍后用户将手动更改此值。 我习惯于使用文档监听器来检测此文本字段中的更改。 当以编程方式进行更改时,它必须什么也不做,但如果手动进行,它应该将背景更改为红色 如何检测textField是手动填写还是由textField.setText()填写? txtMode.getDocument().addDocumentListener(new DocumentLis

我的应用程序中有一个textField,当用户单击JList中的某个项目时,它将以编程方式启动(textField.setText())。 稍后用户将手动更改此值。 我习惯于使用文档监听器来检测此文本字段中的更改。 当以编程方式进行更改时,它必须什么也不做,但如果手动进行,它应该将背景更改为红色

如何检测textField是手动填写还是由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
        }
    });
有两种方法

  • 删除
    DocumentListener
    之前的
    setText(“…”)
    添加
    DocumentListener
    返回(如果完成)
代码

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

//similair void for remove....
  • 使用
    boolean
    值禁用“如果需要”,但您必须更改
    DocumentListener的内容
比如说

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

请记住,所有事件侦听器都是在Swing事件线程上执行的。因此,事情可能不会按照您希望的顺序进行。在这种情况下,任何解决方案都是黑客式的,因为您无法完全控制swing线程以及谁在其上发布事件

我想说的是:假设您选择使用一些标志,让您的侦听器知道这是一个编程更改。下面是可能的场景(我假设您遵循了通过
invokeLater
从swing线程进行任何UI更新的好规则):

  • 将标志设置为跳过事件
  • 塞特克斯
  • 将标志设置为false
  • 如果您在一次调用中完成所有操作,setText将触发发布到事件队列末尾的更新事件,因此,在执行这些事件时,该标志将已为false


    因此,您应该在一个
    invokeLater
    调用中执行步骤1和2,或者甚至执行
    invokeAndWait
    ,然后使用
    invokeLater
    发布另一个事件以取消设置标志。祈祷您的用户不要在这两个调用之间太快而做出一些更改,否则,它们也会被视为编程更改。

    这里的问题是,有时setText()被非您自己的代码调用。不管怎么说,这就是我目前正在努力解决的问题。我希望他们能在每个事件上都有一个wasTriggeredByser()。@Trejkaz请询问如何,在哪里,为什么,有什么特殊原因,顺便说一句,文档是JTextComponents的模型,然后使用/触发模型之间的所有更改/事件进行查看,反之亦然