![](/img/trans.png)
[英]Is there a better way to create an actionListener to JButtons in a for-loop?
[英]Why are all my ActionListener's added to JButtons in a loop identical?
好吧,所以我試圖做一個象棋游戲。 我有一個程序可以創建JButton的8x8二維數組。 然后,我將它們全部循環創建,以完成諸如在白色/黑色之間來回移動並添加一個動作事件之類的工作。 我遇到的問題是每個按鈕都具有相同的動作事件,並且是在行8列H上的最后一個IE按鈕創建的事件是數組中所有按鈕的動作偵聽器。 這是我創建按鈕並添加按鈕的代碼段。
我也有一個枚舉列,例如從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));
然后,該按鈕使用其他屬性(我尚未設置)自行設置
制作井字游戲時,我遇到了同樣的問題。 我使用每個按鈕的哈希碼來追溯實際按下了哪個按鈕。 這是我的按鈕設置:
hashcodes= new ArrayList<Integer>();
for (int i=1;i<=9;i++) {
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setHash(button.hashCode());
testWinner();
testDraw();
}
});
hashcodes.add(button.hashCode());
panel.add(button);
}
}
private void setHash(int hashcode) {
for (int h:hashcodes) {
if (h==hashcode) {
//do stuff
}
}
}
這是我的Test課程,並且效果很好。
public class Test extends javax.swing.JFrame {
private javax.swing.JButton[][] buttons;
private final int ROW = 8;
private final int COLUMN = 8;
public Test() {
initComponents();
}
private void initComponents() {
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
this.setExtendedState(javax.swing.JFrame.MAXIMIZED_BOTH);
this.buttons = new javax.swing.JButton[ROW][COLUMN];
this.setLayout(new java.awt.GridLayout(ROW, COLUMN));
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
final int row = i;
final int column = j;
buttons[i][j] = new javax.swing.JButton(
String.format("Button %d-%d", i, j));
buttons[i][j].addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
// System.out.println(
// String.format("You have just pressed the button at row %d and column %d", row, column));
javax.swing.JOptionPane.showMessageDialog(
Test.this, String.format("You have just pressed the button at row %d and column %d", row, column));
}
});
this.add(buttons[i][j]);
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Test().setVisible(true);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.