【问题标题】:JavaFX split space evenly between two side panels in an HBoxJavaFX 在 HBox 的两个侧面板之间均匀分割空间
【发布时间】:2020-05-26 20:40:03
【问题描述】:

我有一个 HBox,其中心包含一个方形 VBox。 HBox 的宽度可以做得大于它的高度,在侧面留下额外的空间。我想用单独的 VBox 填充左侧和右侧的额外空间,我将在其中放置按钮、信息等。我希望这两个 VBox(“侧面板”)始终具有相同的宽度。但是,如下图所示,当右侧面板有按钮而左侧没有按钮时,它比左侧面板宽:

我想

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 始终是正方形?

谢谢!

【问题讨论】:

    标签: java user-interface javafx


    【解决方案1】:

    当你添加 e 时它会起作用。 g.:

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

    编辑:如果您使用GridPane 作为根布局可能会更好,其中您可以拥有三列具有固定百分比宽度的列,例如 e。 g.:15 %(左侧)、70 %(中心)和 15 %(右侧)。但只有您可以知道并决定什么最适合您的项目。 :-P

    【讨论】:

    • 谢谢,但我不遵循任何善恶的宗教信仰或任何其他教条;)随时提供更好的答案。
    • 在标记错误答案方面没有任何宗教意义;)如果尺寸因任何原因发生变化,这将打破
    • 那么什么是上帝的答案呢?
    【解决方案2】:

    经过大量测试,我得到了这个工作:

    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 设置为零,然后将内部窗格添加到每个面板中,然后将内容添加到其中。我认为这样做的原因是因为在面板的大小被 Hgrow 约束扩展之前为 prefWidth 分配了空间。由于 HBox 为每个面板添加了等量的空间,因此具有更大 prefWidth 的面板最终会更大。通过将两者都设置为零,它们都以没有 prefWidth 开始,因此以相同的大小结束。我相信这也是anko's answer 似乎起作用的原因 - 因为当它们以相同的 prefWidths 开始并且每个添加相同数量的空间时,它们最终具有相同的大小。但是,当舞台的宽度尽可能小时,将 prefWidth 设置为 100 会与 boardBox 的大小(使其不是正方形)混淆。

    我确信有更好的方法可以做到这一点,我很乐意接受更好的答案。

    【讨论】:

    • 难道你不知道,只有魔鬼自己敢为首选宽度设置一个值。 :) 只是在开玩笑。如果 0 比典型的 100 效果更好,我可以接受。干得好。
    • @anko 硬编码尺寸是响应式设计的对立面。在这里,Sam 似乎正在使用嵌套布局来“欺骗”系统。不幸的是,更强大的解决方案可能会涉及创建自定义布局。
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 2022-06-10
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    相关资源
    最近更新 更多