开发者

Error with DocumentListener

I have a JTextField that I want to be limited to fifteen characters. The problem is that when I type over 15 characters, it errors. How can i fix this? Do I have to use some other object?

The error: Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification

 final int maxNicknameLength = 15;
 final JTextField nickname = new JTextField(1); //Max length: 15
 DocumentListener docListen = new DocumentListener() {
      public void changedUpdate(DocumentEvent e) {
           lengthCheck(e, nickname, maxNicknameLength);
      }

      public void insertUpdate(DocumentEvent e) {
           lengthCheck(e, nickname, maxNicknameLength);
      }

      public void removeUpdate(DocumentEvent e) {
           lengthCheck(e, nickname, maxNicknameLength);
      }
      public void lengthCheck (DocumentEvent e, JTextField txt, int max) {
           if (txt.getText().length() > max)
                txt.setText(txt.getText().substring(0, max));
开发者_运维技巧      }    
 };
 nickname.getDocument().addDocumentListener(docListen);


Use a DocumentFilter, not a DocumentListener. By the time the listener fires the Document has already been updated. A filter will prevent the document from being updated.

See: Implementing a Document Filter for a working example that does what your want.


Try this:

public void lengthCheck(final DocumentEvent e, final JTextField txt, 
        final int max) {
    if (txt.getText().length() > max) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                txt.setText(txt.getText().substring(0, max));
            }
        });
    }
}


From the Java tutorial:

You may want to change the document's text within a document listener. However, you should never modify the contents of a text component from within a document listener. If you do, the program will likely deadlock. Instead, you can use a formatted text field or provide a document filter.

There is a synchronization lock on the underlying Document and this lock is taken by the listener when inside your lengthCheck method. Calling setText on the JTextField also tries to grab the lock on the Document, which is not possible.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜