Jef*_*rey 8 java user-interface swing action
通常,当我创建Swing(或任何UI)应用程序时,我会在菜单项和按钮上显示各种操作.我通常创建一个动作注册表并将动作存储在那里,然后当某些事情发生时,我根据应用程序的状态禁用/启用注册表中的动作.我不会称自己是一个狂热的Swing开发人员,虽然我知道我的方法很好,但这是一个非常典型的管理动作的模式吗?或者有更标准的方法吗?
谢谢,
杰夫
Ste*_*eod 10
杰夫,你的方法似乎是一个很好的方法.我做同样的事情.我调用注册表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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在禁用,说ZoomAction,我用
ActionHandler.getActionFor(ZoomAction.class).setEnabled(false);
Run Code Online (Sandbox Code Playgroud)
根据我的经验,处理在Swing GUI上执行操作的" 最 "标准方法是创建ActionListeners并让它们ActionEvent直接处理它们所注册的组件.它是一个简单的设计,它遵循Swing框架中其他种类的GUI事件(MouseListener/ MouseEvent,TableModelListener/ TableModelEvent等)的约定.
Action您描述的框架是一个强大的工具,允许在许多输入方法之间共享操作(即,使用工具栏按钮和菜单项执行相同的操作,因此共享相同Object的操作以处理由两者触发的事件等).这种抽象很酷,但是Sun警告说它比简单的Observers重一点.来自ActionJavaDoc:
请注意,就典型的ActionListener而言,Action实现在存储方面往往更昂贵,而ActionListener不提供集中控制功能和广播属性更改的好处.出于这个原因,您应该注意只使用需要其好处的Actions,并在其他地方使用简单的ActionListener.
我通常采取以下方法:
Action包含Component的动作图.String常量允许应用程序引导代码为"拉出来"的Action从Component所需(例如,将其添加到一个JToolBar,JMenuBar等等).updateActionStates()在Component其中定义一个私有方法,当用户执行某些操作时调用该方法(例如,从a中选择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));
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我通常更倾向于使用Actions来ActionListener暴露Action构成我Component的API的一部分.对于仅存在于Component(例如对话框的"清除"按钮)中的动作,我通常使用ActionListener.但是,我不同意akf关于ActionListener最标准的方法 - 这可能适用于较小的GUI,但不是更复杂的Swing应用程序.
| 归档时间: |
|
| 查看次数: |
1453 次 |
| 最近记录: |