两次调用 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
}
}
});
我觉得有一个简单的解决方案,但出于某种原因,我无法解决这个问题。
我遇到的情况是必须先单击一个按钮才能单击另一个按钮。用户为这 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
}
}
});