Лучший подход для действия с двойным состоянием

StackOverflow https://stackoverflow.com/questions/1667324

Вопрос

Недавно я реализовал Action который переключает включенный статус бизнес-функции.Всякий раз, когда пользователь вызывает действие, я устанавливаю логический флаг:"будетВключить", чтобы определить, включит или отключит функцию следующий вызов.Аналогичным образом я обновляю имя действия, краткое описание и значок, чтобы отразить новое состояние.Тогда в моем actionPerformed(...) метод, я предпринимаю разные действия в зависимости от состояния willEnable.

  1. Является ли это правильным подходом или кто -нибудь может порекомендовать лучший (как я подозреваю, это общая проблема)?(Я вижу JToggleButton действует как кнопка с двумя государствами, но я хочу, чтобы это действие было видно наJMenuBar также как и JButton, поэтому не думайте, что это уместно).

РЕДАКТИРОВАТЬ

В частности, как с этим справляются такие приложения, как IDEA?Будут ли они использовать действия с несколькими состояниями (как указано выше) или поменяют местами другой Action в заданный JButton с использованием setAction(Action)?Возможно, этот подход лучше?

  1. При обновлении свойств действия я могу полагаться на компоненты графического интерфейса, инициализированные с этим Action (например.JButton) автоматически перекрасить себя?Что, если JButtonв результате размер изменится?Должен ли я переоценивать содержаниеJPanel сам?
  2. Изменение имени действия - плохое занятие?Это единственный способ, которым я могу внести изменение текста Jbutton, но я осознаю, что имя, вероятно, должно оставаться постоянным, если действие помещается в ActionMap.

Заранее спасибо.

Это было полезно?

Решение

Я ожидаю, что любой компонент графического интерфейса, созданный с использованием некоторой «модели» данных (я бы включил Action как модель данных) должен зарегистрироваться в качестве прослушивателя этой модели.Это должен принять соответствующие, хм, меры по PropertyChangeEvent быть уволенным:По моему мнению, любое другое поведение будет представлять собой ошибку.

Сомнительно здесь то, правомерно ли менять название акции;я думаю что это не законно.Ваше действие логически ToggleEnabledStatus и это не меняется, поскольку действие было вызвано.Любой компонент, которому необходимо отображать любой другой текст, должен зарегистрироваться в качестве прослушивателя Action а затем проверь свой willEnable флаг, чтобы предпринять соответствующие, эээ, действия.

В качестве альтернативы вы можете написать свой собственный класс, реализующий ToggleButtonModel и Action в то же время и контролировал события изменений изнутри.Однако это очень много кода, а пользы мало.

Другие советы

Возможно, вы захотите посмотреть Образец состояния.

По сути, вы создаете интерфейс и две (или более) его реализации для каждого состояния.В качестве простого примера: состояние отключения может просто реализовать интерфейс, чтобы ничего не делать, в то время как состояние включения выполняет некоторые действия.Чтобы переключить состояние, вы просто сделаете

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

Хотя это немного накладно для одного метода, оно, безусловно, окупится, как только у вас появится несколько методов, которые изменяют его поведение в зависимости от одного состояния.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top