两次调用 ActionListener

Calling ActionListener twice

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

我遇到的情况是必须先单击一个按钮才能单击另一个按钮。用户为这 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 
    }
}

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

This would mean I'd have to call actionListener twice, right?

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

I don't think I could do if (e.getSource() == square[1][4] && e.getSource() == up) { } in the actionPerformed method...

正确,这是非常错误的,因为 ActionEvent 的源 属性 指的是一个对象。


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

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

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

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

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

       }

  }  
});