javafx - javaFX在按钮坐标上显示正确的值
问题描述
我已经将问题简化为问题,所以我正在为扫雷游戏制作 UI,在下面的控制器中,在 StartGame 方法中,一切都很好(根据我使用调试的检查),直到行
游戏.open(x,y)
,这意味着我设法创建板并将按钮(将充当插槽)添加到 GridPane,但我的问题是我似乎无法打开并在插槽上显示正确的值。(地雷类的逻辑工作正常 - 没有 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 个孩子。所以真的,你只是循环遍历第一行(或第一列)中的所有孩子。
在路上,我可以解决这个问题;
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));
}
}
这样你就可以遍历所有的孩子并检查他们在黑板上的状态。
我不知道 GridPane 中子节点的顺序是否对应于布局顺序,这是将 2D 数组打包成 1D 数组的常用技术,
bCont.TheBoard.getChildren().get(i + j*game.getCol());
请记住,您有第 x 列总计按钮。
推荐阅读
- html - 移动/响应式菜单 - 如何调整随下拉菜单移动的 div 元素的位置
- javascript - React redux调度错误:未定义错误
- python - 在 NetworkX 中按年分组以计算年连接数
- javascript - 在 HTML 中嵌入可填写的 PDF 表单,上传已填写的 PDF
- python - python telnet.mt_interact 在任何 IDE 中都不起作用,但 SPYDER
- tcp - 是否有 WPA2 安全 MAVLINK 协议通信?
- python - 将项目添加到购物车 python 请求?
- node.js - 管理和访问多个 mongoDB 连接的最佳方式 - nodeJS
- php - Cpanel 和 laravel 中的 CRON
- reactjs - Redux,使用 useSelector 访问 API 对象内的数据