JavaFX равномерно разделяет пространство между двумя боковыми панелями в HBox - PullRequest
0 голосов
/ 26 мая 2020

У меня есть HBox, который содержит квадратный VBox в центре. Ширина HBox может быть больше его высоты, оставляя дополнительное пространство по бокам. Я хочу заполнить это дополнительное пространство слева и справа отдельными VBox'ами, куда я помещу кнопки, информацию и т. Д. c. Я хочу, чтобы эти два VBox, «боковые панели» всегда были одинаковой ширины. Однако, как вы можете видеть на изображении ниже, когда правая панель имеет кнопку, а левая - нет, она шире, чем левая панель: enter image description here

Я думал

rightPanel.minWidthProperty().bindBidirectional(leftPanel.minWidthProperty());
rightPanel.prefWidthProperty().bindBidirectional(leftPanel.prefWidthProperty());

подойдет, но это не так.

Вот мой код:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.NumberBinding;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class FX010 extends Application{
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        GamePanel gp = new GamePanel();
        Scene scene = new Scene(gp, 800, 600);

        primaryStage.setTitle("testing");
        primaryStage.minWidthProperty().bind(primaryStage.heightProperty());
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.show();
    }
    public class GamePanel extends HBox{
        public GamePanel() {
            this.setMinHeight(400);
            final VBox boardBox = new VBox();

            boardBox.alignmentProperty().set(Pos.CENTER);
            this.alignmentProperty().set(Pos.CENTER);


            VBox leftPanel, rightPanel;
            leftPanel = new VBox();
            rightPanel = new VBox();
            leftPanel.setBorder(new Border(new BorderStroke(Color.DARKRED, BorderStrokeStyle.SOLID,
                    CornerRadii.EMPTY,new BorderWidths(1))));
            rightPanel.setBorder(new Border(new BorderStroke(Color.DARKRED, BorderStrokeStyle.SOLID,
                    CornerRadii.EMPTY,new BorderWidths(1))));
            rightPanel.minWidthProperty().bindBidirectional(leftPanel.minWidthProperty());
            rightPanel.prefWidthProperty().bindBidirectional(leftPanel.prefWidthProperty());
            rightPanel.getChildren().add(new Button("testtesttest"));

            HBox.setHgrow(leftPanel, Priority.ALWAYS);
            HBox.setHgrow(rightPanel, Priority.ALWAYS);

            StackPane board = new StackPane(new Rectangle(100,100,Color.RED));
            board.setBorder(new Border(new BorderStroke(Color.DARKBLUE, BorderStrokeStyle.DASHED,
                    CornerRadii.EMPTY,new BorderWidths(1))));

            final NumberBinding binding = Bindings.min(widthProperty(), heightProperty());

            boardBox.prefWidthProperty().bind(binding);
            boardBox.prefHeightProperty().bind(binding);
            boardBox.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);

            VBox.setVgrow(board, Priority.ALWAYS);

            boardBox.getChildren().add(board);

            getChildren().addAll(leftPanel, boardBox, rightPanel);

            //HBox.setHgrow(this, Priority.ALWAYS);
        }
    }
}

Как я могу заставить leftPanel всегда иметь ту же ширину, что и rightPanel, при этом boardBox всегда будет квадратом?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

После долгого тестирования я получил следующее:

public class GamePanel extends HBox{
        Pane leftPanel, rightPanel, iLeft, iRight;
        VBox boardBox;
        public GamePanel() {
            this.setMinHeight(400);
            iLeft = new Pane();
            boardBox = new VBox();
            iRight = new Pane();

            boardBox.alignmentProperty().set(Pos.CENTER);
            this.alignmentProperty().set(Pos.CENTER);

            leftPanel = new Pane();
            rightPanel = new Pane();
            leftPanel.setBorder(new Border(new BorderStroke(Color.DARKRED, BorderStrokeStyle.SOLID,
                    CornerRadii.EMPTY,new BorderWidths(1))));
            rightPanel.setBorder(new Border(new BorderStroke(Color.DARKRED, BorderStrokeStyle.SOLID,
                    CornerRadii.EMPTY,new BorderWidths(1))));
            rightPanel.setPrefWidth(0);
            leftPanel.setPrefWidth(0);
            iRight.getChildren().add(new Button("testtesttest"));
            rightPanel.getChildren().add(iRight);

            HBox.setHgrow(leftPanel, Priority.ALWAYS);
            HBox.setHgrow(rightPanel, Priority.ALWAYS);


            StackPane board = new StackPane(new Rectangle(100,100,Color.RED));
            board.setBorder(new Border(new BorderStroke(Color.DARKBLUE, BorderStrokeStyle.DASHED,
                    CornerRadii.EMPTY,new BorderWidths(1))));

            final NumberBinding binding = Bindings.min(widthProperty(), heightProperty());

            boardBox.prefWidthProperty().bind(binding);
            boardBox.prefHeightProperty().bind(binding);
            boardBox.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);

            VBox.setVgrow(board, Priority.ALWAYS);

            boardBox.getChildren().add(board);

            getChildren().addAll(leftPanel, boardBox, rightPanel);

            //HBox.setHgrow(this, Priority.ALWAYS);
        }
    }

Это решение включает в себя установку prefWidth левой и правой панелей на ноль, а затем добавление внутренних панелей в каждую панель, содержимое которой затем добавляется к. Я думаю, причина того, что это работает, заключается в том, что для prefWidth выделяется пространство до того, как размер панели будет расширен ограничением Hgrow. Поскольку HBox добавляет равное количество места к каждой панели, панель с большей prefWidth становится больше. Если установить оба значения в ноль, они оба начинаются без prefWidth и, таким образом, имеют одинаковый размер. Я считаю, что именно поэтому ответ anko , похоже, сработал - потому что, когда они начинаются с равными prefWidths и к каждому добавляется одинаковое количество места, они имеют одинаковый размер. Однако установка prefWidth равная 100 не соответствует размеру boardBox (делает его не квадратом), когда ширина рабочей области уменьшается как можно меньше.

Я уверен, что есть лучший способ сделайте это, и я буду рад принять лучший ответ.

0 голосов
/ 27 мая 2020

Он работает, когда вы добавляете, например:

leftPanel.setPrefWidth(100d);
rightPanel.setPrefWidth(100d);

Изменить: Может быть, было бы лучше, если бы вы использовали GridPane как макет root, где вы можете иметь три столбца с фиксированной процентной шириной например: 15% (левая сторона), 70% (центр) и 15% (правая сторона). Но только вы можете знать и решать, что лучше всего подходит для вашего проекта. : -P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...