如何使 JavaFX 窗格适应其内容的大小?

Posted

技术标签:

【中文标题】如何使 JavaFX 窗格适应其内容的大小?【英文标题】:How do I fit a JavaFX Pane to the size of its contents? 【发布时间】:2020-07-30 23:58:16 【问题描述】:

在 JavaFX 中,我看到了很多关于如何使子组件扩展其大小以适应父窗格的示例。但我看不到如何缩小父窗格以适应其子内容的大小。

在下面的示例中,我创建了一个场景大小为 500x500 像素的舞台。在该场景中是一个 VBox,它有一个孩子,一个标签。

我希望 VBox 窗格是标签的大小,而不是整个舞台的大小。 (在更复杂的应用程序中,我将 VBox 设置为可拖动的窗格,因此我希望它足够大以容纳其内容)。

我该怎么做?

import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Sample  extends Application 
  public static void main(String[] args) 
    launch(args);
  

  @Override
  public void start(Stage primaryStage) throws Exception 
    VBox vbox = new VBox();
    vbox.setStyle("-fx-background-color: #efecc2");
    vbox.setPrefSize(100, 100);
    Label label = new Label("Label");
    label.setStyle("-fx-background-color: lightcyan");
    vbox.getChildren().add(label);
    Scene scene = new Scene(vbox, 500, 300);
    primaryStage.setScene(scene);
    primaryStage.show();
  

如下图所示,标签(蓝色背景)很小,但 VBox(黄色背景)填满了整个窗口。我将 VBox 的首选大小设置为 100,100 似乎并不重要:它仍然会填满整个 500 x 300 像素的场景。

如何告诉 VBox 仅与其中的 Label 一样大? (或者,当我在其中添加 3 个东西时,要和它们一样大?)

【问题讨论】:

这能回答你的问题吗? JavaFX - Bind stage size to the root node's preferred size 您将场景设置为 500 x 300。如果不是 vbox,应该填充什么? 场景的根始终是场景的大小。如果您希望VBox 小于场景,请将VBox 放在另一个容器中,并将另一个容器设置为根。 谢谢。是的,看起来我过于简化了我的例子。正如下面的答案所示,如果我将 VBox 放在 AnchorPane 中,那么它会按我希望的那样工作,即 VBox 适合其子项所需的大小。 事实证明,我的问题是因为我将我的 VBox 包装在 StackPane 中,它显然试图让其子级扩展到其完整大小,而不是 AnchorPane,后者不会。 【参考方案1】:

这里的第一个问题是场景的根对象。它将始终与场景大小相同。所以你需要添加父Pane作为根元素,然后添加VBox

第二个问题是Pane。有些元素会影响孩子的大小(BorderPaneStackPane),有些则不会(PaneAnchorPane)。所以你需要选择合适的父母。

这是一个简单的例子:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Sample extends Application 

    @Override
    public void start(Stage primaryStage) 
        Label label = new Label("Label");
        label.setStyle("-fx-background-color: lightcyan");

        VBox vBox = new VBox();
        vBox.setStyle("-fx-background-color: #efecc2");
        vBox.getChildren().add(label);
        AnchorPane root = new AnchorPane();

        root.getChildren().add(vBox);
        Scene scene = new Scene(root, 500, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    


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

【讨论】:

谢谢。这确实像我希望的那样工作。事实证明,如果包含窗格是 AnchorPane,它会按照我的希望工作;但如果它是一个 StackPane(就像我之前在我的项目中使用的那样),那么它不是。 原始文档说如下:“堆栈窗格将尝试调整每个孩子的大小以填充其内容区域。如果无法调整孩子的大小以填充堆栈窗格(因为它无法调整大小或其最大尺寸阻止它)然后它将使用对齐属性在区域内对齐,该属性默认为 Pos.CENTER。”这会切断您需要的功能。

以上是关于如何使 JavaFX 窗格适应其内容的大小?的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 获取窗格的首选大小

如果节点超出 javafx 的边界,是不是可以自动调整窗格大小

如何使用 JavaFX 垂直堆叠下载窗格?

如何在javafx中用鼠标绘制选定的网格窗格范围

java里怎样使背景图片适应窗口大小?

如何调整 UITableViewCell 的大小以适应其内容?