好吧,我正在尝试制作一个 Swing 的国际象棋游戏。我有一个程序可以创建 JButton 的 8x8 二维数组。然后,我在循环中创建它们,执行诸如在白色/黑色之间来回切换并添加 Action 事件之类的操作。我遇到的问题是每个按钮都有相同的操作事件,并且它是最后创建的事件。第 8 行 H 列上的按钮是数组中所有按钮的操作监听器。这是我创建按钮并添加它们的代码片段。
我还有一个枚举列,例如从 int 到字符 1 到 H。 selectPosition 和 targetPosition 是具有两个成员列和行的对象。
public void initializeGui(boolean isWhite) {
boolean shouldBeWhite = true;
for(int i = 0; i< 8; i++){
for(int j = 0; j < 8; j++){
column = i+1;
row = j+1;
JButton square = new JButton();
square.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
final int thisRow = row;
final int thisColumn = column;
selectPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
selectPosition.setRow(thisRow);
if(isSelecting){
System.out.print("Selecting square to move. Row: " + thisRow + " Column: " + Columns.getColumnsFromInt(thisColumn));
selectPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
selectPosition.setRow(thisRow);
} else{
System.out.print("Targeting square to move to. Row: " + thisRow + " Column: " + Columns.getColumnsFromInt(thisColumn) + "\n");
targetPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
targetPosition.setRow(thisRow);
}
System.out.println("");
isSelecting = !isSelecting;
}
});
if(shouldBeWhite){
square.setBackground(Color.WHITE);
shouldBeWhite = false;
}else{
square.setBackground(Color.BLACK);
shouldBeWhite = true;
}
if (j == 7){
shouldBeWhite = !shouldBeWhite;
}
chessBoardSquares[i][j] = square;
gui.add(chessBoardSquares[i][j]);
}
}
if(isWhite){
setInitialPiecesWhiteStart();
}else{
setInitialPiecesBlackStart();
}
}
作为此类的成员,进一步如下:
int column = 0, row = 0;
当我点击这些按钮中的任何一个时,我会看到打印内容
Selecting square to move. Row: 8 Column: H
Targeting square to move to. Row: 8 Column: H
Selecting square to move. Row: 8 Column: H
Targeting square to move to. Row: 8 Column: H
等等。我的问题是为什么这些按钮都被赋予相同的操作事件?我的逻辑演练类似于创建第一个按钮集 column = i+1 和 row = j+1,然后添加一个带有操作事件的操作监听器,该操作事件将当前行/列值设置为内部最终变量,然后打印出来与该操作事件关联的 thisRow 和 thisColumn。我是否覆盖了最后的值,或者范围是否错误?基本上我是如何错误地创建这些按钮操作监听器的?
最佳答案
你可以...
使用 actionCommand
API 在按钮和 ActionListener
之间传递信息...
JButton btn = new JButton();
btn.setActionCommand(row + "x" + column);
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//...
}
});
这里的问题是您依赖 String
解析来提取值,这很快就会变得困惑
你可以...
创建一个自定义的ActionListener
,它接受您想要使用的值...
public class SquareActionListener implements ActionListener {
private int column;
private int row;
public SquareActionListener(int row, int column) {
this.row = row;
this.column = column;
}
@Override
public void actionPerformed(ActionEvent e) {
//...
}
}
这将 ActionListener
与代码的其余部分分离,并为您提供所需的信息,尽管您可能还需要传递其他信息(例如模型)才能使其工作
你可以...
利用Action
API,它旨在提供独立的工作单元,它通常是一个更可重用的解决方案,但可能有点超出您现在的需要
public class SquareAction extends AbstractAction {
private int column;
private int row;
public SquareAction(int row, int column) {
this.row = row;
this.column = column;
}
@Override
public void actionPerformed(ActionEvent e) {
//...
}
}
这看起来很像最后一个建议,但您实际上不是将其添加为按钮的 ActionListener
,而是直接将其应用到按钮...
JButton btn = new JButton(new SquareAction(row, column));
然后该按钮使用其他属性(我尚未设置)来设置自身
关于java - 为什么循环中添加到 JButton 的所有 ActionListener 都是相同的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42568798/