如何使用Scene Builder在VBOX中使网格静态化?

时间:2018-04-20 15:59:07

标签: javafx java-8

我最近刚刚进入基于UI的应用程序,但我无法使生成的GridPane无法随窗口扩展。理想情况下,我希望能够点击小按钮,让它生成静态网格,然后调整根阶段/场景的大小以补偿不同的地牢大小。下面的代码只实现了小按钮,然后在它下面绘制网格。

这是我点击小按钮后的屏幕截图。(以及我手动调整窗口大小后)

This is a screenshot after I hit the small button.(and after I manually resized the window)

控制器类

    package Window;

    import Data.Area;
    import Model.Grid;
    import Model.TileSet;
    import javafx.event.ActionEvent;
    import javafx.scene.Scene;
    import javafx.scene.layout.GridPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    import java.io.IOException;

    public class Controller {


    public GridPane gridmane;

    public void genSmall(ActionEvent actionEvent) throws IOException {

        Grid grid = new Grid(new Area(40, 40));
        grid.getPathfinder().shufflePartitions();
        grid.getPathfinder().fillPartitions();
        grid.getPathfinder().generateHallways();

        importGrid(gridmane, grid);

        Stage stage = new Stage();
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.setOpacity(1);
        stage.setTitle("My New Stage Title");
        stage.setScene(new Scene(gridmane, 340, 400));

        stage.show();
    }


    private void importGrid(GridPane gridPane, Grid grid) {
        for (int i = 0; i < grid.getSize().height; i++) {
            for (int j = 0; j < grid.getSize().width; j++) {
                if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
                    changeSquare(gridPane, i, j, Color.WHITE);
                } else {
                    changeSquare(gridPane, i, j, Color.GRAY);
                }
            }
        }
    }

    private void changeSquare(GridPane gridPane, int xCoordinate, int yCoordinate, Color color) {
        Rectangle rect = new Rectangle();
        rect.setStroke(Color.BLACK);
        rect.setFill(color);
        rect.setWidth(10);
        rect.setHeight(10);
        gridPane.add(rect, xCoordinate, yCoordinate);
        }
    }

主类

    package Window;

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    import java.io.IOException;

    public class Main extends Application {

    Stage stage = new Stage();
    int val = 40;

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.stage = primaryStage;
        setVal(val);
    }


    public static void main(String[] args) {
        launch(args);
    }

    public void setVal(int i) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("/view.fxml"));
        stage.setTitle("Dungeon Generator");

        stage.setScene(new Scene(root, 450, 450));
        //primaryStage.setResizable(false);
        stage.sizeToScene();
        stage.show();
    }


    }

FXML文件

    <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="332.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Window.Controller">
   <children>
      <MenuBar>
        <menus>
          <Menu mnemonicParsing="false" text="File">
            <items>
              <MenuItem mnemonicParsing="false" text="Close" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Edit">
            <items>
              <MenuItem mnemonicParsing="false" text="Delete" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Help">
            <items>
              <MenuItem mnemonicParsing="false" text="About" />
            </items>
          </Menu>
        </menus>
      </MenuBar>
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
         <children>
            <Button alignment="CENTER" mnemonicParsing="false" onAction="#genSmall" prefHeight="27.0" prefWidth="64.0" text="Small" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
            <Button alignment="CENTER" mnemonicParsing="false" text="Medium" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
            <Button alignment="CENTER" mnemonicParsing="false" prefHeight="27.0" prefWidth="66.0" text="Large" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
         </children>
      </HBox>
      <GridPane fx:id="gridmane" VBox.vgrow="NEVER">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
      </GridPane>
   </children>
</VBox>

1 个答案:

答案 0 :(得分:1)

您需要摆脱GridPane行/列的限制。对于居中,您可以将网格包裹在StackPane中,并使用Region.USE_PREF_SIZE(= -Infinity)作为最大尺寸限制来防止其增长。

<StackPane VBox.vgrow="ALWAYS" >
    <children>
        <GridPane fx:id="gridmane" VBox.vgrow="NEVER" maxWidth="-Infinity" maxHeight="-Infinity" />
    </children>
</StackPane>
public void genSmall(ActionEvent actionEvent) throws IOException {

    Grid grid = new Grid(new Area(40, 40));
    grid.getPathfinder().shufflePartitions();
    grid.getPathfinder().fillPartitions();
    grid.getPathfinder().generateHallways();

    importGrid(gridmane, grid);

    gridmane.getScene().getWindow().sizeToScene(); // resize window
}

private void importGrid(GridPane gridPane, Grid grid) {
    gridPane.getChildren().clear(); // remove old children

    for (int i = 0; i < grid.getSize().height; i++) {
        for (int j = 0; j < grid.getSize().width; j++) {
            if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
                changeSquare(gridPane, i, j, Color.WHITE);
            } else {
                changeSquare(gridPane, i, j, Color.GRAY);
            }
        }
    }
}