如何使 JavaFX 控件居中

Posted

技术标签:

【中文标题】如何使 JavaFX 控件居中【英文标题】:How do I center JavaFX controls 【发布时间】:2014-11-27 22:49:37 【问题描述】:

更具体地说,为什么我的 JavaFX 控件没有居中?这是两个屏幕截图,第一个是刚开始之后(我将窗口移到了更明显的位置,但还没有调整它的大小),第二个是在调整它的大小以展示我的问题之后。如果您帮助我确保它在首次显示时(在所有 DPI 上)尺寸正确,则可以加分:

方便的是,相关代码包含在这些屏幕截图中。如果你仍然需要它作为文本,你去:

private void initJFXPanel(JFXPanel holder)

    
        
            rootGrid = new GridPane();
            rootGrid.setAlignment(Pos.CENTER);
            rootGrid.setPadding(new Insets(16));
            rootGrid.setHgap(16);
            rootGrid.setVgap(8);
        

        interior = holder.getScene();
        if (interior == null)
            holder.setScene(interior = new Scene(rootGrid));
        interior.setRoot(rootGrid);

    
    
        statusLabel = new Label("Checking for Updates...");
        statusLabel.setAlignment(Pos.CENTER);
        statusLabel.setTextAlignment(TextAlignment.CENTER);
        rootGrid.add(statusLabel, 0, 0);
    
    
        progressBar = new ProgressBar();
        progressBar.setProgress(-1);
        progressBar.setPrefWidth(Constants.MAX_WIN_BOUNDS.width / 5d); // 1/5 the width of the screen
        rootGrid.add(progressBar, 0, 1);
    
    
        downloadButton = new Button("Get it!");
        downloadButton.setAlignment(Pos.CENTER);
        rootGrid.add(downloadButton, 0, 2);
    
    holder.setMinimumSize(new Dimension((int)(rootGrid.getPrefWidth() + .5), (int)(rootGrid.getPrefHeight() + .5)));
    setMinimumSize(holder.getMinimumSize());

【问题讨论】:

【参考方案1】:

调整大小问题

确保您在 JFrame 中添加尺寸

frame.setSize(500, 300);

中心问题

我不确定您是否正在考虑将框架或 GridPane 中的 JavaFX 控件居中,所以我正在为它们添加答案

框架屏幕居中

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, 
                                        dim.height/2-frame.getSize().height/2);

GridPane 儿童中心

你需要添加

GridPane.setHalignment(child, HPos.CENTER);

到您的代码中,删除其余不必要的代码

我编辑了你的代码:


    Label statusLabel = new Label("Checking for Updates...");
    //statusLabel.setAlignment(Pos.CENTER);
    //statusLabel.setTextAlignment(TextAlignment.CENTER);
    rootGrid.add(statusLabel, 0, 0);
    GridPane.setHalignment(statusLabel, HPos.CENTER);


    ProgressBar progressBar = new ProgressBar();
    progressBar.setProgress(-1);
    progressBar.setPrefWidth(400); // 1/5 the width of the screen
    rootGrid.add(progressBar, 0, 1);


    Button downloadButton = new Button("Get it!");
    //downloadButton.setAlignment(Pos.CENTER);
    rootGrid.add(downloadButton, 0, 2);
    GridPane.setHalignment(downloadButton, HPos.CENTER);

结果是

【讨论】:

那么setAlignmentsetTextAlignment 会做什么呢? 关于调整大小问题的解决方案:将其设置为特定的像素宽度不是我想要的。我希望它能够像我拥有的​​那样紧密贴合组件,以防用户有自定义字体,如果高 DPI 播放奇怪等等。进度条宽度也有同样的问题 我注释掉了你做的那些行,并添加了GridPane.setHalignment(rootGrid, HPos.CENTER);,但是文本和按钮仍然是左对齐的 setAlignment - 指定Labeled 中的文本和图形在Labeled 中有空白区域时应如何对齐。 GridPane.setHalignment(statusLabel, HPos.CENTER);GridPane.setHalignment(downloadButton, HPos.CENTER); 是您需要使用的。您需要指定control,而不是GridPane reference【参考方案2】:

解决方案

将控件放置在 VBox(或其他类似的根布局窗格)中,并将set the VBox alignment 置于中心位置。

布局建议

这是我个人对 JavaFX 布局的建议(只是建议,并不适用于所有人,你可以接受或放弃):

您的窗口以及所有控件和布局将自动调整为首选大小。 让内置的布局管理器和布局系统为您执行尽可能多的计算,您只需提供获得结果所需的最少布局提示。 坚持仅使用 JavaFX 或仅使用 Swing 代码,直到您熟悉这两种代码开发风格并且确实需要混合使用它们。 使用 SceneBuilder 工具来玩转不同的布局并熟悉 JavaFX 布局机制。 学习JavaFX layout tutorial。 查看presentation on JavaFX layout。 为了使舞台居中,屏幕调用stage.centerOnScreen()。 考虑使用 Java 8u40(发布时)的内置对话框支持。

Hi-dpi 支持

查看答案:

JavaFX 8 HiDPI Support

您的对话框的基于 FXML 的示例代码

您可以在SceneBuilder中加载以下内容以轻松显示:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="8.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="updateStatus" text="Checking for Updates..." />
      <ProgressBar fx:id="updateProgress" prefWidth="200.0" progress="0.0" />
      <Button fx:id="updateAction" mnemonicParsing="false" text="Get it!" />
   </children>
   <padding>
      <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
   </padding>
</VBox>

【讨论】:

SceneBuilder 的文档说:已弃用。该类已弃用,将在下一版本中删除 我不知道你从哪里得到这些文本。你参考什么文档?能给个链接吗? 在源代码的 JavaDoc 注释中,SceneBuilder 在 JavaFX 8 中不存在。引用:sta.sh/01f8u7ntv30x 和 docs.oracle.com/javase/8/javafx/api/javafx/scene/… 哦,那不是 SceneBuilder,我是说。我的意思是我在答案中链接的 SceneBuilder 图形设计工具,而不是一些已弃用的构建器类。很抱歉造成混淆,这两个完全不同的东西只是碰巧同名。 好的。那么如何随着下载的进行而改变进度条的进度呢?

以上是关于如何使 JavaFX 控件居中的主要内容,如果未能解决你的问题,请参考以下文章

Qt如何设置窗口屏幕居中显示以及设置大小

如何在 Jquery Mobile ListView 控件中使图像垂直居中?

C#如何设置lable控件往上居中

vs里gridview控件创建的数据库表格怎么居中

QT界面怎么使控件随窗口大小变化一直居中显示

C# 窗体,里多个控件布局相对居中