2010-08-30 2 views
3

Мне было интересно, есть ли какая-то магия, которую я могу использовать, чтобы обойти исключение IllegalStateException и позволить JTextField «пытаться мутировать в уведомлении» или, другими словами, устанавливать свой собственный текст, если его слушатель запускается.В Java/Swing существует ли способ законно «пытаться мутировать в уведомлении»?

Для вашей информации я пытаюсь запрограммировать функцию автозаполнения, которая возвращает наиболее вероятное совпадение в диапазоне 12 перечислений в ответ на вход пользователя в JTextField.

Вот пример кода. Вам придется помиловать мой неуклюжий алгоритм, который скрипит результаты перечисления. Я выделил код, который производит исключение с комментарием:

jtfElement1.addCaretListener(new CaretListener() { 
      @Override 
      public void caretUpdate(CaretEvent e) {      
       String s = jtfElement1.getText(); 
       int[] attributes = new int[13]; 
       // iterate through each enum 
       for (BaseEnumAttributes b: BaseEnumAttributes.values()) { 
        // iterate through the length of the current text in jtfElement1 
        for (int i = 0; i < s.length(); i++) { 
         if (s.length() <= b.toString().length()) {         
          if (b.toString().charAt(i) == s.charAt(i)) { 
           // increase the number of "hits" noted for that enum 
           attributes[b.ordinal()] = attributes[b.ordinal()] + 1; 
          }         
         } 
        }       
       } 
       int priorC = 0; 
       int rightC = 0;      
       // iterate through the "array" of enums to find the highest score 
       for (int j = 0; j < attributes.length; j++) { 
        if (attributes[j] > priorC) { 
         priorC = attributes[j]; 
         rightC = j; 
        } 
       }      
       if (!s.equals("")) { 
        // assign to b the Enum corresponding to the "array" with highest score 
        BaseEnumAttributes b = BaseEnumAttributes.values()[rightC]; 
        iController.updateInputElement1String(b.toString());       
        // THIS TRIGGERS EXCEPTION 
        jtfElement1.setText(b.toString()); 
       } 

      } 
     }); 
+0

Если код Enum затрудняет чтение, можете ли вы его вынуть, поместите постоянную строку в setText() и все еще получите Exception? – PeterMmm

+0

@PeterMmm: Да, исключение все еще запускается даже с постоянной строкой и выведенным кодированием перечисления. – Arvanem

ответ

5

Возможно, вам лучше использовать фильтр документа или собственный документ.

Каковы другие слушатели, ожидающие увидеть, не останется ли документ во время отправки события?

0

Может быть, вы можете задержать SetText() с резьбой для запуска после caretUpdate() окончились.

+0

+1 и спасибо за интересный ответ. Я попробую другой поток - программа уже запущена в потоке Event-Dispatching? – Arvanem

+1

Хотя в тексте Swing есть некоторые претензии в отношении безопасности потоков, на самом деле это не работает. Если вы попробуете эту опцию, я предлагаю 'java.awt.EventQueue.invokeLater'. Будьте внимательны при обработке нескольких обновлений одновременно. –

+0

Как сказал Том, это может быть грязное решение (если когда-либо). Возможно, вы приняли неверного прослушивателя событий, чтобы делать то, что хотите.Чтобы реализовать такие функции самостоятельно, без глубоких знаний, качели могут быть очень неприятными ... – PeterMmm

5

Использование SwingUtilities.invokeLater() размещая все модификации там

0

я найдено на одной и той же проблемы, но я нашел простое решение:

блокировки caretUpdate() булевой, если (ложь) в то время как u'r устанавливает текст в jTextField, чем разблокировать его после. , что-то вроде этого:

boolean caret = true;

private void listValueChanged (javax.swing.event.ListSelectionEvent evt) { caret = false; name.setText ((String) list.getSelectedValue()); caret = true; }

private void nameCaretUpdate(javax.swing.event.CaretEvent evt) { 
    if(caret){ 
    model = new DefaultListModel(); 
    this.fillList(name.getText()); 
    list.setModel(model); 
    } 
} 
0

Создание пользовательского документа и переопределить insertString()

filenameText = new JTextField(new FilenameDocument(), "", 0); 

...

/** 
* document which adds .xml extension if not specified 
* 
*/ 
private class FilenameDocument extends PlainDocument { 

    @Override 
    public void insertString(int offset, String insertedText, AttributeSet set) 
    throws BadLocationException { 
     if (offset == 0) { 
     insertedText = insertedText.trim(); 
     } 
     super.insertString(offset, insertedText, set); 
     if (filenameText != null) { 
      final int caretPos = filenameText.getCaretPosition(); 
      String text = filenameText.getText().trim(); 
      if (text.indexOf('.') == -1) { 
       filenameText.setText(text + ".xml"); 
       filenameText.setCaretPosition(caretPos); 
      } 

     } 
    } 
} 

Обратите внимание, что вызов SetText приведет рекурсивного вызова insertString(), поэтому убедитесь, что у вас есть условие остановки.

0

Я удивлен, что никто не ответил на это, но не было бы лучше реализовать редактируемый JSpinner с SpinnerListModel?

 Смежные вопросы

  • Нет связанных вопросов^_^