デュアルステートアクションの最適なアプローチ
-
13-09-2019 - |
質問
最近実装したのは、 Action
ビジネス機能の有効ステータスを切り替えます。ユーザーがアクションを呼び出すたびに、ブール値のフラグを設定します。」有効にする" を使用して、次の呼び出しで関数を有効にするか無効にするかを決定します。同様に、アクション名、簡単な説明、アイコンを更新して、新しい状態を反映します。それから私の中で actionPerformed(...)
メソッドの状態に基づいて異なるアクションを実行します willEnable
.
- これは正しいアプローチですか、それとも
誰もがより良いものをお勧めします(私のように
これは一般的な問題であると思われます) ?(わかります
JToggleButton
2つの状態のボタンとして機能 しますが、 このアクションはJMenuBar
同様にJButton
、 これは適切ではないと思わないで ください)。
編集
具体的には、IDEA のようなアプリケーションはこれにどのように対処しますか?(上記のような) マルチステート アクションを使用するのでしょうか、それとも 違う Action
与えられたものに JButton
を使用して setAction(Action)
?おそらくこのアプローチの方が良いでしょうか?
- アクションのプロパティを更新するとき、私はそれで初期化されたGUIコンポーネントに頼ることができます
Action
(例えば。JButton
)自動的に自分自身を塗り直します か?もしJButton
結果としてサイズが変わりますか?含有するを再検証する必要 がありますJPanel
自分自身? - アクションの名前を変更するのは悪いことですか?これは私がJButtonのテキストを変更することができる唯一の方法ですが、アクションがに配置されている場合、その名前はおそらく一定のままであることを認識しています
ActionMap
.
前もって感謝します。
解決
何らかのデータ「モデル」を使用して作成された GUI コンポーネントはすべて「モデル」であると予想します ( Action
データ モデルとして) 自身をそのモデルのリスナーとして登録する必要があります。それ しなければならない 適切な、えー、アクションを取る PropertyChangeEvent
解雇される:私の意見では、それ以外の動作はバグとなります。
ここで問題となるのは、アクションの名前を変更することが正当であるかどうかです。私はそう思います それは合法ではありません. 。あなたの行動は論理的には トグル有効ステータス そしてアクションが呼び出されたからといってそれは変わりません。他のテキストを表示する必要があるコンポーネントは、それ自体をリスナーとして登録する必要があります。 Action
そしてあなたのことを確認してください willEnable
適切なアクションを実行するためのフラグ。
あるいは、実装した独自のクラスを作成することもできます。 ToggleButtonModel
そして Action
同時に、その内部から変更イベントを制御します。ただし、これは大量のコードですが、利点はほとんどありません
他のヒント
見てみるのもいいかもしれません 状態パターン.
基本的に、状態ごとに 1 つのインターフェイスとその 2 つ (またはそれ以上) の実装を作成します。簡単な例として、無効状態は何もしないインターフェースを実装するだけで、有効状態はいくつかのアクションを実行します。状態を切り替えるには、次のようにします
interface IState {
void doAction();
boolean isEnabled();
}
class EnabledState implement IState {
void doAction() {
setState(new DisabledState());
// do something
}
boolean isEnabled() {return true;}
}
class DisabledState implement IState {
void doAction() {
setState(new EnabledState());
// do nothing
}
boolean isEnabled() {return false;}
}
private IState state = new DisabledState(); // default is disabled
private PropertyChangeSupport support = new PropertyChangeSupport(this);
void setState(IState state) {
if (this.state != state) {
IState oldState = this.state;
this.state = state;
support.firePropertyChange("enabled", oldState.isEnabled(), state.isEnabled());
}
}
void doAction() {
state.doAction();
}
単一のメソッドの場合は少しオーバーヘッドがかかりますが、単一の状態に応じて動作を変更するメソッドが複数ある場合には、確実に効果があります。