【问题标题】:JavaFX Centering VBox inside GridPaneGridPane 中的 JavaFX 居中 VBox
【发布时间】:2016-02-02 17:21:26
【问题描述】:

非常感谢您对我的问题的帮助。

我正在使用 JavaFX 和 NetBeans IDE。 我正在为桌面客户端制作一个非常简单的启动窗口。 窗口当前看起来像这个图像。

当前外观:

想要的外观(用油漆编辑):

换句话说,我希望按钮是:

  1. 在“欢迎”文本下方居中
  2. 保持当前宽度

我目前的设置是:

我有一个 GridPane 作为根。不确定为什么 JavaFX 选择使用 (col,row),但这就是我将在下面表示我的设置的方式:

  • @GridPane(0,0) -> '欢迎'文本
  • @GridPane(0,1) -> VBox(此 VBox 包含上图所示的 2 个按钮)

相关代码(或我认为相关的,如有错误请指正)如下:

//adds GridPane to Scene
GridPane grid = new GridPane();
RowConstraints row1 = new RowConstraints();
row1.setPercentHeight(25);
grid.getRowConstraints().add(row1);
grid.setAlignment(Pos.CENTER);
Scene scene = new Scene(grid, 400, 300,Color.WHITESMOKE);

//Create welcome message and add it to grid, and align it to the center
Text sceneTitle = new Text("Welcome");
grid.add(sceneTitle,0,0);
GridPane.setHalignment(sceneTitle,HPos.CENTER);

//Create buttons and fix their widths
Button newBtn = new Button("Create New Project");
Button loadBtn = new Button("Load Existing Project");
newBtn.setMaxWidth(150);
loadBtn.setMaxWidth(150);

//Create a VBox, add children to it, and then add it to the grid
VBox vBtns = new VBox();
vBtns.setSpacing(5);
vBtns.getChildren().addAll(newBtn,loadBtn);
grid.add(vBtns,0,1);

我尝试了很多不同的东西.. 提到一些更“合乎逻辑”的东西:

//1. Center the VBox within its current GridPane cell
GridPane.setHalignment(vBtns,HPos.CENTER);

//2. Center the buttons within the VBox 
newBtn.setAlignment(Pos.CENTER);
loadBtn.setAlignment(Pos.CENTER);

我从来都不擅长 GUI 编程。当一件本应如此简单的事情需要这么长时间才能弄清楚时,这是非常令人沮丧的。 有没有开发人员可以帮助我找到解决方案?

【问题讨论】:

  • 不要试图在 GridPane 中与之抗争。相反,将你的东西包装在另一个 VBox 中,使其宽度为 100%,并使其内容居中。然后你的内部内容将位于该 VBox 的中心。 JavaFX/FXML 就是将元素嵌套在其他元素中以获得您想要的样式。 (另外,您应该真正检查 FXML 而不是手动编写此 gui,JavaFX 确实从 FXML 中受益,然后您可以使用 SceneBuilder 拖放您的 GUI 元素并将它们全部对齐,等等。)。
  • 或者,只需将所有三个内容放在一个 VBox 中。或单个GridPane。但是这里根本不需要两个布局窗格。
  • @SnakeDoc 嗨!是的,我已经安装了 Scene Builder 插件。我对嵌套元素没有按照我想要的方式居中感到不满意,所以我回到了代码。
  • @HenryLin 使用 FXML 而不是手动编写所有 UI 将使事情更“易于管理”,尽管显然存在学习曲线。 SceneBuilder 可以做所有你可以用代码做的事情,所以如果它没有按照你想要的方式工作,那可能是因为你没有勾选正确的选项或其他东西。这绝对值得学习,并且会为您节省大量时间。
  • @James_D 我之前尝试将它们全部放入一个 VBox 中,但我切换回了 GridPane,因为我想添加一个小图标以显示在“欢迎”文本的左侧。不幸的是,我不得不把它拿出来,因为我无法让包含 ImageView 的文本正确居中。

标签: java javafx


【解决方案1】:

要使用当前设置修复它,您只需要:

vBtns.setAlignment(Pos.CENTER);

但是,这似乎过于复杂。为什么不干呢

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class LayoutTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane grid = new GridPane();
        RowConstraints row1 = new RowConstraints();
        row1.setPercentHeight(25);
        grid.getRowConstraints().add(row1);

        ColumnConstraints colConstraints = new ColumnConstraints();
        colConstraints.setHalignment(HPos.CENTER);
        grid.getColumnConstraints().add(colConstraints);

        grid.setAlignment(Pos.CENTER);
        Scene scene = new Scene(grid, 400, 300,Color.WHITESMOKE);

        //Create welcome message and add it to grid, and align it to the center
        Text sceneTitle = new Text("Welcome");
        sceneTitle.setStyle("-fx-font-size:48;");
        grid.add(sceneTitle,0,0);

        //Create buttons and fix their widths
        Button newBtn = new Button("Create New Project");
        Button loadBtn = new Button("Load Existing Project");
        newBtn.setMaxWidth(150);
        loadBtn.setMaxWidth(150);

        grid.add(newBtn, 0, 1);

        GridPane.setMargin(loadBtn, new Insets(5, 0, 5, 0));
        grid.add(loadBtn, 0, 2);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

【讨论】:

  • 我将按钮包装到一个 VBox 中,因为我只想指定它们两者之间的间隙。我最初尝试按照您的建议进行操作,但按钮粘在一起并且指定“grid.setVgap”不起作用,因为它会在文本和按钮之间放置一个难看的空间。
  • 您可以通过GridPane.setMargin(node, insets) 更精确地控制网格中任意节点任意一侧的空间量;或者您可以使用行约束来更好地控制每行的相对高度以及单元格内容的定位。
  • 因为 stackoverflow 不允许私人消息,而且您似乎是最活跃的 JavaFX stackoverflow 响应者之一。我希望我能从这里问您一个问题:您是亲自手动编写代码、编辑 FXML 还是使用场景构建器?我在这篇文章中为那个愚蠢的页面手动编写了代码,现在我正在尝试使用场景生成器来重现它。当您第一次开始学习这个框架时,您是否遵循了类似的过程?
  • 我是通过在 Java 代码中“手动”完成它来学习的;我发现 Eclipse 的代码完成比在 GUI 构建器中找到相关控件更能向我展示所有选项。但是我老了-school(或者可能只是旧的)。对于现在的实际开发,主要是 FXML,一些是手动的,一些布局我将在 SceneBuilder 中构建(有时我需要随后编辑 SceneBuilder 不支持的功能)。
猜你喜欢
  • 2014-12-14
  • 1970-01-01
  • 2014-11-09
  • 2021-05-04
  • 2012-09-30
  • 2017-03-21
  • 2017-02-11
  • 2021-03-17
相关资源
最近更新 更多