6

Swing ベースのアプリケーションでコンボボックスを使用していますが、ユーザー イベントから生成された ItemEvent とアプリケーションによって発生した ItemEvent を区別するために何をすべきかを理解するのに苦労しています。

たとえば、コンボボックス ' combo' があり、ItemListener ' ' で itemStateChanged イベントをリッスンしているとしlistenerます。ユーザーが選択を項目 2 に変更するか、次の行を実行すると (疑似コード):

combo.setSelection(2)

.. これらのイベントを区別できないようです。

そうは言っても、私は決して Swing の専門家ではないので、質問しようと思いました。

ありがとう!

4

5 に答える 5

3

ユーザーがアイテム2を選択するか、APIがsetSelection(2)を呼び出すかにかかわらず、イベントは同じように表示されます。

問題の解決策は、選択が変更されたときにitemStateChangedコードに実行させたいことを再考することかもしれません。条件ごとにアプリの動作が異なるのはなぜですか?たぶん、あなたがあなたの利益のために使うことができる類似点があります。

フラグを使用するときは注意してください。itemStateChangedイベントは、フラグの状態を設定したスレッドとは異なるスレッドであるイベントディスパッチスレッドで発生します。これは、フラグの使用が100%信頼できるとは限らないことを意味します。

于 2008-10-06T21:33:56.903 に答える
2

作用と反作用の法則は非常に明確です:)。変更に対応しようとする場合、ユーザーとアプリケーションを区別する必要はありません。「区別」する必要があるユースケースは 1 つだけ想像できます。アプリケーションが何らかのデータを表示している場合。この場合、おそらくアプリケーションのデータ モデルがあります。また、このモデルにはいくつかの変更リスナーがあり、アプリケーション GUI はコンポーネントに値を設定することで反応します。そしてまた。ユーザーが GUI コンポーネントに何かを選択した場合。データ モデルは、値を変更することによって反応します。この場合、監視対象オブジェクトからのイベントを無視するようにモデルに通知する、データ モデルにある種の読み取り専用状態を設定するのは簡単です。この通知セットは EDT で実行する必要があり、フラグ付けに問題はありません。小さな例:

class ApplicationDataModel {

    private Flag current = Flag.RW;

    public void setData(ApplicationData data) {
        current = Flag.RO;
        setDataImpl(data);
        notifyObservers();
        current = Flag.RW;
    }

    public void reaction(Event e) {
        if (flag = Flag.RO) return;
        ...
    }

}

フラグ付けには注意し、スレッド化を忘れないでください。別のスレッドから setData を呼び出している場合は、EDT で問題が発生します。もちろん。オブジェクトの抽出はApplicationData別のスレッドで実行する必要があります;)。一般に、アプリケーションの設計を再考してください。

于 2008-10-07T08:40:29.540 に答える
1

選択を設定する前にコードでフラグを設定してから、リスナーでこのフラグを確認できます(フラグが設定されている場合は設定を解除します)...

Java 6以降、より良い方法があるかもしれませんが、これは私がいつも行っていた方法です...

[編集] : David が指摘するように、EDT で SwingUtilities.invokeLater などを使用してフラグを設定 (およびコンボを更新) する必要があります (UI コントロールを変更しているため、とにかくこれを行う必要があります)。

于 2008-10-06T21:11:11.380 に答える
0

したがって、単純な古い直接的な状態の変更ではなく、ユーザーの選択で何らかのアクションを実行する必要があると思います。これは、柔軟性が制限されているために発生する問題です (特に、他の方向に柔軟性がある場合、柔軟性は常に制限されます)。

私のおすすめ:

まず、常に Swing でモデルを使用するようにしてください。ウィジェットは複雑になりすぎており、さまざまな懸念事項を分割する必要があります。幸いなことに、Swing はすでにそのモデルを備えています。

一般的なパターンは、モデル間で委任を行うことです。したがって、この場合、データを保持する「実際の」デフォルト モデルがあります。JComboBox と実際の ComboBoxModel の間に挿入し、状態変更命令でアクションを実行する ComboBoxModel を委譲します。アプリケーション コードは JComboBox を無視し、委譲モデルをバイパスして実際の ComboBoxModel に直行する必要があります。したがって、図では次のようになります。

ユーザー -- JComboBox -- ActionComboBoxModel -- DefaultComboBoxModel -- アプリケーション コード
于 2008-10-07T13:58:41.113 に答える
0

イベントを区別する必要がある場合は、再考が必要な設計に関する何かがある可能性があります。MVC の要点は、モデルへの変更をユーザーの実際のマウス クリックから分離することです。

おそらく、なぜこれら 2 つの状況を区別したいのかという観点から、質問を言い換える必要があります。次に、目標を達成するための別の方法に関するガイダンスを提供できます。

于 2008-10-07T03:23:25.030 に答える