В Java / Swing есть ли способ юридически «попытаться изменить в уведомлении»? - PullRequest
3 голосов
/ 30 августа 2010

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

К вашему сведению, я пытаюсь запрограммировать функцию автозаполнения, которая возвращает наиболее вероятное совпадение в диапазоне 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());
                }

            }
        });

Ответы [ 6 ]

5 голосов
/ 03 сентября 2010

Используйте SwingUtilities.invokeLater (), поместив туда все модификации

5 голосов
/ 30 августа 2010

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

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

0 голосов
/ 19 января 2012

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

0 голосов
/ 02 ноября 2011

Создание пользовательского документа и переопределение 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 голосов
/ 07 июня 2011

Я обнаружил ту же проблему, но нашел простое решение:

заблокируйте caretUpdate () с помощью логического значения if (false), когда вы устанавливаете текст в jTextField, а не разблокируете его после. , как то так:

логическая каретка = true;

private void listValueChanged (javax.swing.event.ListSelectionEvent evt) { каретка = ложь; 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 голосов
/ 30 августа 2010

Возможно, вы можете отложить setText () с помощью Thread для запуска после завершения caretUpdate ().

...