我试图在JTextField
中键入阿拉伯数字,并且按如下方式使用DocumentListener
:
txtName.getDocument().addDocumentListener(this);
...
public void insertUpdate(DocumentEvent e){setLabel();}
public void removeUpdate(DocumentEvent e){setLabel();}
public void changedUpdate(DocumentEvent e){}
public void setLabel()
{
String s = txtName.getText();
s = s.replace('0','\u0660');
s = s.replace('1','\u0661');
s = s.replace('2','\u0662');
s = s.replace('3','\u0663');
s = s.replace('4','\u0664');
s = s.replace('5','\u0665');
s = s.replace('6','\u0666');
s = s.replace('7','\u0667');
s = s.replace('8','\u0668');
s = s.replace('9','\u0669');
s = s.replace('.',',');
txtName.setText(s);
}
但我在
txtName.setText(s);
处出错错误是:
Exception occurred during event dispatching:
java.lang.IllegalStateException: Attempt to mutate in notification
最佳答案
如果您阅读DocumentListener API,将会看到发生此错误的原因:
DocumentEvent通知基于JavaBeans事件模型。无法保证传递给侦听器的顺序,并且在对文档进行进一步更改之前必须通知所有侦听器。这意味着DocumentListener的实现可能不会使事件的来源(即关联的Document)发生突变。
考虑改用DocumentFilter。
例如。,
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;
@SuppressWarnings("serial")
public class DocListenerProblem extends JPanel {
private static final String REPLACE_CHARS = "0123456789.";
private JTextField txtName = new JTextField(20);
public DocListenerProblem() {
add(txtName);
PlainDocument doc = (PlainDocument) txtName.getDocument();
doc.setDocumentFilter(new MyDocumentFilter());
}
private class MyDocumentFilter extends DocumentFilter {
@Override
public void insertString(FilterBypass fb, int offset, String text,
AttributeSet attr) throws BadLocationException {
if (REPLACE_CHARS.contains(text)) {
text = doSwap(text);
}
super.insertString(fb, offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
if (REPLACE_CHARS.contains(text)) {
text = doSwap(text);
}
super.replace(fb, offset, length, text, attrs);
}
@Override
public void remove(FilterBypass fb, int offset, int length)
throws BadLocationException {
super.remove(fb, offset, length);
}
}
public String doSwap(String text) {
StringBuilder sb = new StringBuilder();
for (char c : text.toCharArray()) {
if (REPLACE_CHARS.contains(String.valueOf(c))) {
if (c == '.') {
c = ',';
} else {
c = (char) ('\u0660' - '0' + c);
}
}
sb.append(c);
}
return sb.toString();
}
private static void createAndShowUI() {
JFrame frame = new JFrame("DocListenerProblem");
frame.getContentPane().add(new DocListenerProblem());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
关于java - 在JTextField中键入阿拉伯数字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6470260/