写了很长时间的Swing 程序,总结了一些Action 使用方面的模式与大家共享一下。
1、Sensitive Action Pattern
写过Swing 程序的人都知道,根据用户选择的对象来控制某些Action 的状态(Enable/Disable)是比较繁琐的一件事情,通常我们需要监听控件的选择事件,然后再获取到Action的实例,再根据不同的条件来改变它的状态,代码中到处充满了if...else...这些过程性的代码,而且有时为了获取到Action 的实例,还要做很多特殊的处理。
Sensitive Action 模式是我在编写代码时想出的,主要的目的是让代码变得更加简洁,尽量避免重复的代码。接口层的结构图如下:
接口图
上图中各成员的说明如下:
SensitiveAction:该接口定义了selectionChanged 方法,当用户选择对象发生变化时,可以通过该方法通知本Action,
InstanceProvider:该接口定义了一些方法用户获取用户选中的实例。
除了上面定义的接口以外,还有一些帮助类如下:
这些ActionHelper 类主要负责监听事件,然后通知所有被加入的SensitiveAction。
具体应用时的代码如下:
- public void attachAction(JTable table) {
- JTableActionHelper helper = new JTableActionHelper(table);
- ConcreteAction action1 = new ConcreteAction();
- helper.addSensitveAction(action1);
- .....//Create popup menu and add it to the JTable
- }
2、Alternative Action Pattern
该模式是基于上面的SensitiveAction 模式的,我在开发的经常会遇到一些互斥的Action,例如:Lock/Unlock,Activate/Deactivate 等等。这些Action 同时只能出现一个,AlternativeAction 的代码实现如下:
- public class AlternativeAction extends AbstractAction implements SensitiveAction{
- public AlternativeAction(SensitiveAction action1,SensitiveAction actions2) {
- this.action1 = action1;
- this.action2 = action2;
- }
- public void actionPerformed(ActionEvent event) {
- if(action1.isEnable())
- action1.actionPerformed(event);
- else if(action2.isEnable())
- action2.actionPerformed(event);
- }
- public void selectionChanged(InstanceProvider provider) {
- action1.selectionChanged(provider);
- action2.selectionChanged(provider);
- if(action1.isEnabled())
- putValue(NAME,action1.getValue(NAME);
- else if(action2.isEnable())
- putValue(NAME, action2.getValue(NAME));
- )
- }
3、Safe Action
在Action 的actionPerformed 方法中经常会出现一些 RuntimeException,这些异常如果不被捕捉,就会出现用户点击了一个菜单或按钮后没有任何反应;有时候,我们也需要在actionPerformed 方法中处理一些业务相关的Exception,例如:用户去删除一个用户组下有用户的用户组时,系统应该弹出相应的警告对话框。像这类的问题如果让每个Action 自己去处理会出现很多重复的代码,应该只需要一个类去处理这类问题,然后所有的Action 从该中继承就可以了,代码如下:
- public abstract class SafeAction extends AbstractAction{
- private Container parent;
- public SafeAction(Container parent) {
- this.parent = parent;
- }
- public void actionPerformed(ActionEvent e) {
- try {
- performed(e);
- } catch (Throwable e1) {
- //Show error dialog;
- }
- }
- public abstract void performed(ActionEvent e)throws Throwable;
- }
该类定义了一个模板方法performed 方法,子类应该在该方法中编写Action 的执行代码。