Как разместить методы @Action в отдельном классе от компонента Swing? - PullRequest
2 голосов
/ 01 февраля 2010

При разработке приложений Swing я обычно определял интерфейс делегата для каждого компонента пользовательского интерфейса для обратных вызовов действий. Например, если есть класс MyDialog, который содержит кнопку MyButton, то ActionListener для MyButton вызовет MyDialog.Delegate.OnMyButtonClick(Event e). Затем компонент пользовательского интерфейса становится «тупым» и требует от контроллера обработки событий, а также обновления самого компонента.

Я подумал, что, используя @Actions Swing Application Framework, я смог обойти создание делегатских интерфейсов и реализаций, определив методы @Action в классах реализации, позволяя ApplicationContext определить, что вызывать. По-видимому, это не так, поскольку я не вижу четкого способа добавления этих классов в ApplicationContext, и я не вижу каких-либо примеров таких действий.

Кому-нибудь удалось использовать SAF таким образом, чтобы между пользовательским интерфейсом и кодом действия пользовательского интерфейса было четкое разделение?

Ответы [ 2 ]

2 голосов
/ 29 марта 2010

Я нашел хороший способ отделить пользовательский интерфейс от поведения с помощью @ Actions.

Сначала создайте компонент пользовательского интерфейса, скажем JPanel с кнопкой, а затем назначьте ему открытый метод, который можно использовать для установки действия кнопки:

class CustomJPanel extends JPanel {
   private JButton myButton;
   public CustomJPanel() {
      initializeComponents();
   }
   public void initializeComponents() {
      myButton = new JButton();
   }
   public void setButtonAction(javax.swing.Action action)
   {
      myButton.setAction(action);
   }
}

Затем создайте класс Action, который предоставит логику для этой кнопки:

class CustomJPanelActions {
   @Action
   public void doSomething()
   {
       JOptionPane.showMessageDialog(null,"You pressed me!");
   }
}

Наконец, настройте контроллер приложения и во время настройки назначьте соответствующее действие соответствующему пользовательскому интерфейсу:

class MyApp extends SingleFrameApplication {
   private JFrame mainFrame;
   private JLabel label;

   @Override
   protected void startup() {
      getMainFrame().setTitle("BasicSingleFrameApp");
      CustomJPanel panel = new CustomJPanel();
      panel.setButtonAction(getContext().getActionMap(new CustomJPanelActions()).get("doSomething");
      show(panel);
   }

   public static void main(String[] args) {
      Application.launch(BasicFrameworkApp.class, args);
   }
}

Таким образом, пользовательский интерфейс логически отделен от элемента управления (т. Е. Действия) и может быть протестирован сам по себе. Контроллер может принимать любые необходимые ему решения, чтобы определить, какое действие установить и какое конкретное действие назначить элементам управления пользовательского интерфейса. То есть можно создать набор тестовых действий и набор активных действий и т. Д.

Этот метод использования SAF работал довольно хорошо для меня.

1 голос
/ 01 февраля 2010

В Javadoc SAF есть некоторая информация о том, как это сделать, в документе для ActionManager # getActionMap

...