3

我最近实现了一个Action切换业务功能启用状态的功能。每当用户调用该操作时,我都会设置一个布尔标志:“ willEnable ”来确定下一次调用是启用还是禁用该功能。同样,我更新动作名称、简短描述和图标以反映新状态。然后在我的actionPerformed(...)方法中,我根据willEnable.

  1. 这是正确的方法还是任何人都可以推荐更好的方法(因为我怀疑这是一个常见问题)?(我可以看到它JToggleButton充当两个状态按钮,但我希​​望此 Action 在 a JMenuBar和 a上可见JButton,所以不认为这是合适的)。

编辑

具体来说,像 IDEA 这样的应用程序是如何处理这个问题的?他们会使用多状态动作(如上)还是将不同Action的动作换成给定的JButtonusing setAction(Action)?也许这种方法更好?

  1. 当更新一个动作的属性时,我可以依赖于初始化的 GUI 组件Action(例如 JButton)自动重绘自己吗?如果JButton 尺寸因此发生变化怎么办?我应该重新验证包含 JPanel自己吗?
  2. 更改动作的名称是一件坏事吗?这是我可以更改 JButton 文本的唯一方法,但我意识到如果将操作放置在ActionMap.

提前致谢。

4

2 回答 2

3

您可能想查看State Pattern

基本上,您为每个状态创建一个接口和两个(或更多)实现。举个简单的例子,禁用状态可能只是实现接口什么都不做,而启用状态执行一些操作。要切换状态,您只需执行

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

虽然单个方法的开销有点小,但只要您有几种方法可以根据单个状态改变其行为,它肯定会有所回报。

于 2009-11-03T13:27:47.483 回答
2

我希望任何使用某些数据“模型”(我将包括一个Action作为数据模型)创建的 GUI 组件都应该将自己注册为该模型的侦听器。它必须对被解雇采取适当的,呃,行动PropertyChangeEvent:在我看来,任何其他行为都会构成错误。

这里值得怀疑的是,更改动作名称是否合法;我认为这是不合法的。您的操作在逻辑上是ToggleEnabledStatus并且不会因为操作已被调用而改变。任何需要显示任何其他文本的组件都应将自己注册为监听器Action,然后检查您的willEnable标志以采取适当的,呃,行动。

或者,您可以编写自己的类,该类同时实现ToggleButtonModelAction控制其中的更改事件。但是,这是很多代码,但收益却很小

于 2009-11-03T13:36:22.943 回答