在 JTextField 中输入阿拉伯数字 [英] Typing Arabic numbers in JTextField

查看:50
本文介绍了在 JTextField 中输入阿拉伯数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 JTextField 中输入阿拉伯数字,我使用了 DocumentListener 如下:

I am trying to type Arabic numbers in a JTextField and I used DocumentListener as follows:

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,你会看到为什么会出现这个错误:

If you read the DocumentListener API, you'll see why this error occurred:

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

The DocumentEvent notification is based upon the JavaBeans event model. There is no guarantee about the order of delivery to listeners, and all listeners must be notified prior to making further mutations to the Document. This means implementations of the DocumentListener may not mutate the source of the event (i.e. the associated Document).

考虑改用 DocumentFilter.

Consider using a DocumentFilter instead.

例如

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

}

这篇关于在 JTextField 中输入阿拉伯数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆