gpt4 book ai didi

java - 在 JavaFX 中将元素动态添加到固定大小的 GridPane

转载 作者:行者123 更新时间:2023-12-02 05:42:23 29 4
gpt4 key购买 nike

我想在 JavaFX 中显示包含各种矩形的网格。不能调整此网格的大小很重要。

我选择了GridPane布局。我动态添加 javafx.scene.shape.Rectangle到它。这是我的网格 2 行 4 列的样子。

Grid 4x2

调整大小后,我希望它保持相同的整体形状,即每个Rectangle具有相同的尺寸并在我的 Rectangle 之间保持水平和垂直间隙s。

但是,这是我使用 4x4 网格得到的结果:
enter image description here

问题在于:

  • 最后一行和最后一列的大小与 Rectangle 的其余部分不同s。
  • 缝隙已经消失。

  • 这是我负责刷新显示的代码:
    public void refreshConstraints() {
    getRowConstraints().clear();
    getColumnConstraints().clear();

    for (int i = 0; i < nbRow; i++) {
    RowConstraints rConstraint = new RowConstraints();
    // ((nbRow - 1) * 10 / nbRow) = takes gap into account (10% of height)
    rConstraint.setPercentHeight(100 / nbRow - ((nbRow - 1) * 10 / nbRow));
    getRowConstraints().add(rConstraint);
    }

    for (int i = 0; i < nbColumn; i++) {
    ColumnConstraints cConstraint = new ColumnConstraints();
    cConstraint.setPercentWidth(100 / nbColumn - ((nbColumn - 1) * 10 / nbColumn));
    getColumnConstraints().add(cConstraint);
    }

    }

    使用 setFillWidthsetHgrow也没有结果,我的 Rectangle 之间存在差距s,但 Rectangle s 没有调整大小,它们与我的 GUI 元素的其余部分重叠。

    编辑 :MCVE 代码:
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.ColumnConstraints;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.RowConstraints;
    import javafx.scene.paint.Paint;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;

    public class DynamicGrid extends Application {

    //Class containing grid (see below)
    private GridDisplay gridDisplay;

    @Override
    public void start(Stage primaryStage) {

    //Represents the grid with Rectangles
    gridDisplay = new GridDisplay(400, 200);

    //Fields to specify number of rows/columns
    TextField rowField = new TextField();
    TextField columnField = new TextField();
    //Function to set an action when text field loses focus
    buildTextFieldActions(rowField, columnField);
    HBox fields = new HBox();
    fields.getChildren().add(rowField);
    fields.getChildren().add(new Label("x"));
    fields.getChildren().add(columnField);

    BorderPane mainPanel = new BorderPane();
    mainPanel.setLeft(gridDisplay.getDisplay());
    mainPanel.setBottom(fields);

    Scene scene = new Scene(mainPanel);
    primaryStage.setTitle("Test grid display");
    primaryStage.setScene(scene);
    primaryStage.show();
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
    launch(args);
    }

    private void buildTextFieldActions(final TextField rowField, final TextField columnField) {
    rowField.focusedProperty().addListener(new ChangeListener<Boolean>() {

    @Override
    public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
    if (!t1) {
    if (!rowField.getText().equals("")) {
    try {
    int nbRow = Integer.parseInt(rowField.getText());
    gridDisplay.setRows(nbRow);
    gridDisplay.updateDisplay();
    } catch (NumberFormatException nfe) {
    System.out.println("Please enter a valid number.");
    }
    }
    }
    }
    });

    columnField.focusedProperty().addListener(new ChangeListener<Boolean>() {

    @Override
    public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
    if (!t1) {
    if (!columnField.getText().equals("")) {
    try {
    int nbColumn = Integer.parseInt(columnField.getText());
    gridDisplay.setColumns(nbColumn);
    gridDisplay.updateDisplay();
    } catch (NumberFormatException nfe) {
    System.out.println("Please enter a valid number.");
    }
    }
    }
    }
    });
    }

    //Class responsible for displaying the grid containing the Rectangles
    public class GridDisplay {

    private GridPane gridPane;
    private int nbRow;
    private int nbColumn;
    private int width;
    private int height;
    private double hGap;
    private double vGap;

    public GridDisplay(int width, int height) {
    this.gridPane = new GridPane();
    this.width = width;
    this.height = height;
    build();
    }

    private void build() {
    this.hGap = 0.1 * width;
    this.vGap = 0.1 * height;
    gridPane.setVgap(vGap);
    gridPane.setHgap(hGap);
    gridPane.setPrefSize(width, height);
    initializeDisplay(width, height);
    }

    //Builds the first display (correctly) : adds a Rectangle for the number
    //of rows and columns
    private void initializeDisplay(int width, int height) {
    nbRow = height / 100;
    nbColumn = width / 100;

    for (int i = 0; i < nbColumn; i++) {
    for (int j = 0; j < nbRow; j++) {
    Rectangle rectangle = new Rectangle(100, 100);
    rectangle.setStroke(Paint.valueOf("orange"));
    rectangle.setFill(Paint.valueOf("steelblue"));
    gridPane.add(rectangle, i, j);

    }
    }
    }

    //Function detailed in post
    //Called in updateDisplay()
    public void refreshConstraints() {
    gridPane.getRowConstraints().clear();
    gridPane.getColumnConstraints().clear();
    for (int i = 0; i < nbRow; i++) {
    RowConstraints rConstraint = new RowConstraints();
    rConstraint.setPercentHeight(100 / nbRow - ((nbRow - 1) * 10 / nbRow));
    gridPane.getRowConstraints().add(rConstraint);
    }

    for (int i = 0; i < nbColumn; i++) {
    ColumnConstraints cConstraint = new ColumnConstraints();
    cConstraint.setPercentWidth(100 / nbColumn - ((nbColumn - 1) * 10 / nbColumn));
    gridPane.getColumnConstraints().add(cConstraint);
    }

    }

    public void setColumns(int newColumns) {
    nbColumn = newColumns;
    }

    public void setRows(int newRows) {
    nbRow = newRows;
    }

    public GridPane getDisplay() {
    return gridPane;
    }

    //Function called when refreshing the display
    public void updateDisplay() {
    Platform.runLater(new Runnable() {

    @Override
    public void run() {
    //The gridpane is cleared of the previous children
    gridPane.getChildren().clear();

    //A new rectangle is added for row*column
    for (int i = 0; i < nbColumn; i++) {
    for (int j = 0; j < nbRow; j++) {
    Rectangle rectangle = new Rectangle(100, 100);
    rectangle.setStroke(Paint.valueOf("orange"));
    rectangle.setFill(Paint.valueOf("steelblue"));
    gridPane.add(rectangle, i, j);
    }
    }
    //Call to this function to update the grid's constraints
    refreshConstraints();
    }
    });

    }

    }

    }

    最佳答案

    好像是 TilePane比 GridPane 更适合这个用例。

    2by4
    3by2

    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.TilePane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;

    // java 8 code
    public class DynamicTiles extends Application {

    //Class containing grid (see below)
    private GridDisplay gridDisplay;

    //Class responsible for displaying the grid containing the Rectangles
    public class GridDisplay {

    private static final double ELEMENT_SIZE = 100;
    private static final double GAP = ELEMENT_SIZE / 10;

    private TilePane tilePane = new TilePane();
    private Group display = new Group(tilePane);
    private int nRows;
    private int nCols;

    public GridDisplay(int nRows, int nCols) {
    tilePane.setStyle("-fx-background-color: rgba(255, 215, 0, 0.1);");
    tilePane.setHgap(GAP);
    tilePane.setVgap(GAP);
    setColumns(nCols);
    setRows(nRows);
    }

    public void setColumns(int newColumns) {
    nCols = newColumns;
    tilePane.setPrefColumns(nCols);
    createElements();
    }

    public void setRows(int newRows) {
    nRows = newRows;
    tilePane.setPrefRows(nRows);
    createElements();
    }

    public Group getDisplay() {
    return display;
    }

    private void createElements() {
    tilePane.getChildren().clear();
    for (int i = 0; i < nCols; i++) {
    for (int j = 0; j < nRows; j++) {
    tilePane.getChildren().add(createElement());
    }
    }
    }

    private Rectangle createElement() {
    Rectangle rectangle = new Rectangle(ELEMENT_SIZE, ELEMENT_SIZE);
    rectangle.setStroke(Color.ORANGE);
    rectangle.setFill(Color.STEELBLUE);

    return rectangle;
    }

    }

    @Override
    public void start(Stage primaryStage) {

    //Represents the grid with Rectangles
    gridDisplay = new GridDisplay(2, 4);

    //Fields to specify number of rows/columns
    TextField rowField = new TextField("2");
    TextField columnField = new TextField("4");

    //Function to set an action when text field loses focus
    buildTextFieldActions(rowField, columnField);

    HBox fields = new HBox(10);
    fields.getChildren().add(rowField);
    fields.getChildren().add(new Label("x"));
    fields.getChildren().add(columnField);

    BorderPane mainPanel = new BorderPane();
    mainPanel.setCenter(gridDisplay.getDisplay());
    mainPanel.setTop(fields);

    Scene scene = new Scene(mainPanel, 1000, 800);
    primaryStage.setTitle("Test grid display");
    primaryStage.setScene(scene);
    primaryStage.show();
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
    launch(args);
    }

    private void buildTextFieldActions(final TextField rowField, final TextField columnField) {
    rowField.focusedProperty().addListener((ov, t, t1) -> {
    if (!t1) {
    if (!rowField.getText().equals("")) {
    try {
    int nbRow = Integer.parseInt(rowField.getText());
    gridDisplay.setRows(nbRow);
    } catch (NumberFormatException nfe) {
    System.out.println("Please enter a valid number.");
    }
    }
    }
    });

    columnField.focusedProperty().addListener((ov, t, t1) -> {
    if (!t1) {
    if (!columnField.getText().equals("")) {
    try {
    int nbColumn = Integer.parseInt(columnField.getText());
    gridDisplay.setColumns(nbColumn);
    } catch (NumberFormatException nfe) {
    System.out.println("Please enter a valid number.");
    }
    }
    }
    });
    }
    }

    关于java - 在 JavaFX 中将元素动态添加到固定大小的 GridPane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23272924/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com