可调整大小的二次网格

时间:2014-12-25 14:37:14

标签: javafx-8

我想在窗口中显示二次GridPane。窗口可以具有所有可能的尺寸,并且通常宽度和高度不相等。无论如何,我想将GridPane显示为像这样的中心:

width greater than height

分别

height greater than width

理想情况下,广场周围有可配置的填充物。这些图片是从画布方法中获取的,但我想切换到标准控件。任何人都可以给我一些提示如何实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

为窗口的任何分辨率实现网格的平方布局的一种方法是重新缩放它以使用窗口的最大大小(在一些填充之后),同时保持平方大小。

而不是GridPane,简单的Group可以更灵活地移动其子项,但需要手动布局它们。

这个简单的片段基于您可以找到的{20}游戏的JavaFX实现here。它使用可设置的矩形来创建网格,并在其上添加“tile”。要了解有关样式,布局或平铺移动的更多信息,请转到所提到的链接。

private static final int NUM_CELLS = 15;
private static final int CELL_SIZE = 50;
private static final int TILE_SIZE = CELL_SIZE-15;
private final static int MARGIN = 20;

@Override
public void start(Stage primaryStage) {
    // create background square grid
    Group gridGroup = new Group();
    IntStream.range(0,NUM_CELLS).boxed().forEach(i->
        IntStream.range(0,NUM_CELLS).boxed().forEach(j->{
            Rectangle cell = new Rectangle(i * CELL_SIZE, j * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            cell.setFill(Color.WHEAT);
            cell.setStroke(Color.GREY);
            gridGroup.getChildren().add(cell);
        })
    );
    // Add grid to board
    Group board = new Group(gridGroup);

    // add random tiles to board
    IntStream.range(0,NUM_CELLS).boxed().forEach(i->
        IntStream.range(0,NUM_CELLS).boxed().forEach(j->{
            if(i==j || NUM_CELLS-i-1==j){
                Label label = new Label();
                label.setMinSize(TILE_SIZE, TILE_SIZE);
                label.setPrefSize(TILE_SIZE, TILE_SIZE);
                label.setMaxSize(TILE_SIZE, TILE_SIZE);
                label.setStyle("-fx-background-color: red; -fx-background-radius: 50");
                label.setLayoutX((i+0.5)*CELL_SIZE-TILE_SIZE/2);
                label.setLayoutY((j+0.5)*CELL_SIZE-TILE_SIZE/2);
                board.getChildren().add(label);
            }
        })
    );

    Bounds gameBounds = board.getLayoutBounds();

    StackPane root = new StackPane(board);

    // Listener to rescale and center the board
    ChangeListener<Number> resize = (ov, v, v1) -> {
        double scale = Math.min((root.getWidth() - MARGIN) / gameBounds.getWidth(), 
                                (root.getHeight() - MARGIN) / gameBounds.getHeight());
        board.setScaleX(scale);
        board.setScaleY(scale);
        board.setLayoutX((root.getWidth() - gameBounds.getWidth()) / 2d);
        board.setLayoutY((root.getHeight() - gameBounds.getHeight()) / 2d);
    };
    root.widthProperty().addListener(resize);
    root.heightProperty().addListener(resize);

    Scene scene = new Scene(root);

    // Maximum size of window
    Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
    double factor = Math.min(visualBounds.getWidth() / (gameBounds.getWidth() + MARGIN),
            visualBounds.getHeight() / (gameBounds.getHeight() + MARGIN));
    primaryStage.setScene(scene);
    primaryStage.setWidth((gameBounds.getWidth() + MARGIN) * factor);
    primaryStage.setHeight((gameBounds.getHeight() + MARGIN) * factor);
    primaryStage.show();
}

这是在调整窗口大小后的样子:

Grid