如何为我的程序单击每个按钮的索引?

所以我有一个双按钮arrays。 一旦我点击一个按钮,我需要能够获得它的索引用于进一步编码(这是一个像游戏一样的扫雷)。 到目前为止这是我的代码。 我有一个双for循环为每个按钮创建一个句柄事件,但我无法弄清楚如何获取每个按钮的索引。 我试过e.getSource()但它只返回无用的地址。 我试过给每个按钮一个Id,但它只接受字符串。 我迷失在接下来该做什么。

import javafx.application.Application; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Stage; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Random; public class main extends Application { Button[][] tiles = new Button[8][8]; Integer[][] mine_field = new Integer[8][8]; Stage window; public void start(Stage primaryStage){ BorderPane Field = new BorderPane(); HBox Start_Show = new HBox(50); Button Start = new Button("Start"); Button Show = new Button ("Show"); Start.setStyle("-fx-font-size: 15.5pt;"); Show.setStyle("-fx-font-size: 15.5pt;"); Start_Show.getChildren().addAll(Start, Show); Start_Show.setAlignment(Pos.CENTER); Start_Show.setPadding(new Insets(10,10,10,10)); Field.setTop(Start_Show); tiles = create_tiles(tiles); int i; int j; VBox columns = new VBox(); for(i=0; i<8; i++){ HBox row = new HBox(); for(j=0; j<8; j++){ row.getChildren().add(tiles[i][j]); } columns.getChildren().add(row); } columns.setAlignment(Pos.CENTER); columns.setPadding(new Insets(0,0,0,100)); Field.setCenter(columns); mine_field = set_mines(mine_field); Start.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { start(primaryStage); } }); Show.setOnAction(new EventHandler() { @Override public void handle(ActionEvent e){ int i = 0; int j = 0; for(i=0; i<8; i++){ for(j=0; j<8; j++){ if(mine_field[i][j] == 1) { tiles[i][j].setStyle("-fx-font-size: 15.5pt;"); tiles[i][j].setTextFill(Color.RED); tiles[i][j].setMaxHeight(150); tiles[i][j].setMaxWidth(251); tiles[i][j].setText("M"); } } } } }); for(i=0; i<8; i++){ for(j=0; j<8; j++){ Tile_Handler tile_handle = new Tile_Handler(); tiles[i][j].setOnAction(tile_handle); } } Scene scene = new Scene(Field, 600, 600); primaryStage.setTitle("MineSweeper!"); primaryStage.setScene(scene); primaryStage.show(); } public Button[][] create_tiles(Button[][] array){ int i; int j; for(i=0; i<8; i++){ for(j=0; j<8; j++){ Button my_butt = new Button("?"); my_butt.setStyle("-fx-font-size: 20pt;"); my_butt.prefWidthProperty(); array[i][j] = my_butt; } } return array; } public Integer[][] set_mines(Integer[][] array){ Random random = new Random(); int i; int j; int k; for(i=0; i<8; i++){ for(j=0; j<8; j++){ array[i][j] = 0; } } for(i=0; i<10; i++){ j = random.nextInt(8); k = random.nextInt(8); array[j][k] = 1; } return array; } class Tile_Handler implements EventHandler { public void handle(ActionEvent e){ System.out.println("yo clicked one button located at "); } } public static void main(String[] args){ Application.launch(args); } } 

您可以使用实用程序函数和lambda表达式动态创建具有参数的切片处理程序:

 private EventHandler createTileHandler(int x, int y) { return event -> tileHandler(x, y); } private void tileHandler (int x, int y){ System.out.println(String.format("Clicked tile at (%d,%d)", x, y)); } 

然后应用于不同的按钮,如下所示:

  ... for (int i=0; i<8; i++){ for (int j=0; j<8; j++) { tiles[i][j].setOnAction(createTileHandler(i, j)); } } ... 

或者,修改当前解决方案,可以向Tile_Handler添加两个成员,因此在创建它时,将其附加到特定坐标:

 class Tile_Handler implements EventHandler { private int x, y; public Tile_Handler(int x, int y) { this.x = x; this.y = y; } public void handle(ActionEvent e){ System.out.println(String.format("yo clicked one button located at %d,%d",x,y)); } } 

然后将实例化更改为

 Tile_Handler tile_handle = new Tile_Handler(i, j); 

Sillyfly的答案很棒,下面的信息只是作为一个不同的选项。

如果您只需要访问事件处理程序中的坐标,Sillyfly将协调数据存储在事件处理程序中的方法是一种很好的方法。 如果您需要从其他位置访问,可以使用以下方法。

您可以将坐标与原始对象(按钮)存储在一起,而不是将坐标存储在事件处理程序中。 您可以通过扩展按钮并添加其他属性或使用可在任何节点上设置的通用userData属性来完成此操作。

 for (int i = 0; i < N_ROWS; i++) { for (int j = 0; j < N_COLS; j++) { Button button = new Button(); button.setUserData(new Coord(i,j)); button.setOnAction(event -> takeActionForCoord((Coord) button.getUserData())); pane.getChildren().add(button); } } 

Coord是按钮坐标的持有者类别。

 class Coord { private int i; private int j; public Coord(int i, int j) { this.i = i; this.j = j; } public int getI() { return i; } public int getJ() { return j; } }