JavaFX边框窗格布局(拉伸左侧和右侧窗格)

JavaFX边框窗格布局(拉伸左侧和右侧窗格),java,javafx,Java,Javafx,我正在使用BorderPane在JavaFX中实现布局 假设BorderPane的maxPrefWidth设置为1000。左窗格中有一个按钮,右窗格中有一个按钮。在中间窗格中,有另一个大小未知的按钮 如果:中间元素的宽度为500,则左侧和右侧节点 宽度应该是250 如果:中间元素的宽度为600,则左侧和右侧节点 宽度应该是200 有没有办法告诉左窗格和右窗格自动(水平)增长,直到击中中心节点?BorderPane按设计扩展中间区域 您的意图与的设计意图不一致 引用Javadoc: 顶部和底部

我正在使用BorderPane在JavaFX中实现布局

假设BorderPane的maxPrefWidth设置为1000。左窗格中有一个按钮,右窗格中有一个按钮。在中间窗格中,有另一个大小未知的按钮

  • 如果:中间元素的宽度为500,则左侧和右侧节点 宽度应该是250
  • 如果:中间元素的宽度为600,则左侧和右侧节点 宽度应该是200
有没有办法告诉左窗格和右窗格自动(水平)增长,直到击中中心节点?

BorderPane
按设计扩展中间区域 您的意图与的设计意图不一致

引用Javadoc:

顶部和底部子项将调整为其首选高度,并扩展边框窗格的宽度。左侧和右侧子节点的大小将调整为其首选宽度,并在顶部和底部节点之间延伸长度。中心节点将被调整大小以填充中间可用空间。任何位置都可以为空

这意味着:

  • 中心将扩展以占用所有额外空间
  • 顶部和底部采用最大宽度和首选高度
  • 左侧和右侧区域采用其首选宽度和最大高度
把中间想象成一个盒子,里面有一个强壮的人,他上下推,然后向外推

对于许多商业应用程序来说,这种逻辑通常非常方便。外部区域通常用于、、等。然后,内部区域包含感兴趣的主要内容。考虑到这种用法,只将必要的空间分配给外部区域是有意义的,而将大部分空间分配给内部内容区域是有意义的

例如,下面是一个使用JavaFX14的完整示例应用程序

在这个示例应用程序的中心区域,我们放置了一个包含单个按钮的
HBox
布局。我们将该布局的背景色设置为
cornflowerblue
color,以显示中心区域的内容如何扩展以占用所有额外空间

package work.basil.example;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.time.ZonedDateTime;

/**
 * JavaFX App
 */
public class App extends Application
{

    @Override
    public void start ( Stage stage )
    {
        // Widgets
        ToolBar toolBar = new ToolBar();
        Button button = new Button( "Click Me" );
        toolBar.getItems().add( button );

        Button buttonLeft = new Button( "Left" );
        Button buttonRight = new Button( "Right" );

        HBox appContent = new HBox( new Button( "Bonjour le monde" ) );
        appContent.setStyle( "-fx-background-color: cornflowerblue;" );

        HBox statusBar = new HBox( new Label( "Status goes here. Now: " + ZonedDateTime.now() ) );

        // Arrange
        BorderPane borderPane = new BorderPane();
        borderPane.setTop( toolBar );
        borderPane.setLeft( buttonLeft );
        borderPane.setCenter( appContent );
        borderPane.setRight( buttonRight );
        borderPane.setBottom( statusBar );

        var scene = new Scene( borderPane , 1000 , 1000 );
        stage.setScene( scene );
        stage.show();
    }

    public static void main ( String[] args )
    {
        launch();
    }
}
选择其他布局 正如对问题的评论,考虑到您的意图,您应该使用不同的布局管理器

你也许可以靠一个小男孩过日子。为了获得最大的控制力,您需要投入一些时间来掌握

GridPane
你的问题不是很清楚。如果您希望将中心内容的宽度固定为500像素,而左侧和右侧是灵活的,按比例分配任何额外空间,则在设置to或
优先级时使用。始终在左侧和右侧单元格上使用

下面是一个完整的示例应用程序

我们在单行网格窗格的每个单元格中放置一个按钮,每个按钮嵌套在一个
HBox
。颜色戏剧性地显示了此处显示的尺寸行为。或者,您可以删除彩色的
HBox
,而不是调用
gridPane.setStyle(“-fx网格线可见:true;”)来显示每个单元格周围的边框线

package work.basil.example;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.time.ZonedDateTime;

/**
 * JavaFX App
 */
public class App extends Application
{

    @Override
    public void start ( Stage stage )
    {
        // Widgets
        Button buttonLeft = new Button( "Left" );
        HBox left = new HBox( buttonLeft );
        left.setStyle( "-fx-background-color: Salmon;" );

        Button buttonCenter = new Button( "Center" );
        HBox center = new HBox( buttonCenter );
        center.setStyle( "-fx-background-color: CornflowerBlue;" );

        Button buttonRight = new Button( "Right" );
        HBox right = new HBox( buttonRight );
        right.setStyle( "-fx-background-color: MediumSeaGreen;" );

        // GridPane
        GridPane gridPane = new GridPane();
        gridPane.addRow( 0 , left , center , right );  // Add these widgets in first row (annoying zero-based counting means index 0 is row 1).
        gridPane.setStyle( "-fx-grid-lines-visible: true ;" );  // Add lines to the edges of each cell (row/column) in the grid. Useful for learning and debugging. https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#gridpane

        // Grid constraints
        ColumnConstraints column1 = new ColumnConstraints();
        column1.setHgrow( Priority.SOMETIMES ); // Extra space alloted to this column.

        ColumnConstraints column2 = new ColumnConstraints( 500 ); // Fixed width of 500 pixels.

        ColumnConstraints column3 = new ColumnConstraints();
        column3.setHgrow( Priority.SOMETIMES );// Extra space alloted to this column.

        gridPane.getColumnConstraints().addAll( column1 , column2 , column3 ); // first column gets any extra width

        // Render
        var scene = new Scene( gridPane , 1000 , 150 );
        stage.setScene( scene );
        stage.setTitle( "Example of JavaFX GridPane, by Basil Bourque" );
        stage.show();
    }


    public static void main ( String[] args )
    {
        launch();
    }
}
应用程序运行的屏幕截图。请注意,左侧和右侧如何分别获得250像素的剩余空间。我们将窗口()设置为1000像素,并将中间部分的宽度固定为500像素。这就剩下500个像素需要分配。左侧和右侧单元格都设置为相同的优先级,因此它们在它们之间均匀地分割空间:每个500/2=250像素

如果用户将窗口宽度缩小到600像素,则左右单元格将各为50像素:600-500=100,100/2=50像素


一般来说,我建议发布代码,而不是试图描述它。例如,这可以代表您的问题:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage stage) throws Exception   {

        Button leftBtn = new Button("Left");
        Button centerBtn = new Button("Center");
        centerBtn.widthProperty().addListener((obs, oldValue,newValue)-> {
                //change the logic as needed
                leftBtn.setPrefWidth(newValue.doubleValue() >= 600 ? 200 : 250);
        });
        centerBtn.setPrefSize(600, 0);
        Button rightBtn = new Button("Right");
        Pane root = new BorderPane(centerBtn, null, rightBtn, null, leftBtn);
        root.setPrefSize(1000, 150);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

public static void main(String[] args) {
        launch(args);
    }
}
这也使帮助变得容易得多。例如,注释中建议的带有
HBox
的解决方案只需要对mre进行细微更改(将操作框添加到中间按钮以更改其宽度):


您可以使用
HBox
使用
HBox
,正如@Sedrick所建议的,在左右元素上设置
hgrow
,或者使用
GridPane
并为三列设置
列约束
,对
BorderPane
进行全面而清晰的解释。有小的打字错误:
按钮按钮右=新按钮(“左”)@c0der谢谢,修复了。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

public class Main extends Application {

    private static final double MIN = 300, MAX = 700, DELTA = 100;
    private Button centerBtn;
    @Override
    public void start(Stage stage) throws Exception   {

        Button leftBtn = new Button("Left");
        HBox.setHgrow(leftBtn, Priority.NEVER);

        centerBtn = new Button("Click to change width");
        HBox.setHgrow(leftBtn, Priority.NEVER);
        centerBtn.widthProperty().addListener((obs, oldValue,newValue)-> {
            //change the logic as needed
            leftBtn.setPrefWidth(newValue.doubleValue() >= 600 ? 200 : 250);
        });
        centerBtn.setPrefSize(600, 0);
        centerBtn.setOnAction(e-> changeCenterBtnWidth());
        Button rightBtn = new Button("Right");
        HBox.setHgrow(rightBtn, Priority.ALWAYS);
        Pane root = new HBox(leftBtn,centerBtn,rightBtn);
        root.setPrefSize(1000, 150);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    private void changeCenterBtnWidth() {
        double newWidth = centerBtn.getWidth() +  DELTA;
        newWidth = newWidth < MAX ? newWidth : MIN;
        centerBtn.setPrefWidth(newWidth);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
    public void start(Stage stage) throws Exception   {

        Button leftBtn = new Button("Left");

        centerBtn = new Button("Click to change width");
        centerBtn.widthProperty().addListener((obs, oldValue,newValue)-> {
            //change the logic as needed
            leftBtn.setPrefWidth(newValue.doubleValue() >= 600 ? 200 : 250);
        });
        centerBtn.setPrefSize(600, 0);
        centerBtn.setOnAction(e-> changeCenterBtnWidth());
        Button rightBtn = new Button("Right");

        GridPane root = new GridPane();
        root.add(leftBtn,0, 0);
        root.add(centerBtn,1, 0);
        root.add(rightBtn,2, 0);
        root.setPrefSize(1000, 150);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
   }