javaFX 在按钮坐标上显示正确的值

javaFX show correct value on button coordinates

我已经将问题简化为问题,所以我正在为扫雷游戏制作 UI,在下面的控制器中,在 StartGame 方法中,一切正常(根据我使用的检查debug) 直到

game.open(x,y)

,这意味着我设法创建了面板并将按钮(将充当插槽)添加到 GridPane,但我的问题是我似乎无法打开并在插槽上显示正确的值。 (地雷的逻辑 class 工作正常 - 没有 javaFX 部分的那个)。

package MS;

import java.io.IOException;
import java.util.Random;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBase;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class NewGameCONTROLLER {
    Mines game;
    int rows, columns, mines;
    Button b;

    @FXML
    private TextField NumRows;

    @FXML
    private TextField NumCols;

    @FXML
    private TextField NumM;

    @FXML
    private Button StartGame;

    @FXML
    private Button BackMainMenu;

    @FXML
    private Button RandomGame;

    @FXML
    void BackMainMenu(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(); // Create loading object
        loader.setLocation(getClass().getResource("MainMenuFXML.fxml")); // fxml location
        VBox root = loader.load(); // Load layout
        root.setStyle("-fx-background-image: url(\"file:///C:/EclipseProjects/MineSweeper/src/MS/menu.jpg\")");
        Scene scene = new Scene(root); // Create scene with chosen layout
        Stage primaryStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        primaryStage.setTitle("..."); // Set stage's title
        primaryStage.setMinWidth(400); // Won't be allowed to make width/height smaller
        primaryStage.setMinHeight(350);
        primaryStage.setMaxWidth(600);
        primaryStage.setMaxHeight(450);
        primaryStage.setScene(scene); // Set scene to stage
        primaryStage.show(); // Show stage
    }

    @FXML
    void RandomGame(ActionEvent event) {
        Random rand = new Random();
        int low = 3, high = 15;
        int minesLow = 1, minesHigh;
        rows = rand.nextInt(high - low) + low;
        columns = rand.nextInt(high - low) + low;
        minesHigh = rows * columns - 1;
        mines = rand.nextInt(minesHigh - minesLow) + minesLow;
        game = new Mines(rows, columns, mines);
    }

    @FXML
    void StartGame(ActionEvent event) throws IOException {
        rows = Integer.parseInt(NumRows.getText());
        columns = Integer.parseInt(NumCols.getText());
        mines = Integer.parseInt(NumM.getText());
        game = new Mines(rows, columns, mines);

        FXMLLoader loader = new FXMLLoader(); // Create loading object
        loader.setLocation(getClass().getResource("BoardFXML.fxml")); // fxml location

        AnchorPane root = loader.load(); // Load layout
        root.setStyle("-fx-background-image: url(\"file:///C:/EclipseProjects/MineSweeper/src/MS/Pic.jpg\")");
        Scene scene = new Scene(root); // Create scene with chosen layout
        Stage gameStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        gameStage.setTitle("..."); // Set stage's title
        gameStage.setMinWidth(1000); // Won't be allowed to make width/height smaller
        gameStage.setMinHeight(500);
        gameStage.setMaxWidth(1200);
        gameStage.setMaxHeight(800);
        gameStage.setScene(scene); // Set scene to stage

        BoardCONTROLLER bCont = loader.getController(); // Prepare board in BoardCONTROLLER
        for (int i = 0; i < columns; i++)
            for (int j = 0; j < rows; j++) {
                b = new Button(" ");
                b.setMinSize(40, 40);
                b.setMaxSize(40, 40);
                bCont.TheBoard.add(b, i, j);
            }
        for (int i = 0; i < bCont.TheBoard.getChildren().size(); i++) {
            ((ButtonBase) bCont.TheBoard.getChildren().get(i)).setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    int x, y;
                    event.getSource();
                    x = (int) ((Button) event.getSource()).getProperties().get("gridpane-column");
                    y = (int) ((Button) event.getSource()).getProperties().get("gridpane-row");
                    game.open(x, y);
                    for (int i=0;i<game.getCol();i++)
                        for (int j=0;i<game.getRow();j++) {
                            if (game.board[i][j].charAt(1)=='T')
                                ((Button) bCont.TheBoard.getChildren().get(i)).setText(game.get(x, y));
                        }
                /*  while ()
                    for (int i = 0; i < bCont.TheBoard.getChildren().size(); i++) {
                        if (game.board[x][y].charAt(2) == 'B') {
                            ((Button) bCont.TheBoard.getChildren().get(i)).setText(game.get(x, y));
                        }
                    }*/
                }
            });
        }
        gameStage.show(); // Show stage
    }

}

谢谢。

当我看到这个循环时。

for (int i=0;i<game.getCol();i++)
    for (int j=0;i<game.getRow();j++) {
        if (game.board[i][j].charAt(1)=='T')
            ((Button) bCont.TheBoard.getChildren().get(i)).setText(game.get(x, y));
    }    
}

变量i对应的不是一行坐标,它对应的是棋盘中的第n个child。所以实际上,您只是循环遍历第一行(或第一列)中的所有 children。

我正在努力解决这个问题;

for( Node child: bCont.TheBoard.getChildren() ){
    int i = (int) ((Button) child).getProperties().get("gridpane-column");
    int j = (int) ((Button) child).getProperties().get("gridpane-row");
    if (game.board[i][j].charAt(1)=='T'){
        ((Button) child).setText(game.get(x, y));
    }
}

这样你就可以浏览所有 children 并检查他们在板上的状态。

不知道GridPane中的children个节点的顺序是否对应​​布局顺序,一个二维数组打包成一维数组的常用技巧,

bCont.TheBoard.getChildren().get(i + j*game.getCol());

记住你有 row x col total 按钮。