单击时,Java-FX接收Shape-Array索引

时间:2018-05-27 20:37:44

标签: java javafx shape mouseclick-event

我正在尝试构建战舰应用程序。到目前为止,我设法为玩家和敌人显示两个字段。一个字段由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;
    }

结果如下:

enter image description here

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

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

2 个答案:

答案 0 :(得分:1)

劳拉,比我想象的要快得多。这是我的解决方案(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;
}

返回:

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)

当我点击一个Shape时。 为这个问题道歉..

答案 1 :(得分:1)

我建议使用GridPane代替HBox es和VBox。您可以将循环索引复制到final局部变量,以从循环体内创建的匿名EventHandler类/ lambda表达式访问它们,或者可以使用GridPane.getRowIndex / GridPane.getColumnIndex GridPane孩子:

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 
});
而在内循环中