两次调用 ActionListener

问题描述

我觉得有一个简单的解决方案,但出于某种原因,我无法理解它。

我遇到一种情况,必须先单击一个按钮才能单击另一个按钮。用户为这 2 个 JButton 选择的选项将决定程序的下一步。这意味着我必须调用 actionListener 两次,对吗?我将如何在一个 actionPerformed 方法中执行此操作?

我认为我无法在 actionPerformed 方法中执行 if (e.getSource() == square[1][4] && e.getSource() == up) { }...

编辑:我有一块 4x4 按钮板,我使用 JButton 的二维数组制作,它们包含 2 个部分。我还有 4 个 JButtons 代表北、东、南、西。用户必须点击 4x4 棋盘上的棋子,然后点击方向才能使棋子移动。

public class Board extends JPanel implements actionListener
{
    // other variables listed

    private JButton[][] square;

    private boolean circleSelected = false;
    private boolean triangleSelected = false;
    
    // other irrelevant methods
    
    public void actionPerformed(actionEvent e)
    {
        // I don't know how to go about this part 
    }
}

如果需要,我有包含圆形块的 square[0][0] 和包含三角形块的 square[2][3]。但是,由于 x 和 y 会不断变化,我不想指定确切的位置。相反,我宁愿从 clicekd 的图像中确定 circleSelected 变量,即如果用户点击按钮 [x][y] 上面有一个圆圈的图像,那么 circleSelected = true 如果这是有道理的...

解决方法

这意味着我必须调用 actionListener 两次,对吗?

不完全是。您不应直接调用 ActionListener 一次,而这些侦听器应仅响应用户操作。

我认为我无法在 actionPerformed 方法中执行 if (e.getSource() == square[1][4] && e.getSource() == up) { }...

正确,这是非常错误的,因为 ActionEvent 的 source 属性引用一个且仅一个对象。


您可能应该做的是使用类的私有实例字段或多个字段来保存侦听器中使用的状态信息。换句话说,让一个或多个变量保存信息,告诉类之前是否按下了按钮,哪个按钮等,然后根据这些状态变量保存的内容来确定侦听器中发生的事情。如需更具体的详细信息和答案,请考虑提出更具体的问题,包括相关代码,最好是 minimal example program

顺便说一句,大多数按钮都应该有自己的侦听器,通常作为匿名内部类。

旁白#2:如果一个按钮在另一个按钮被按下之前不应该被按下,那么那个按钮或其动作应该被禁用,直到它应该被按下。这可以通过在按钮或其操作(如果有操作)上调用 .setEnabled(...) 来更改。

例如,尝试编译并运行下面的代码。在这里,我使用 firstButton 作为我的 state 字段,该字段更改 ActionListener 的行为。为此,您可以使用布尔值或类的任何实例字段:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Board extends JPanel {
    public static final int ROWS = 4;
    private JButton[][] square = new JButton[ROWS][ROWS];

    private JButton firstButton = null;
    
    public Board() {
        JPanel squarePanel = new JPanel(new GridLayout(ROWS,ROWS));
        for (int i = 0; i < square.length; i++) {
            for (int j = 0; j < square.length; j++) {
                String text = String.format("[%d,%d]",j,i);
                square[i][j] = new JButton(text);
                square[i][j].setFont(square[i][j].getFont().deriveFont(32f));
                square[i][j].addActionListener(e -> squareListener(e));
                squarePanel.add(square[i][j]);
            }
        }
        
        setLayout(new BorderLayout());
        add(squarePanel);
    }
    
    private void squareListener(ActionEvent e) {
        if (firstButton == null) {
            firstButton = (JButton) e.getSource();
            firstButton.setEnabled(false);
        } else {
            JButton secondButton = (JButton) e.getSource();
            secondButton.setEnabled(false);
            String text = "First Button: " + firstButton.getActionCommand() + "; Second Button: " + secondButton.getActionCommand();
            JOptionPane.showMessageDialog(this,text,"Selected Buttons",JOptionPane.PLAIN_MESSAGE);
            for (JButton[] row : square) {
                for (JButton button : row) {
                    button.setEnabled(true);
                }
            }
            firstButton = null;
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new Board());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
,

只需创建一个布尔变量 isButtonOneClicked ,它可以显示是否单击了第一个按钮,如果单击了按钮 2 并且该变量的值为 true,则将执行您的下一步操作

boolean isButtonOneClicked=false;
button1.addActionListener(new ActionListener(){  
   public void actionPerformed(ActionEvent e){ 
        isButtonOneClicked=true;
  }  
});
button2.addActionListener(new ActionListener(){  
   public void actionPerformed(ActionEvent e){ 
      if(isButtonOneClicked){
          //perform next steps
       }
       else{
            // button 1 isn't clicked 
            // can't proceed to next Steps

       }

  }  
});

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...