Ошибка с DocumentListener - PullRequest
       2

Ошибка с DocumentListener

2 голосов
/ 15 июня 2011

У меня есть JTextField, который я хочу ограничить пятнадцатью символами.Проблема в том, что когда я набираю более 15 символов, это ошибки.Как я могу это исправить?Нужно ли использовать какой-то другой объект?

Ошибка: исключение в потоке "AWT-EventQueue-0" java.lang.IllegalStateException: попытка изменить в уведомлении

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

Ответы [ 3 ]

8 голосов
/ 15 июня 2011

Используйте DocumentFilter, а не DocumentListener. К тому времени, когда слушатель запускает, Документ уже обновлен. Фильтр предотвратит обновление документа.

См. Реализация фильтра документов для рабочего примера, который делает то, что вы хотите.

3 голосов
/ 15 июня 2011

Попробуйте это:

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));
            }
        });
    }
}
1 голос
/ 15 июня 2011

Из учебника Java :

Возможно, вы захотите изменить текст документа в слушателе документа.Однако вы никогда не должны изменять содержимое текстового компонента из слушателя документа.Если вы это сделаете, программа, скорее всего, будет в тупике.Вместо этого вы можете использовать отформатированное текстовое поле или предоставить фильтр документа.

Существует блокировка синхронизации для базового Document, и эта блокировка принимается слушателем, когда внутри вашего метода lengthCheck,Вызов setText на JTextField также пытается захватить блокировку на Document, что невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...