棋盘自动调整大小 [英] Chessboard with automatic resizing

查看:200
本文介绍了棋盘自动调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我试图在javaFX中显示棋盘。我将不得不执行不同的操作并绘制一些瓷砖,所以我选择使用Canvas为每个瓷砖和GridPane以网格方式为我安排它们。

不幸的是我遇到了一些问题随着网格瓷砖的大小调整;我希望我的整个棋盘自动调整它的大小到场景。因此,我在GridPane的高度和宽度属性中添加了一个ChangeListener,它负责调整tile的大小。这仅在窗口变大时才有效,当窗口缩小到更小的尺寸时,所有东西都会变大!

这是最短的 SSCCE 我想出了再现我的问题:

So, I am trying to display a chessboard in javaFX. I will have to perform different operations and draw on some of the tiles so I chose to use a Canvas for each tile and a GridPane to arrange them for me in a grid fashion.
Unfortunately I am having some problems with the resizing of the grid tiles; I want my whole chessboard to automatically adapt its size to the Scene. Therefore, I have added a ChangeListener to both the height and width properties of the GridPane which takes care of resizing the tiles. This only works when the window gets bigger, when the window is reduced to a smaller size everything still gets bigger!
Here's the shortest SSCCE I came up with which reproduces my problem:

package chessboardtest;

import javafx.application.Application;
import javafx.beans.value.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.stage.Stage;

public class ChessboardTest extends Application {

    final int size = 10;

    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox();

        final GridPane chessboard = new GridPane();
        fillChessboard(chessboard, size);

        ChangeListener<Number> resizeListener = new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
                double newWidth = chessboard.getWidth() / size;
                double newHeight = chessboard.getHeight() / size;

                for(Node n: chessboard.getChildren()) {
                    Canvas canvas = (Canvas)n;
                    canvas.setWidth(newWidth);
                    canvas.setHeight(newHeight);
                }
            }
        };

        chessboard.widthProperty().addListener(resizeListener);
        chessboard.heightProperty().addListener(resizeListener);

        root.getChildren().add(chessboard);
        root.setPadding(new Insets(10));
        VBox.setVgrow(chessboard, Priority.ALWAYS);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("chessboard");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    void fillChessboard(GridPane pane, int size) {
        class RedrawListener implements ChangeListener<Number> {
            Color color;
            Canvas canvas;
            public RedrawListener(Canvas c, int i) {
                if(i % 2 == 0) {
                    color = Color.BLACK;
                }
                else {
                    color = Color.WHITE;
                }
                canvas = c;
            }

            @Override
            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
                canvas.getGraphicsContext2D().setFill(color);
                canvas.getGraphicsContext2D().fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            }
        }

        for(int row = 0; row < size; row++) {
            for(int col = 0, i = row; col < size; col++, i++) {
                Canvas c = new Canvas();
                RedrawListener rl = new RedrawListener(c, i);
                c.widthProperty().addListener(rl);
                c.heightProperty().addListener(rl);

                pane.add(c, row, col);
            }
        }
    }

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


推荐答案

如果你不需要画布(你可能不需要),只需使用 StackPane s作为方块,并使它们填充宽度和高度。您可以随时向 StackPane 添加画布(或其他任何内容)以显示其内容。

If you don't need a canvas (and you probably don't), just use StackPanes for the squares and make them fill the width and the height. You can always add a canvas (or anything else) to the StackPanes to display their content.

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Chessboard extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        final int size = 8 ;
        for (int row = 0; row < size; row++) {
            for (int col = 0; col < size; col ++) {
                StackPane square = new StackPane();
                String color ;
                if ((row + col) % 2 == 0) {
                    color = "white";
                } else {
                    color = "black";
                }
                square.setStyle("-fx-background-color: "+color+";");
                root.add(square, col, row);
            }
        }
        for (int i = 0; i < size; i++) {
            root.getColumnConstraints().add(new ColumnConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, HPos.CENTER, true));
            root.getRowConstraints().add(new RowConstraints(5, Control.USE_COMPUTED_SIZE, Double.POSITIVE_INFINITY, Priority.ALWAYS, VPos.CENTER, true));
        }
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

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

这篇关于棋盘自动调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆