Java:JFrame同属性按钮点击识别与Reversi游戏实现技术问询
嘿,这两个问题本质上是同一个需求——不管按钮的文本、高亮样式是否一致,我们都要精准定位到用户点击的按钮在数组里的位置。结合你的Reversi游戏场景,我给你几个实用的解决方案:
方案1:用
ActionCommand存储索引(最简洁的常规方案) 初始化按钮数组的时候,把每个按钮的索引(一维数组的下标,或者二维数组的行/列)设置为它的ActionCommand,这样点击时直接读取即可:
如果是一维数组存储64个按钮:
JButton[] buttons = new JButton[64]; for (int i = 0; i < 64; i++) { buttons[i] = new JButton(); // 将索引转为字符串作为ActionCommand buttons[i].setActionCommand(String.valueOf(i)); // 添加点击监听器 buttons[i].addActionListener(e -> { JButton clickedBtn = (JButton) e.getSource(); // 把字符串转回整数索引 int clickedIndex = Integer.parseInt(clickedBtn.getActionCommand()); // 这里就可以用索引处理落子逻辑了 handlePlayerMove(clickedIndex); }); }
如果是二维数组(更贴合Reversi的8x8棋盘):
JButton[][] gameBoard = new JButton[8][8]; for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { gameBoard[row][col] = new JButton(); // 把行和列拼接成字符串存起来 gameBoard[row][col].setActionCommand(row + "," + col); gameBoard[row][col].addActionListener(e -> { JButton clickedBtn = (JButton) e.getSource(); // 拆分出行和列 String[] coords = clickedBtn.getActionCommand().split(","); int clickedRow = Integer.parseInt(coords[0]); int clickedCol = Integer.parseInt(coords[1]); handlePlayerMove(clickedRow, clickedCol); }); } }
方案2:遍历数组匹配点击的按钮(最直接的笨方法)
如果不想额外设置ActionCommand,也可以在监听器里直接遍历你的按钮数组,找到和事件源匹配的那个按钮:
// 以一维数组为例 buttons[i].addActionListener(e -> { JButton clickedBtn = (JButton) e.getSource(); int clickedIndex = -1; // 遍历数组找匹配的按钮 for (int k = 0; k < buttons.length; k++) { if (buttons[k] == clickedBtn) { clickedIndex = k; break; } } if (clickedIndex != -1) { // 找到索引后处理逻辑 handlePlayerMove(clickedIndex); } });
这个方法简单粗暴,64个按钮的遍历完全不会有性能问题,适合快速测试场景。
你可以创建一个继承自JButton的子类,直接把行/列索引作为成员变量存储,这样获取起来更直观,也方便后续扩展按钮的自定义属性:
// 自定义按钮类 class BoardButton extends JButton { private final int row; private final int col; public BoardButton(int row, int col) { this.row = row; this.col = col; } // 提供获取索引的方法 public int getRow() { return row; } public int getCol() { return col; } }
然后初始化棋盘时用这个子类:
BoardButton[][] gameBoard = new BoardButton[8][8]; for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { gameBoard[row][col] = new BoardButton(row, col); gameBoard[row][col].addActionListener(e -> { BoardButton clickedBtn = (BoardButton) e.getSource(); // 直接获取行和列,不用转字符串/拆分 int clickedRow = clickedBtn.getRow(); int clickedCol = clickedBtn.getCol(); handlePlayerMove(clickedRow, clickedCol); }); } }
我个人比较推荐这个方案,尤其是当你的Reversi游戏后续需要给按钮加更多状态(比如是否可落子、棋子颜色)时,自定义类的扩展性会强很多。
内容的提问来源于stack exchange,提问作者Muhammad Bilal
相关产品推荐
相关产品推荐

