选项卡中的 JavaFX 布局

JavaFX layouts in a Tab

我正在尝试创建一个完全由填满屏幕的 TabPane 组成的屏幕,并且选项卡的内容填满了选项卡。到目前为止,这是我所拥有的,它创建了一个填满屏幕的选项卡,但是当我将内容添加到选项卡时,除了计算和设置 width/height 之外,我没有尝试任何其他操作。我可以编写代码来做到这一点,但我坚信应该完全没有必要,因为布局管理器的全部意义在于根据一组规则很好地计算布局...

Java外汇应用:

public class TestFX extends Application
{
    @Override
    public void start(Stage stage) throws Exception
    {
        TabPane tPane = new TabPane();
        tPane.setStyle("-fx-background-color : pink;");
        tPane.getStyleClass().add("floating"); // Found this tip on SO already, if you remove it the tab won't fill the screen anymore.
        tPane.getTabs().add(new Tab("Test Tab", new TestTabFX()));
        
        Rectangle2D scrnRect = Screen.getPrimary().getVisualBounds();
        stage.setX(scrnRect.getMinX() + scrnRect.getWidth() / 2);
        stage.setY(scrnRect.getMinY());
        stage.setWidth(scrnRect.getWidth() / 2);
        stage.setHeight(scrnRect.getHeight());

        Scene scene = new Scene(tPane);
      stage.setTitle("Test Tabs");  
      stage.setScene(scene); 
      stage.show();
    }
    
    public static void main(String args[])
    {
        launch(args);
    }
}

Java将成为选项卡内容的 FX 组件:

public class TestTabFX extends Group
{
    public TestTabFX()
    {
        TextField serverURL = new TextField("http://localhost:9090");
        Button startServer = new Button("Start");
        Button stopServer = new Button("Stop");
        Button testServer = new Button("Test");
        TextArea serverDetails = new TextArea();
        
        HBox top = new HBox(10d, new Label("Server URL:"), serverURL, startServer, stopServer, testServer); 
        top.setStyle("-fx-background-color : red;");
        
        GridPane tab = new GridPane();
        tab.setStyle("-fx-background-color : green;");
        tab.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(7D))));
        tab.addRow(0, top);
        tab.addRow(1, serverDetails);
        
        this.getChildren().add(tab);
    }
}

PS 我是 JavaFX 的新手,但多年来一直使用常规 Java ,当我考虑使用普通的方法是多么容易时,这只会增加我的挫败感Java。我想要的是要居中的 TextField 和 Buttons 的顶部集合以及要填充屏幕的 TextArea。如果屏幕也调整大小,两者都应适当调整大小。

如有任何帮助,我们将不胜感激。

正如 Kleopatra 所提到的,布局的选择造成了差异。在您的情况下,您希望内容用选项卡中可用的 space 填充。布局 StackPane 具有扩展到其父节点的可用 space 的默认行为。 供您参考,选项卡内容区域已经是一个 StackPane,它扩展到完整可用 space。所以这是您选择的布局和适当的属性将允许您的内容填充 space.

供您参考,我在下面提到了一些布局。以下所有布局的行为方式相同。请查看我们设置的适当属性,以便按照我们的意愿行事。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class TestFX extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        TabPane tPane = new TabPane();
        tPane.setStyle("-fx-background-color : pink;");
        tPane.getStyleClass().add("floating"); // Found this tip on SO already, if you remove it the tab won't fill the screen anymore.
        tPane.getTabs().add(new Tab("Test Tab1", new TestTabFX1()));
        tPane.getTabs().add(new Tab("Test Tab2", new TestTabFX2()));
        tPane.getTabs().add(new Tab("Test Tab3", new TestTabFX3()));

        Rectangle2D scrnRect = Screen.getPrimary().getVisualBounds();
        stage.setX(scrnRect.getMinX() + scrnRect.getWidth() / 2);
        stage.setY(scrnRect.getMinY());
        stage.setWidth(scrnRect.getWidth() / 2);
        stage.setHeight(scrnRect.getHeight());

        Scene scene = new Scene(tPane);
        stage.setTitle("Test Tabs");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String args[]) {
        launch(args);
    }

    // EXTENDING STACKPANE : Has the default feature to fill the available space.
    class TestTabFX1 extends StackPane {
        public TestTabFX1() {
            TextField serverURL = new TextField("http://localhost:9090");
            Button startServer = new Button("Start");
            Button stopServer = new Button("Stop");
            Button testServer = new Button("Test");
            TextArea serverDetails = new TextArea();
            VBox.setVgrow(serverDetails, Priority.ALWAYS);

            HBox top = new HBox(10d, new Label("Server URL:"), serverURL, startServer, stopServer, testServer);
            top.setAlignment(Pos.CENTER);

            VBox tab = new VBox(top, serverDetails);
            tab.setSpacing(10);
            tab.setPadding(new Insets(10));
            getChildren().addAll(tab);
        }
    }

    // EXTENDING VBOX : By using VGrow, you can make the layout to fill the available space
    class TestTabFX2 extends VBox {
        public TestTabFX2() {
            TextField serverURL = new TextField("http://localhost:9090");
            Button startServer = new Button("Start");
            Button stopServer = new Button("Stop");
            Button testServer = new Button("Test");
            TextArea serverDetails = new TextArea();
            VBox.setVgrow(serverDetails, Priority.ALWAYS);

            HBox top = new HBox(10d, new Label("Server URL:"), serverURL, startServer, stopServer, testServer);
            top.setAlignment(Pos.CENTER);

            setSpacing(10);
            setPadding(new Insets(10));
            getChildren().addAll(top, serverDetails);
        }
    }

    // EXTENDING GRIDPANE : By using column/row constraints, you can make the layout to fill the available space.
    class TestTabFX3 extends GridPane {
        public TestTabFX3() {
            TextField serverURL = new TextField("http://localhost:9090");
            Button startServer = new Button("Start");
            Button stopServer = new Button("Stop");
            Button testServer = new Button("Test");
            TextArea serverDetails = new TextArea();

            HBox top = new HBox(10d, new Label("Server URL:"), serverURL, startServer, stopServer, testServer);
            top.setAlignment(Pos.CENTER);

            addRow(0, top);
            addRow(1,serverDetails);

            ColumnConstraints cc = new ColumnConstraints();
            cc.setHgrow(Priority.ALWAYS);
            cc.setFillWidth(true);
            getColumnConstraints().add(cc);

            RowConstraints rc1 = new RowConstraints();
            RowConstraints rc2 = new RowConstraints();
            rc2.setVgrow(Priority.ALWAYS);
            rc2.setFillHeight(true);
            getRowConstraints().addAll(rc1,rc2);

            setVgap(10);
            setPadding(new Insets(10));
        }
    }
}