JavaFX GridPane 正在调整大小而不是使用新数量的约束保持位置
JavaFX GridPane is resizing instead of holding position with new amount of Constraints
我的任务是创建一个 UI,左侧是导航选项卡,右侧是网格窗格(向下滚动 ui)。
首先,我通过向其添加 Row- 和 Columnconstraints 来初始化网格。首次启动程序后,它完全可以正常工作。
看起来像:
在按下具有更新值的应用按钮后,初始化矩阵似乎仍然存在,并将新约束置于旧值之上。
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
VBox settings = new VBox();
GridPane matrix = new GridPane();
Button applyButton = new Button("Apply settings");
TextField sizeMatrix = new TextField("size");
TextField amountLivingCells = new TextField("living Cells");
matrix.setMinHeight(400);
matrix.setMinWidth(400);
matrix.setMaxHeight(400);
matrix.setMaxWidth(400);
final int initialSize = 12;
final int initialAmountBlackCells = 30;
NumberBinding size = Bindings.min(matrix.widthProperty(),
matrix.heightProperty().subtract(50))
.divide(20);
//binding for size rounded down
NumberBinding roundedSize = Bindings.createIntegerBinding(() -> size.intValue(), size);
//initialize matrix
setConstraints(matrix, initialSize);
//fill out matrix with white Rectangles
setBlankRectangles(matrix, roundedSize, initialSize);
setRandomlyBlackRectangles(matrix, initialAmountBlackCells, initialSize);
applyButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
int size = Integer.parseInt(sizeMatrix.getText());
int amountCells = Integer.parseInt(amountLivingCells.getText());
LogicMinimal.newMatrix(matrix, size);
LogicMinimal.fillMatrixWithDeadCells(matrix, size);
LogicMinimal.randomlySetLivingCells(matrix, amountCells, size);
}
});
root.getChildren().addAll(settings, matrix);
settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
settings.setSpacing(20);
Scene scene = new Scene(root,800,800);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
for(int i = 0; i < amount; i++)
{
int randomCol = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);
int randomRow = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);
for (Node node : matrix.getChildren())
{
if (node instanceof Rectangle &&
GridPane.getColumnIndex(node) == randomCol &&
GridPane.getRowIndex(node) == randomRow)
{
Rectangle cell = (Rectangle)node;
cell.setFill(Color.BLACK);
}
}
}
}
private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
for(int column = 0; column < size; column++)
{
for(int row = 0; row < size; row++)
{
Rectangle dead_cell = new Rectangle();
dead_cell.setFill(Color.WHITE);
dead_cell.widthProperty().bind(roundedSize);
dead_cell.heightProperty().bind(roundedSize);
GridPane.setColumnIndex(dead_cell, column);
GridPane.setRowIndex(dead_cell, row);
matrix.add(dead_cell, column, row);
}
}
}
private void setConstraints(GridPane matrix, int size) {
matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());
double cellWidth;
double cellHeight;
for(int i = 0; i < size; i++)
{
ColumnConstraints colConst = new ColumnConstraints();
cellWidth = 100.0 / size;
colConst.setPercentWidth(cellWidth);
matrix.getColumnConstraints().add(colConst);
RowConstraints rowConst = new RowConstraints();
cellHeight = 100.0 / size;
rowConst.setPercentHeight(cellHeight);
matrix.getRowConstraints().add(rowConst);
}
}
public static void main(String[] args) {
launch(args);
}
}
所以我看到的主要问题是这些行
LogicMinimal.newMatrix(matrix, size1);
LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);
这是因为您创建了一个新矩阵而没有删除旧矩阵,所以这导致它仍然显示在屏幕上。此外,您从未发布 LogicMinimal
Class 的代码,因此我添加了必要的代码以使其 运行 正确
我还更改了以下两行,以便黑色方块出现在第 0 列和第 0 行中,您也可以随时恢复此更改
int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0
这是完全运行可用的class
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
TextField sizeMatrix = new TextField();
sizeMatrix.setPromptText("Size");
TextField amountLivingCells = new TextField();
amountLivingCells.setPromptText("living Cells");
Button applyButton = new Button("Apply settings");
applyButton.setOnAction(e -> {
//Remove Old matrix
GridPane oldMatrix = null;
for (Node child : root.getChildren()) {
if(child instanceof GridPane) {
oldMatrix = (GridPane) child;
break;
}
}
root.getChildren().remove(oldMatrix);
int size = Integer.parseInt(sizeMatrix.getText());
int amountCells = Integer.parseInt(amountLivingCells.getText());
//Build and Add new Matrix
GridPane newMatrix = buildNewMatrix(size, amountCells);
root.getChildren().add(newMatrix);
//No longer needed
//LogicMinimal.newMatrix(matrix, size1);
//LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
//LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);
});
VBox settings = new VBox();
settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
settings.setSpacing(20);
GridPane matrix = buildNewMatrix(12, 30);
root.getChildren().addAll(settings, matrix);
Scene scene = new Scene(root,800,800);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
applyButton.requestFocus();
} catch(Exception e) {
e.printStackTrace();
}
}
private GridPane buildNewMatrix(int initialSize, int initialAmountBlackCells){
GridPane newMatrix = new GridPane();
newMatrix.setMinHeight(400);
newMatrix.setMinWidth(400);
newMatrix.setMaxHeight(400);
newMatrix.setMaxWidth(400);
NumberBinding size = Bindings.min(newMatrix.widthProperty(),
newMatrix.heightProperty().subtract(50))
.divide(20);
//binding for size rounded down
NumberBinding roundedSize = Bindings.createIntegerBinding(size::intValue, size);
//initialize newMatrix
setConstraints(newMatrix, initialSize);
//fill out newMatrix with white Rectangles
setBlankRectangles(newMatrix, roundedSize, initialSize);
setRandomlyBlackRectangles(newMatrix, initialAmountBlackCells, initialSize);
return newMatrix;
}
private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
for(int i = 0; i < amount; i++)
{
int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0
for (Node node : matrix.getChildren())
{
if (node instanceof Rectangle &&
GridPane.getColumnIndex(node) == randomCol &&
GridPane.getRowIndex(node) == randomRow)
{
Rectangle cell = (Rectangle)node;
cell.setFill(Color.BLACK);
}
}
}
}
private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
for(int column = 0; column < size; column++)
{
for(int row = 0; row < size; row++)
{
Rectangle dead_cell = new Rectangle();
dead_cell.setFill(Color.WHITE);
dead_cell.widthProperty().bind(roundedSize);
dead_cell.heightProperty().bind(roundedSize);
GridPane.setColumnIndex(dead_cell, column);
GridPane.setRowIndex(dead_cell, row);
matrix.add(dead_cell, column, row);
}
}
}
private void setConstraints(GridPane matrix, int size) {
matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());
double cellWidth;
double cellHeight;
for(int i = 0; i < size; i++)
{
ColumnConstraints colConst = new ColumnConstraints();
cellWidth = 100.0 / size;
colConst.setPercentWidth(cellWidth);
matrix.getColumnConstraints().add(colConst);
RowConstraints rowConst = new RowConstraints();
cellHeight = 100.0 / size;
rowConst.setPercentHeight(cellHeight);
matrix.getRowConstraints().add(rowConst);
}
}
}
我的任务是创建一个 UI,左侧是导航选项卡,右侧是网格窗格(向下滚动 ui)。 首先,我通过向其添加 Row- 和 Columnconstraints 来初始化网格。首次启动程序后,它完全可以正常工作。
看起来像:
在按下具有更新值的应用按钮后,初始化矩阵似乎仍然存在,并将新约束置于旧值之上。
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
VBox settings = new VBox();
GridPane matrix = new GridPane();
Button applyButton = new Button("Apply settings");
TextField sizeMatrix = new TextField("size");
TextField amountLivingCells = new TextField("living Cells");
matrix.setMinHeight(400);
matrix.setMinWidth(400);
matrix.setMaxHeight(400);
matrix.setMaxWidth(400);
final int initialSize = 12;
final int initialAmountBlackCells = 30;
NumberBinding size = Bindings.min(matrix.widthProperty(),
matrix.heightProperty().subtract(50))
.divide(20);
//binding for size rounded down
NumberBinding roundedSize = Bindings.createIntegerBinding(() -> size.intValue(), size);
//initialize matrix
setConstraints(matrix, initialSize);
//fill out matrix with white Rectangles
setBlankRectangles(matrix, roundedSize, initialSize);
setRandomlyBlackRectangles(matrix, initialAmountBlackCells, initialSize);
applyButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
int size = Integer.parseInt(sizeMatrix.getText());
int amountCells = Integer.parseInt(amountLivingCells.getText());
LogicMinimal.newMatrix(matrix, size);
LogicMinimal.fillMatrixWithDeadCells(matrix, size);
LogicMinimal.randomlySetLivingCells(matrix, amountCells, size);
}
});
root.getChildren().addAll(settings, matrix);
settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
settings.setSpacing(20);
Scene scene = new Scene(root,800,800);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
for(int i = 0; i < amount; i++)
{
int randomCol = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);
int randomRow = ThreadLocalRandom.current().nextInt(1, sizeMatrix + 1);
for (Node node : matrix.getChildren())
{
if (node instanceof Rectangle &&
GridPane.getColumnIndex(node) == randomCol &&
GridPane.getRowIndex(node) == randomRow)
{
Rectangle cell = (Rectangle)node;
cell.setFill(Color.BLACK);
}
}
}
}
private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
for(int column = 0; column < size; column++)
{
for(int row = 0; row < size; row++)
{
Rectangle dead_cell = new Rectangle();
dead_cell.setFill(Color.WHITE);
dead_cell.widthProperty().bind(roundedSize);
dead_cell.heightProperty().bind(roundedSize);
GridPane.setColumnIndex(dead_cell, column);
GridPane.setRowIndex(dead_cell, row);
matrix.add(dead_cell, column, row);
}
}
}
private void setConstraints(GridPane matrix, int size) {
matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());
double cellWidth;
double cellHeight;
for(int i = 0; i < size; i++)
{
ColumnConstraints colConst = new ColumnConstraints();
cellWidth = 100.0 / size;
colConst.setPercentWidth(cellWidth);
matrix.getColumnConstraints().add(colConst);
RowConstraints rowConst = new RowConstraints();
cellHeight = 100.0 / size;
rowConst.setPercentHeight(cellHeight);
matrix.getRowConstraints().add(rowConst);
}
}
public static void main(String[] args) {
launch(args);
}
}
所以我看到的主要问题是这些行
LogicMinimal.newMatrix(matrix, size1);
LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);
这是因为您创建了一个新矩阵而没有删除旧矩阵,所以这导致它仍然显示在屏幕上。此外,您从未发布 LogicMinimal
Class 的代码,因此我添加了必要的代码以使其 运行 正确
我还更改了以下两行,以便黑色方块出现在第 0 列和第 0 行中,您也可以随时恢复此更改
int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0
这是完全运行可用的class
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
TextField sizeMatrix = new TextField();
sizeMatrix.setPromptText("Size");
TextField amountLivingCells = new TextField();
amountLivingCells.setPromptText("living Cells");
Button applyButton = new Button("Apply settings");
applyButton.setOnAction(e -> {
//Remove Old matrix
GridPane oldMatrix = null;
for (Node child : root.getChildren()) {
if(child instanceof GridPane) {
oldMatrix = (GridPane) child;
break;
}
}
root.getChildren().remove(oldMatrix);
int size = Integer.parseInt(sizeMatrix.getText());
int amountCells = Integer.parseInt(amountLivingCells.getText());
//Build and Add new Matrix
GridPane newMatrix = buildNewMatrix(size, amountCells);
root.getChildren().add(newMatrix);
//No longer needed
//LogicMinimal.newMatrix(matrix, size1);
//LogicMinimal.fillMatrixWithDeadCells(matrix, size1);
//LogicMinimal.randomlySetLivingCells(matrix, amountCells, size1);
});
VBox settings = new VBox();
settings.getChildren().addAll(sizeMatrix, amountLivingCells, applyButton);
settings.setSpacing(20);
GridPane matrix = buildNewMatrix(12, 30);
root.getChildren().addAll(settings, matrix);
Scene scene = new Scene(root,800,800);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
applyButton.requestFocus();
} catch(Exception e) {
e.printStackTrace();
}
}
private GridPane buildNewMatrix(int initialSize, int initialAmountBlackCells){
GridPane newMatrix = new GridPane();
newMatrix.setMinHeight(400);
newMatrix.setMinWidth(400);
newMatrix.setMaxHeight(400);
newMatrix.setMaxWidth(400);
NumberBinding size = Bindings.min(newMatrix.widthProperty(),
newMatrix.heightProperty().subtract(50))
.divide(20);
//binding for size rounded down
NumberBinding roundedSize = Bindings.createIntegerBinding(size::intValue, size);
//initialize newMatrix
setConstraints(newMatrix, initialSize);
//fill out newMatrix with white Rectangles
setBlankRectangles(newMatrix, roundedSize, initialSize);
setRandomlyBlackRectangles(newMatrix, initialAmountBlackCells, initialSize);
return newMatrix;
}
private void setRandomlyBlackRectangles(GridPane matrix, int amount, int sizeMatrix) {
for(int i = 0; i < amount; i++)
{
int randomCol = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in col 0
int randomRow = ThreadLocalRandom.current().nextInt(0, sizeMatrix + 1);//Change 1 to 0 to allow to be placed in row 0
for (Node node : matrix.getChildren())
{
if (node instanceof Rectangle &&
GridPane.getColumnIndex(node) == randomCol &&
GridPane.getRowIndex(node) == randomRow)
{
Rectangle cell = (Rectangle)node;
cell.setFill(Color.BLACK);
}
}
}
}
private void setBlankRectangles(GridPane matrix, NumberBinding roundedSize, int size) {
for(int column = 0; column < size; column++)
{
for(int row = 0; row < size; row++)
{
Rectangle dead_cell = new Rectangle();
dead_cell.setFill(Color.WHITE);
dead_cell.widthProperty().bind(roundedSize);
dead_cell.heightProperty().bind(roundedSize);
GridPane.setColumnIndex(dead_cell, column);
GridPane.setRowIndex(dead_cell, row);
matrix.add(dead_cell, column, row);
}
}
}
private void setConstraints(GridPane matrix, int size) {
matrix.getRowConstraints().removeAll(matrix.getRowConstraints());
matrix.getColumnConstraints().removeAll(matrix.getColumnConstraints());
double cellWidth;
double cellHeight;
for(int i = 0; i < size; i++)
{
ColumnConstraints colConst = new ColumnConstraints();
cellWidth = 100.0 / size;
colConst.setPercentWidth(cellWidth);
matrix.getColumnConstraints().add(colConst);
RowConstraints rowConst = new RowConstraints();
cellHeight = 100.0 / size;
rowConst.setPercentHeight(cellHeight);
matrix.getRowConstraints().add(rowConst);
}
}
}