Java 使用注册表管理Swing操作
通常,在创建Swing(或任何UI)应用程序时,我会在菜单项和按钮上显示各种操作。我通常创建一个操作注册表并将操作存储在其中,然后当某些事情发生时,我会根据应用程序的状态在注册表中禁用/启用操作。 我不认为自己是一个狂热的Swing开发人员,尽管我对Swing的方法非常熟悉,但这是一种非常典型的操作管理模式吗?还是有更标准的方法 谢谢 Jeff根据我的经验,处理Swing GUI上执行的操作的“最”标准方法是创建Java 使用注册表管理Swing操作,java,swing,user-interface,action,Java,Swing,User Interface,Action,通常,在创建Swing(或任何UI)应用程序时,我会在菜单项和按钮上显示各种操作。我通常创建一个操作注册表并将操作存储在其中,然后当某些事情发生时,我会根据应用程序的状态在注册表中禁用/启用操作。 我不认为自己是一个狂热的Swing开发人员,尽管我对Swing的方法非常熟悉,但这是一种非常典型的操作管理模式吗?还是有更标准的方法 谢谢 Jeff根据我的经验,处理Swing GUI上执行的操作的“最”标准方法是创建ActionListeners,并让它们直接为注册的组件处理ActionEvents
ActionListener
s,并让它们直接为注册的组件处理ActionEvent
s。这是一个简单的设计,它遵循Swing框架中其他种类GUI事件的约定(MouseListener
/MouseEvent
,TableModelListener
/TableModelEvent
等)
您描述的操作
框架是一个强大的工具,允许在许多输入方法之间共享操作(即,使用工具栏按钮和菜单项执行相同的操作,因此共享相同的对象
,以处理两者触发的事件,等等)。这个抽象非常酷,但Sun警告说,它比简单的观察者要重一些。从
请注意,就存储而言,Action实现往往比典型的ActionListener更昂贵,因为ActionListener无法提供集中控制功能和广播属性更改的好处。出于这个原因,您应该注意只在需要的地方使用操作,并在其他地方使用简单的ActionListener
我通常采取以下方法:
- 将
注册到包含操作
组件的操作映射中
- 定义一个公共
常量,允许应用程序引导代码从所需的字符串
中“拉出”组件
(例如,将其添加到操作
,JToolBar
等)JMenuBar
- 在
中定义私有的组件
方法,当用户执行某些操作(例如从updateActionState()
中选择N行)时调用该方法。此方法根据JTable
组件的当前状态启用/禁用所有定制操作
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来公开构成组件
API一部分的Action
s。对于仅存在于组件中的操作(例如对话框的“清除”按钮),我通常使用ActionListener
。但是,我不同意akf关于ActionListener
是最标准的方法的观点——这可能适用于较小的GUI,但不适用于更复杂的Swing应用程序。Jeff,您的方法似乎是一个好方法。我也这么做。我调用registry 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);
}
}
我在动作上使用注释,然后反射地查找它们
稍微整洁一点,新的操作会自动管理。这一切都是有意义的,这通常是我采取的方法。我想我只是想在我确实需要使用它们的时候找到最好的方法来管理这些动作。。。
ActionHandler.getActionFor(ZoomAction.class).setEnabled(false);