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

时间:2015-12-09 21:22:58

标签: java arrays button javafx javafx-8

所以我有一个双按钮阵列。一旦我点击一个按钮,我需要能够获得它的索引用于进一步编码(这是一个像游戏一样的扫雷)。到目前为止这是我的代码。我有一个双for循环为每个按钮创建一个Handle事件,但我无法弄清楚如何获取每个按钮的索引。我已经尝试过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<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
             start(primaryStage);               
        }

    });

    Show.setOnAction(new EventHandler<ActionEvent>() {
        @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<ActionEvent> {

    public void handle(ActionEvent e){




        System.out.println("yo clicked one button located at ");
    }
}



public static void main(String[] args){

        Application.launch(args);

}







}

2 个答案:

答案 0 :(得分:3)

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

private EventHandler<ActionEvent> 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<ActionEvent> {

    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);

答案 1 :(得分:2)

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;
    }
}