【问题标题】:DocumentListener method being called repeatedlyDocumentListener 方法被重复调用
【发布时间】:2017-11-28 09:34:39
【问题描述】:

我制作了一个文档监听器,它会在插入文本时调用一个方法。它可以工作,但问题是它就像在循环中一样,并且一直被调用。
该方法使用方法内部的 swingutilties.invokelater。

   private void addNewLine() {
       SwingUtilities.invokeLater( () -> {
        textArea.append(System.getProperty("line.separator")+"hey");
       });
   }


    private final DocumentListener addNewLine = Handlers.forDocumentUpdate((event) -> {
         addNewLine();
    });

    @SuppressWarnings("serial")
    static DocumentListener forDocumentUpdate(Consumer<? super DocumentEvent> eventHandler) {
    return new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent event) {
            eventHandler.accept(event);
        }
        @Override
        public void removeUpdate(DocumentEvent event) {
        }
        @Override
        public void changedUpdate(DocumentEvent event) {
        }
      };
    }

【问题讨论】:

  • 不要从DocumentListener 中更新Document,这可能会导致突变异常,或者您似乎已经发现,其他异常行为。相反,请考虑使用DocumentFilter
  • 与其试图找到解决问题的“解决办法”,不如先用最适合该工作的工具来解决它,看看TransferHandler
  • 好吧,通过 TransferHandler 来做会很浪费,因为当我真的想运行一行代码时,我必须重写很多代码。我试图通过 TransferHandler 来做几个小时。我对 documentfilter 不是很熟悉,但我会看看它。我认为如果它可能忽略过滤器所做的任何更改会更好。

标签: java swing loops invokelater swingutilities


【解决方案1】:

在我使用 DocumentListener 完成任务之前,但是递归循环出现了问题。正确的方法是添加一个 DocumentFilter,它会简单地添加一个换行符以及插入要插入的原始文本的代码。

((AbstractDocument) textArea.getDocument()).
            setDocumentFilter(new NewLineFilter()); 

public class NewLineFilter extends DocumentFilter {
@Override
public void insertString(FilterBypass fb,int offs,String str,AttributeSet a)
        throws BadLocationException {
}
@Override 
public void replace(FilterBypass fb, int offs,int length, String str, AttributeSet a)
        throws BadLocationException {
    System.out.println("in replace");
    super.replace(fb,offs,length,str,a);
    super.insertString(fb, fb.getDocument().getLength(), System.lineSeparator(), a);
}}

如果您知道编写此代码的更好方法,或者如果您知道一种方法可以创建一个可以为此创建匿名类的处理程序,那就太好了。我不能使用 Consumer,因为 replace() 有多个参数。我可以制作另一个功能界面,但我不知道它会有多大用处。如果我需要再次做同样的事情,我认为可能会重用这个类。

【讨论】:

    猜你喜欢
    • 2015-10-28
    • 2014-03-12
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    相关资源
    最近更新 更多