当前位置: 首页 > 知识库问答 >
问题:

自动调整大小的棋盘

严承允
2023-03-14

所以,我试图在JavaFX中显示一个棋盘。我将不得不执行不同的操作和绘制一些瓷砖,所以我选择使用画布为每个瓷砖和一个网格窗格为我以网格的方式排列它们。
不幸的是,我有一些问题与网格瓷砖的大小;我想让我的整个棋盘自动适应它的大小来适应场景。因此,我在GridPane的height和width属性中添加了一个ChangeListener,它负责调整瓷砖的大小。这只在窗口变大时起作用,当窗口缩小到更小的尺寸时,所有的东西仍然变大!
下面是我想出的最短的SSCCE,它再现了我的问题:

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);
    }
}

共有1个答案

牛华皓
2023-03-14

如果您不需要画布(您可能不需要),只需对方块使用stackpanes,并使它们填充宽度和高度。您始终可以向StackPane添加画布(或其他任何内容)以显示它们的内容。

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);
    }
}
 类似资料:
  • Android最近增加了根据视图大小以及最小和最大文本大小调整TextViews文本大小的支持。 https://developer.Android.com/guide/topics/ui/look-and-feel/autosizing-textView.html 不幸的是,他们不支持EditTexts,那么EditText还有其他的替代方案吗?

  • 我在使用gmap组件时遇到了一个小问题:当我试图使组件可调整大小时(即在CSS的帮助下将地图的高度和宽度都设置为100%),组件会收缩,地图本身也会变得不可见。但如果设置了固定的高度/宽度,则组件工作良好。有没有一种方法可以自动调整GMAP的大小?

  • 我是JavaFX的新手,目前我试图构建一个小型聊天窗口。为此,我为我的Listview获得了以下自定义单元格布局。 网格 我使用外部HBox,所以我可以像whatsapp一样对齐消息。。。(左右对齐)。在我的GridPane中,我得到了两列,消息(标签)在左侧,其他一些随机的东西在右侧(时间戳,一些小图标)。现在我需要的是:GridPane/左列/标签的高度应该根据文本消息的长度动态地增长/收缩。

  • 问题内容: 我一直试图(徒劳地)建立一个页面,当我更改窗口大小时,其元素将重新调整大小。我可以在CSS中使用它来处理图像,但是没有问题,但是我似乎无法在文本上完成相同的操作,而且我不确定在CSS中是否有可能。而且我似乎找不到能完成此任务的jQuery脚本。 当用户调整窗口大小时,我实质上希望页面能够动态流畅地缩放,而无需用户调用页面缩放。通过css在我的img div上这可以正常工作,但对于文本则

  • 我是一个新的android开发和我正在尝试创建和应用程序与网格菜单,菜单。 当前依赖项:compile fileTree(目录:“libs”,include:['*.jar'])testCompile“junit:junit:4.12”编译组:“org.apache.httpcomponents”,名称:“httpclient-android”,版本:“4.3.5.1”编译组:“cz.mseber

  • 问题内容: 我有一个子类,可以在其上添加按钮,标签,表格等。要在屏幕上显示,请使用: 但是,当我调整窗口大小时,面板的大小不会改变。即使调整了尺寸,如何使面板的尺寸与窗口的尺寸相同? 问题答案: 您可以设置一个类似于BorderLayout的布局管理器,然后更具体地定义面板应该放置的位置: 这会将面板置于框架的中央区域,并在调整框架大小时自动增长。