Java-FX 在点击时接收 Shape-Array 的索引

Java-FX Receive Index of Shape-Array when clicked

我正在尝试构建一个战舰应用程序。到目前为止,我设法为玩家和敌人显示了两个字段。一个字段由 10 x 10 个矩形组成 - 一个 VBox 中有 10 个 HBox。这是为我创建字段的方法:

private Rectangle[][] field;    
public VBox CreateField(){
        VBox vbox = new VBox(2);
        for(int i = 0; i < this.columns; ++i){
            HBox hbox = new HBox(2);
            for(int j = 0; j < this.rows; ++j){
                this.array[j][i] = 0;
                this.field[i][j] = new Rectangle(this.height*j, this.width*i, this.height, this.width);
                this.field[i][j].setStroke(Color.BLACK);
                this.field[i][j].setFill(Color.LIGHTGRAY);                
                hbox.getChildren().add(this.field[i][j]);
            }
            vbox.getChildren().add(hbox);
        } 
        return vbox;
    }

这是结果:

当用户点击其中一个矩形时,我需要接收一个矩形的索引。

你们能给我一个例子/代码片段如何解决我的问题吗?

大声笑,比我想象的要快。这是我的解决方案 (How can I get the indexes of each button clicked for my program?)

private EventHandler<? super MouseEvent> 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));
}
public VBox CreateField(){
    VBox vbox = new VBox(2);
    for(int i = 0; i < this.columns; ++i){
        HBox hbox = new HBox(2);
        for(int j = 0; j < this.rows; ++j){
            this.array[j][i] = 0;
            this.field[i][j] = new Rectangle(this.height*j, this.width*i, this.height, this.width);
            this.field[i][j].setStroke(Color.BLACK);
            this.field[i][j].setFill(Color.LIGHTGRAY);      
            this.field[i][j].setOnMouseClicked(createTileHandler(i,j));
            hbox.getChildren().add(this.field[i][j]);
        }
        vbox.getChildren().add(hbox);
    } 
    return vbox;
}

这个returns:

Clicked tile at (3,2)
Clicked tile at (3,2)
Clicked tile at (4,4)
Clicked tile at (3,0)
Clicked tile at (8,8)
Clicked tile at (9,9)
Clicked tile at (0,0)
Clicked tile at (0,1)
Clicked tile at (0,2)

当我单击一个形状时。 为这个问题道歉..

我建议使用 GridPane 而不是 HBoxes 和 VBox。您可以将循环索引复制到 final 局部变量,以便从在循环体内创建的匿名 EventHandler class/lambda 表达式访问它们,或者您可以使用 GridPane.getRowIndex/GridPane.getColumnIndexGridPane children:

public GridPane CreateField(){
    GridPane grid = new GridPane();
    grid.setVgap(2);
    grid.setHgap(2);
    EventHandler<MouseEvent> handler = evt -> {
        Node source = (Node) evt.getSource();
        int row = GridPane.getRowIndex(source);
        int column = GridPane.getColumnIndex(source);
        ...
    };
    for(int i = 0; i < this.columns; i++){
        for(int j = 0; j < this.rows; j++){
            Rectangle rect = new Rectangle(this.height*j, this.width*i, this.height, this.width);
            this.array[j][i] = 0;
            this.field[i][j] = rect;
            rect.setStroke(Color.BLACK);
            rect.setFill(Color.LIGHTGRAY);
            rect.setOnMouseClicked(handler);
            grid.add(rect, j, i);
        }
    } 
    return grid;
}

您也可以使用

final int finalI = i;
final int finalJ = j;
rect.setOnMouseClicked(evt -> {
    // TODO: use finalI and finalJ here 
});

而是在内部循环中。