管理摇摆动作与注册表(Managing Swing Actions with a Registry)

2019-08-02 09:32发布

通常,当我创建一个Swing(或任何UI)的应用程序,我已经出现在菜单项和按钮的各种操作。 我通常创建操作注册表和行动时发生某些事情存储在那里,然后,我禁用/启用基于应用程序的状态,在注册表中的行动。 我不会称自己是狂热的Swing开发人员,虽然我知道我身边的不够好办法,但这是管理操作一个非常典型的模式? 或者有没有做的更标准的方式吗?

谢谢,

杰夫

Answer 1:

杰夫,你的做法似乎是一个不错的办法。 我做同样的事情。 我所说的注册表的ActionHandler,它看起来是这样的:

import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.ImmutableClassToInstanceMap;

import javax.swing.*;
import javax.swing.text.DefaultEditorKit;

public class ActionHandler {

    private static final ClassToInstanceMap<Action> actionMap =
            new ImmutableClassToInstanceMap.Builder<Action>().
                    put(DefaultEditorKit.CutAction.class, new DefaultEditorKit.CutAction()).
                    put(DefaultEditorKit.CopyAction.class, new DefaultEditorKit.CopyAction()).
                    put(DefaultEditorKit.PasteAction.class, new DefaultEditorKit.PasteAction()).
                    put(RefreshAction.class, new RefreshAction()).
                    put(MinimizeAction.class, new MinimizeAction()).
                    put(ZoomAction.class, new ZoomAction()).
                    build();

    public static Action getActionFor(Class<? extends Action> actionClasss) {
        return actionMap.getInstance(actionClasss);
    }
}

现在禁用,说ZoomAction,我使用

   ActionHandler.getActionFor(ZoomAction.class).setEnabled(false);


Answer 2:

从我的经验,处理的Swing GUI执行的操作“ ”的标准方法是创建ActionListener S和让他们处理ActionEvent直接S表示与它们注册的组件。 这是一个简单的设计,它需要遵循与其他种类在Swing框架(GUI事件的约定MouseListener / MouseEventTableModelListener / TableModelEvent等)。

Action你描述框架是一个强大的工具,允许多种输入法之间的行为(即,具有工具栏按钮和菜单项执行相同的操作,因此共享相同的共享Object用于处理事件双方触发等)。 这种抽象是很酷,但是Sun警告说,这是一个有点重加权比简单的观察员。 从Action的JavaDoc:

注意动作的实现往往在存储比典型的ActionListener,它不提供的功能和属性更改广播的集中控制的好处而言更加昂贵。 出于这个原因,你应该注意只使用其中需要这些优点的操作,和其他地方使用简单的ActionListeners。



Answer 3:

我通常采取以下方法:

  • 注册Action与含Component的行动地图。
  • 定义一个公共String常量,允许应用程序引导代码为“拉出来”的ActionComponent的要求(例如,将其添加到JToolBarJMenuBar ,等等)。
  • 定义的私人updateActionStates()的内方法Component ,其被称为当用户执行某些操作(例如,从选择N行JTable )。 这种方法启用/禁用基础上,当前状态的所有定制的动作Component

例:

public class MyPanel extends JPanel {
  public static final String MY_ACTION_NAME = "MyAction";

  private final JTable myTable;       

  public MyPanel() {
    // Create action and define behaviour.
    this.myAction = new AbstractAction(MY_ACTION_NAME, ...);

    // Register with component's action map.
    getActionMap().put(myAction.getValue(Action.NAME), myAction);

    // Optionally register keyboard shortcuts using component's input map.
    getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(...);

    // Create JTable and add a call to updateActionStates when the selection changes.
    myTable = new JTable(...);
    myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
      public void valueChanged(ListSelectionEvent evt) {
        updateActionStates();
      }
    });
  }

  private void updateActionStates() {
    // Action will only be enabled if one table row is selected.
    getActionMap.get(MY_ACTION_NAME).setEnabled(myTable.getSelectedRowCount == 1);
  }
}

// Application start-up code:

MyPanel pnl = new MyPanel();
JToolBar toolBar = new JToolBar();
// Pull out action from action map and add to toolbar.
toolBar.add(pnl.getActionMap().get(MyPanel.MY_ACTION_NAME));

顺便说一句,我通常比较喜欢Action s到ActionListener S代表露出Action形成我的接合部S Component的API。 对于那些仅仅存在于内操作Component (如对话框的“清除”按钮),我通常使用ActionListener 。 但是,我不同意关于AKF ActionListener是最标准的做法-这可能是更小的GUI真实的,但不是更复杂的Swing应用程序。



Answer 4:

我使用的行动注解,然后若有所思地找到它们。

有点整洁,并采取新的行动得到自动管理。



文章来源: Managing Swing Actions with a Registry