我该如何在Swing中组织我的动作?

3

我目前正在替换我的匿名ActionListeners


new ActionListener() {
    @Override
    public void actionPerformed(final ActionEvent event) {
        // ...
    }
}

使用 class 文件表示操作:

public class xxxxxxxAction extends AbstractAction {
}

然而,我的GUI能够执行许多操作(例如:创建人物操作、重命名人物操作、删除人物操作、交换人物操作等)。

有没有一种好的方法将这些类组织成一个连贯的结构?


2
请提供一些上下文; 请参阅如何使用Actions - trashgod
@trashgod,您所说的上下文是什么意思?我正在感受将约60个ActionListeners转换为单独类的压力,不确定是否有更好的方法来组织我的代码中的Actions。 - sdasdadas
3个回答

8

您可以将操作放在单独的包中以进行隔离。有时,将它们放在一个类中是很有用的,特别是如果这些操作相关或具有共同的父级,例如:

public class SomeActions {
    static class SomeActionX extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    static class SomeActionY extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }

    static class SomeActionZ extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    }
}

然后访问它们的方法是:
JButton button = new JButton();
button.setAction(new SomeActions.SomeActionX());

1
你也可以使用Action API,这也允许你存储有关操作的属性,许多Swing组件都能够用其自身配置。 - MadProgrammer

6

我只是感到将约60个ActionListener转换成单独的类很麻烦。

只有你可以决定是否60个ActionListener是最少的。这个示例使用了四个单一类的实例。如果按照一系列静态工厂方法分组,那么这里StyledEditorKit是一个很好的例子。在这里所引用的示例中,使用了嵌套类。在这里所引用的JHotDraw动态生成适当的操作。


1
谢谢,这也是 Aqua 概述的内容 - 但知道名称是“静态工厂方法”很好。 - sdasdadas

4
首先,您应该为所有操作(如createPerson、removePerson等)提供公共的actionPerformed方法。所有这些操作方法应在一个类中(我称之为PersonController)。然后,您需要定义AbstractPersonAction:
public class AbstractPersonAction extends AbstractAction {
  private PersonController controller;

  public AbstractPersonAction(PersonController aController) {
    controller = aController;
  }

  protected PersonController getController() {
    return controller;
  }
}

现在,您可以将所有操作提取到单独的类中。
public class CreatePersonAction extends AbstractPersonAction {

  public CreatePersonAction(PersonController aController) {
    super(controller);
  }

  public void actionPerformed(ActionEvent ae) {
    getController().createPerson();
  }
}

这些操作可以是外部类的一部分,也可以放置在单独的“actions”包中。


这与其他答案的思路类似,但如果我只能传递控制器一次而不是在创建每个操作时都要传递(而不被迫在程序启动时“初始化”),那将会很有帮助。 - sdasdadas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接