10

JComboBox を使用してテーブル セルの文字列値を変更する次のコードに問題があります。JComboBox は正常に動作しますが、ボックスをクリックしてから何も選択せずにクリックすると、行を削除しても JComboBox のドロップダウンが表示されたままになります。JButton などの別の Swing コンポーネントをクリックすると、そのコンポーネントが消えてしまうことがよくありますが、常にではありません。


    TableColumn col = myTable.getColumnModel().getColumn(0);
    JComboBox eq = new JComboBox();
    eq.addItem("==");
    eq.addItem("!=");
    DefaultCellEditor editor = new DefaultCellEditor(eq);
    col.setCellEditor(editor);

編集:以前に設定したことを忘れていました:


    myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

この行をコメントアウトするか false に設定すると、他の Swing コンポーネントをクリックしてもボックスが消えることはありません。それを入れて、フォーカスのあるものをクリックすると、ボックスが消え、問題が軽減されますが、動作の原因が隠される可能性があります.

ここで何か間違ったことをしていますか、それとも手順を忘れていますか? または、強制的に閉じる方法はありますか?

ありがとう!

4

2 に答える 2

14

これを理解するには、編集可能なテーブルで何が行われるかを理解する必要があります。短い理論:

すべてのセルには潜在的なレンダラーとエディターがあります。レンダラーはセルに描画方法を伝えるだけで、イベントとは対話しません。ただし、エディターはイベントと対話できるコンポーネントです。編集をトリガーするイベントが発生すると、エディター コンポーネントがテーブルの上に追加されます。編集が完了すると、コンポーネントが削除されます。

コンポーネントを非表示にするには、セルがまだ「編集中」状態になっていないことを確認する必要があります。これが、terminateEditOnFocusLast が JComboBox を消滅させる理由です。他のことでボックスを動かしたい場合は、特定のイベント、場合によってはフォーカス、またはセル選択に応答して removeEditor() を呼び出す必要があります。

何が起こるかを実際に把握するには、removeEditor()、editCellAt() などのソース コードをざっと見て、デバッガーで 1 回実行することをお勧めします。イベント処理コードの一部をオーバーライドしたか、そうすべきではないときにそれを呼び出している可能性があります。JTable のエディター/イベント処理コードは非常に脆弱であり、誤った順序で呼び出しが発生して、面白い副作用が発生するのは非常に簡単です。

また、Java はバージョン間で JTable のイベントとフォーカスの動作を非常に微妙に変更したことがあります。swing のフォーカス処理が変更されたのは 1.4 から 1.5 の間だったと思います。したがって、最初に試すことをお勧めするのは、別の Java バージョンを使用したコードです。バグは Sun によって引き起こされた可能性があり (複雑なエディター コードの一部を変更する必要がありました)、リリース間で異なる場合は、Sun に報告する方が簡単です。

于 2009-02-18T23:09:08.810 に答える
3

この質問は古いことは知っていますが、参考までにここに私の解決策があります。DefaultCellEditor を拡張し、JComboBox がキャンセルされるのをリッスンしてから、エディターを強制的にキャンセルします。

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class ComboBoxCellEditor extends DefaultCellEditor {

    public ComboBoxCellEditor(JComboBox comboBox) {
        super(comboBox);
        comboBox.addPopupMenuListener(new PopupMenuListener() {

            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            public void popupMenuCanceled(PopupMenuEvent e) {
                cancelCellEditing();
            }
        });
    }
}

それで ...

DefaultCellEditor editor = new ComboBoxCellEditor(combobox);
column.setCellEditor(editor);
于 2016-02-05T18:36:21.247 に答える