【问题标题】:JavaFX: FXML: How to make the child to extend its size to fit the parent pane?JavaFX:FXML:如何使子级扩展其大小以适应父窗格?
【发布时间】:2014-04-11 20:01:17
【问题描述】:

我已经设法在父 fxml(mainMenu UI)下加载了一个子 fxml(子 UI)。 我创建了一个 ID 为“mainContent”的 AnchorPane。此窗格绑定到 4 个面,并根据舞台变化。

子窗口将被加载到“mainContent”锚窗格中。但是,我无法弄清楚如何让孩子与它的父母“mainContent”一起改变。

我的子 UI 是这样调用的。

@FXML
private void mnuUserLevel_onClick(ActionEvent event) {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("DBedit.fxml"));
    loader.setController(new DBeditEntityUserlevel());

    try {
           Node n = (Node)loader.load();
           mainContent.getChildren().add(n);
    } catch (IOException e){
           System.out.println(e.getMessage());
    }
}

为了进一步说明我的问题,请查看我的快照。红色方块是孩子。黄色方块是 MainMenu 父级的“mainContent”AnchorPane。

【问题讨论】:

  • 这个面板绑定了4个面,根据舞台变化。你是怎么做到的?

标签: java javafx-2 fxml


【解决方案1】:

如果您将AnchorPane 类的static 方法setTopAnchor( child, value )setBottomAnchor( ... )setLeftAnchor( ... )setRightAnchor( ... ) 设置为0.0,则子Node 将被拉伸到父 AnchorPane 的完整扩展。

文档链接:AnchorPane

编辑:在文档链接中,您还可以查看如何在 java 代码中设置这些值。

FXML 示例:

<AnchorPane fx:id="mainContent" ...>
<StackPane fx:id="subPane" AnchorPane.topAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" ></StackPane>
</AnchorPane>

【讨论】:

  • 嗨,Sascha B,添加了一个按钮。例如。 按钮 fx:id="button" layoutX="172.0" layoutY="195.0" onAction="#ingresarLogin" prefHeight="35.0" prefWidth="87.0" text= "Ingresar" /> 是正确的??.........谢谢
  • 这个接受的答案对我不起作用。它水平填充而不是垂直填充。不明白为什么这么简单的概念这么难实现。
  • 这不正确。该用例涉及让父代和祖先Nodes 适应他们的后代Nodes,而不是相反。看我的回答。
【解决方案2】:

如果您有一个Region,它是Node子类,包括AxisChartControlPane(这可能包括您可能想要加载),您可以将子项的大小绑定到父项中的空间,类似于他们所做的here。现在,将来对父级大小的任何调整都将反映在子级中。

Region n = (Region)loader.load();
mainContent.getChildren().add(n);
n.prefWidthProperty().bind(mainContent.widthProperty());
n.prefHeightProperty().bind(mainContent.heightProperty());

【讨论】:

  • 不知道这是否从较新版本的 javafx 开始,但对我来说设置 prefWidth/Height 没有任何作用,我必须使用 minHeight。
【解决方案3】:

看看你的界面结构,我猜你最好使用 BorderPane 作为你的父容器,这个建议不要直接在 BorderPane 容器内使用 AnchorPane 这是我的建议:

->BorderPane-Top = "你的菜单"

->BorderPane-Center = 另一个容器(可能是 SplitPane、另一个 BorderPane 等。但我猜不是 AnchorPane,但你可以尝试)

->BorderPane-Bottom = 另一个容器(可以是带有按钮或标签的信息或通知等的 hbox。)

【讨论】:

    【解决方案4】:

    我认为接受的答案不是正确的。在AnchorPane 中设置锚点就像在the documentation (setBottomAnchor) 中所说的那样:

    如果设置,锚窗格将保持孩子的大小和位置,所以 它的底部总是被锚窗格的那个量所抵消 底部内容边缘。

    但这不是我们想要的。就是安排东西,让孩子和父母的大小一样。

    从我的实验中,要欣赏的重要一点是父母Node 将接受并适应其孩子/孩子的宽度和高度(首选宽度?首选高度?)... 如果你告诉它。换句话说,该机制的工作方向与您可能假设的相反:可以告诉父母适应孩子,而不是孩子适应父母。

    使用包含 AnchorPaneScrollPane 包含 TextAreaHBox,使用 SceneBuilder,这就是问题所要寻找的:

      <HBox prefHeight="100.0" prefWidth="200.0">
         <children>
            <ScrollPane prefHeight="100.0">
              <content>
                <AnchorPane>
                     <children>
                        <TextArea fx:id="logTextArea" prefWidth="800.0">
                        </TextArea>
                     </children>
                  </AnchorPane>
              </content>
            </ScrollPane>
         </children>
      </HBox>
    

    请注意,没有使用锚点,最重要的是ScrollPaneAnchorPane 没有“首选宽度”设置。

    在 SceneBuilder 中,要在此处调整 ScrollPaneAnchorPane 的内容在右侧面板/concertina 中,在“布局:...:”下选择 ScrollPane,然后设置“Pref宽度”到“USE_COMPUTED_AREA”。然后选择AnchorPane 并执行相同操作。最后,选择TextArea 并将其设置为您的选择,例如在我的情况下为 800(像素)。显然,如果您愿意,可以将此设置调整为更复杂的代码。

    然后您将看到TextArea (AnchorPane) 和祖父母Node (ScrollPane) 的父Node 进行调整以适应TextArea

    请注意,HBoxprefWidth 设置随后会被忽略。像HBox 这样的容器的正常工作是容纳其后代,并且只有当您将其maxWidth 设置为与其后代的要求不兼容的东西时,才会应用该约束。

    如果您将孙子 Node 设置为这样的 prefWidth 为 800,我认为在正常情况下,有某种方法可以计算祖父 ScrollPane 的宽度:这将与在所涉及的所有三个组件中设置边框、填充、边距等。请注意 RegioncomputePrefWidth 类中的 protected 方法,用于覆盖子类,这可能很有趣。

    另外,在ScrollPane 的情况下,是否存在垂直和/或水平滚动条,以及它们出现的时间。如果您在TextArea 上将wrapText 设置为true,您可能希望永远不会出现水平滚动条。我的实验似乎表明你还需要将ScrollPanefitToWidthProperty设置为true

    【讨论】:

      【解决方案5】:

      您可以尝试设置 prefWidth。我不知道为什么,但在将 newPane 引用到 AnchorPane 之后,它似乎需要在 SceneBuilder 中设置的 prefWidth。

      Node newPane = FXMLLoader.load(getClass().getResource("view/YourPane.fxml"));
      List<Node> parentChildren = ((Pane)yourAnchorPaneId.getParent()).getChildren();
      parentChildren.set(parentChildren.indexOf(yourAnchorPaneId), newPane);
      yourAnchorPaneId.setPrefWidth(1800); // 1800 just example value for test
      Main.primaryStage.setWidth(500); // 500 example value with which you wishe to start app
      

      【讨论】:

        【解决方案6】:

        方法一:

        // @FXML private AnchorPane pnlContainer;
        
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Demo.fxml"));
        
        Node _node = loader.load();
        
        _node.prefWidth(pnlContainer.widthProperty().doubleValue());
        _node.prefHeight(pnlContainer.heightProperty().doubleValue());
        
        // container child clear
        pnlContainer.getChildren().clear();
        
        // new container add
        pnlContainer.getChildren().add(_node);
        

        替代方法;

        FXMLLoader loader = new FXMLLoader(getClass().getResource("Demo.fxml"));
        
        Node _node = loader.load();
        
        AnchorPane.setTopAnchor(_node, 0.0);
        AnchorPane.setRightAnchor(_node, 0.0);
        AnchorPane.setLeftAnchor(_node, 0.0);
        AnchorPane.setBottomAnchor(_node, 0.0);
        
        // container child clear
        pnlContainer.getChildren().clear();
        
        // new container add
        pnlContainer.getChildren().add(_node);
        

        方法2详细链接:JavaFX Panel inside Panel auto resizing

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-16
          • 2021-12-10
          • 2010-11-16
          • 1970-01-01
          • 2020-08-27
          • 1970-01-01
          • 2022-08-18
          • 1970-01-01
          相关资源
          最近更新 更多