java操作textField数据时覆盖textField上的getText方法

时间:2015-09-27 01:12:58

标签: java swing runtime-error jtextfield

我创建了一个覆盖JTextField的外部类。在类中,我添加了一个DocumentListener,它取代了阻止输入某个字符。下面是代码(它不是确切的代码,为了简化这个问题):

import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

class test extends JTextField{
private String filteredText;

public void getDefaultText(){
super.getText();
}

public String getText(){
return filteredText;
}

public void remword(){
super.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void changedUpdate(DocumentEvent arg0) {
            }

            @Override
            public void insertUpdate(DocumentEvent arg0) {
                Runnable ru = new Runnable() {
                    @Override
                    public void run() {
                                String finalText = getDefaultText().replace("xyz", "asd");
                                setText(finalText);
                                filteredText = finalText;
                        }
                    }
                };
                SwingUtilities.invokeLater(ru);         
}

            @Override
            public void removeUpdate(DocumentEvent arg0) {
            }
});
}
}

现在这段代码工作正常,除非我使用返回错误getText()的{​​{1}}方法。我曾尝试弄乱Attempt to mutate in notificatonsynchronized但无济于事。

1 个答案:

答案 0 :(得分:3)

来自DocumentListener

  

DocumentEvent通知基于JavaBeans事件模型。无法保证向听众传递的顺序,并且必须在对文档进行进一步突变之前通知所有听众。 这意味着DocumentListener的实现可能不会改变事件的来源(即关联的文档)。

您应该使用DocumentFilter来控制文档操作。

顺便说一句,使用getText()不应该抛出此异常。你可能意味着setText(String)

对于此用例,您不需要为JTextField创建子类:

((AbstractDocument) textField.getDocument()).setDocumentFilter(new DocumentFilter() {
    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
        super.insertString(fb, offset, sanitize(string), attr);
    }

    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        super.replace(fb, offset, length, sanitize(text), attrs);
    }

    private String sanitize(String s) {
        return s == null ? null : s.replace("xyz", "asd");
    }
});

请注意我的解决方案仍然允许" xyz"在文件中如果逐字逐句输入或删除例如" _"来自" xy_z"。