如何在Java Swing中实现单击执行多个操作

4

我有一个问题,如何通过单个按钮点击执行其他按钮的操作。以下是三个按钮的示例代码:

JButton a = new JButton("a");
a.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    // Action of a is Here                   
  }
});

JButton b = new JButton("b");
b.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    // Action of b is Here                   
  }
});

那些应该一起出现,比如:

JButton c = new JButton("c");
c.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    // Action of c is Here
    // Action of a 
    // Action of b              
   }
});

在上面的例子中,我有三个按钮a、b、c,每个按钮都有自己的动作;但是你可以看到,C还必须运行A和B的动作。有什么好的方法来解决这个问题?

我刚刚在我的答案中添加了第四个解决方案,我仍然需要验证它,但这应该可以正常工作。 - AxelH
嘿,对不起啊,我是 Stackoverflow 的新手。你可以看一下我的声望和徽章,我真的很高兴你能帮我编辑,但是我真的不知道如何应用更改。你能帮我吗?我真的没有恶意。 - Intact Abode
没关系:这就是我问的原因。所以:你要“点击”那一行,上面写着“edited at ...”。这会给你一个完整的编辑列表,显示了对你的问题进行的所有编辑。现在,如果你想简单地恢复某个版本,你可以转到该版本并点击“回滚”链接。这就是我刚刚做的;既然我们都同意,你的回滚不是有意的。 - GhostCat
正如您所看到的,重新制作的内容已经回来了;而我对您的“抱怨”也消失了。但是要明白一件事:您需要在问题中描述您的问题。无论好坏,像“问候/感谢/重要问题/帮助我”这样的内容在这里都不被鼓励;-) - GhostCat
犯错误意味着学习新的东西。但错误必须只犯一次。所以@GhostCat,你教了我一些新的东西,谢谢。这种错误不会再发生了。 - Intact Abode
4个回答

4
其他答案都是正确的,但这里缺少一个重要方面:小心在AWT事件分派线程上执行“太多事情”。
意思是:当点击按钮时,会创建一个事件,UI框架使用该特殊线程来触发注册的监听器。如果其中一个监听器现在决定进行密集计算... UI事件线程将忙于执行“那件事”。而在执行“那件事”期间,此线程不可用于分派任何其他UI事件。
因此,这不仅涉及创建methodA()、methodB()、methodC()并在第三个动作监听器中调用它们。还包括了解是否将多个调用组合成一个主题:“我最好在单独的线程中运行这些操作,以避免阻塞事件分派线程”。
在这种意义上,其他答案告诉您下一步该怎么做;但一定要非常小心即将创建的“联合操作”按钮所产生的“活动量”!

我在这个问题中没有真正考虑到这一点,但这确实需要提到!通常情况下,如果处理时间超过1/30秒,我会停止大型进程。如果低于此值,则人眼无法察觉,因此不应该成为问题(这不是规则,只是我的做法)。 - AxelH
重点是:今天正常工作并不意味着它明天或将来也会正常。前几天我看到一个人在操作监听器中执行数据库查询。这在您的开发设置中可能会漂亮地工作。但在其他情况下,仅等待连接对象从池中获取可能很容易停滞数秒钟。突然之间,“出乎意料”的是UI客户端冻结了。付费客户会打电话给您的支持团队。 - GhostCat
啊啊啊啊,不幸的是我看到过类似的东西...当然那不是我的规则的一部分,但任何需要外部资源的过程,也就是增长时间或等待时间的过程,都不属于那个逻辑! - AxelH

2

1) 方法

对于每个操作使用方法并在 ActionListener.actionPerformed 中调用它们。

public void methodA(){}
public void methodB(){
    methodA();
}

2) 操作实例

您可以创建自己的 ActionListener 类来执行操作。

第一个操作:

class ActionA implements ActionListener{
     public void actionPerformed(ActionEvent e) {
          ...
    }
}

一种改进的操作

class ActionB extends ActionA{
    public void actionPerformed(ActionEvent e) {
           super.actionPerformed(e);  //Will call the first action
           ...
    }
}

这是有限制的,因为你不能拥有多个继承,但也是一个不错的解决方案。

3) 点击

最后一个方法,我不太喜欢,使用AbstractButton.doClick在其他按钮上进行动态点击。

4) 添加多个事件

请注意,该方法不是setActionListener而是addActionListener,这意味着它将接受多个ActionListener。

所以需要定义两个实例。

ActionListener listenerA = new ActionLisener ..
ActionListener listenerB = new ActionLisener ..

buttonA.addActionListener(listenerA);

buttonB.addActionListener(listenerB);

buttonC.addActionListener(listenerA);
buttonC.addActionListener(listenerB);

通过一个小测试,我注意到动作的执行顺序是B->A(可能不是普遍情况)。
正如评论中所说,我们应该知道风险,这将会。如果一个操作由于异常而失败,下一个操作应该执行吗?默认情况下不会,因为进程不会隐藏异常。
我建议将此解决方案限制在GUI管理中,例如重置字段,禁用等可用于不同按钮的操作。

我会谨慎考虑选项4......当然,它可以工作。但是,这种方式分配“责任”不太透明。 - GhostCat
@GhostCat 明白!我建议将此限制在GUI管理方面,例如启用/禁用字段、清除文本字段等,但不包括业务逻辑。要管理执行动作和异常处理是不可能的。 - AxelH

1

无论你想在按钮点击时做什么,都可以将其放在一个方法中并从任何地方调用它。

public void methodForA(){
   // do here what you want
}

你现在可以在需要调用的方法中调用它。在你的情况下,是从按钮点击 A 和按钮点击 C 调用。
JButton a = new JButton("a");
a.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        methodForA();
    }
 });

// and also in your c-Button
JButton c = new JButton("c");
c.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
          // Action of c is Here
          methodForA(); 
   }
});

谢谢@Stefan Lindner,这比我预期的简单得多,逻辑很简单,非常感谢你,伙计。+1,这对我有用。 - Intact Abode

1

为每个按钮创建3个方法,与actionListeners action Perform方法独立,并从actionPerformed方法中调用它们:

private void btnAClicked(){};
private void btnBClicked(){};
private void btnCClicked(){};


JButton c = new JButton("c");
    c.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
           btnCClicked();
           btnAClicked(); 
           btnBClicked();              

        }
    });

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