在JTextField中键入阿拉伯数字

我试图在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);收到错误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(); } }); } }