4

IllegalStateExceptionを回避し、JTextFieldが「通知で変更を試みる」ことを許可する、つまり、リスナーがトリガーされた場合に独自のテキストを設定するために使用できる魔法があるかどうか疑問に思いました。

参考までに、JTextFieldでのユーザーの入力に応じて、12個の列挙型の範囲で最も可能性の高い一致を返すオートコンプリート関数をプログラムしようとしています。

これがコードサンプルです。列挙型の結果をきしむ私の不器用なアルゴリズムを許さなければなりません。コメントで例外を生成するコードを強調表示しました:

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

            }
        });
4

6 に答える 6

5

ドキュメント フィルタまたはカスタム ドキュメントを使用する方がよいでしょう。

イベントのディスパッチ中にドキュメントが同じままでない場合、他のリスナーは何を見ることが期待されますか?

于 2010-08-30T11:00:31.147 に答える
5

そこにすべての変更を配置する SwingUtilities.invokeLater() を使用します

于 2010-09-03T06:17:44.420 に答える
0

誰もこれに答えていないことに驚いていますが、編集可能なJSpinnerSpinnerListModelで実装したほうがよかったのではないでしょうか?

于 2012-01-19T13:35:34.717 に答える
0

caretUpdate() が終了した後に実行する Thread で setText() を遅らせることができるかもしれません。

于 2010-08-30T10:42:51.733 に答える
0

私は同じ問題を抱えていますが、簡単な解決策を見つけました:

テキストを jTextField に設定している間は、ブール値の if(false) で caretUpdate() をロックしてからロックを解除してください。. このようなもの:

ブールキャレット = true;

private void listValueChanged(javax.swing.event.ListSelectionEvent evt) { キャレット = false; name.setText((String)list.getSelectedValue()); キャレット = true; }

private void nameCaretUpdate(javax.swing.event.CaretEvent evt) {
   if(caret){
    model = new DefaultListModel();
    this.fillList(name.getText());
    list.setModel(model);
    }
}
于 2011-06-07T00:40:28.570 に答える
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( ) が再帰的に呼び出されるので、停止条件があることを確認してください。

于 2011-11-02T18:00:24.107 に答える