创建自定义控件以包含其他自定义控件

时间:2017-01-12 08:40:41

标签: java javafx javafx-2 javafx-8 custom-controls

我正在创建一个应该引导用户完成步骤的应用,如下面的屏幕截图所示:

enter image description here

  <Step fx:id="selectConnectionStep" source="SelectConnection" stepLabel="Step 1 : Select a Connection" />
  <Step fx:id="selectSObjectStep" source="SelectSObject" stepLabel="Step 2 : Select an SObject" />
  <Step fx:id="selectActionStep" stepLabel="Step 3 : Select an Action">
      <VBox GridPane.columnSpan="2" GridPane.rowIndex="1">
          <Action actionLabel="test" onAction="#test" />
          <GridPane.margin>
              <Insets bottom="15.0" left="15.0" right="10.0" top="10.0" />
          </GridPane.margin>
      </VBox>
  </Step>

在应用程序中,我有更多的场景配置为以这种方式工作,所以我想以一种易于维护的方式进行设计。

我创建了自定义控件,名为&#34; Step&#34; (基本上扩展 GridPane

每个&#34;步骤&#34;有title,loadingIcon和内部组件。

在前两个步骤中,我使用&#39;来源&#39;加载内部组件。我创建的属性。我只是给出了Component的FXML文件的名称。在代码中我只加载FXML并将组件放在正确的位置。 但是,正如在第3步中可以看到的,我尝试将内部组件填充为Step子级。可以看出这是有效的,但我希望Step将其子项注入正确的位置,而不指定将其放在网格中的任何细节。

即。

<Step fx:id="selectActionStep" stepLabel="Step 3 : Select an Action">
      <VBox>
          <Action actionLabel="test" onAction="#test" />
      </VBox>
</Step>

如果我没有指定任何细节,该组件将进入左上角的GridPane内。

问题是自定义控件如何操纵其FXML子元素? 我可以扩展GridPane吗?

谢谢:)

2 个答案:

答案 0 :(得分:2)

执行此操作的最佳方法是在添加“标准”元素后向子列表添加ListChangeListener,例如

private static final Insets MARGIN = new Insets(10, 10, 15, 15);

...

// add standard elements...

getChildren().addListener((ListChangeListener.Change<? extends Node> c) -> {
    while (c.next()) {
        if (c.wasAdded()) {
             for (Node n : c.getAddedSubList()) {
                 GridPane.setColumnSpan(2);
                 GridPane.setRowIndex(1);
                 GridPane.setMargin(MARGIN);
             }
        } 
    }
});

答案 1 :(得分:1)

我也发现这篇文章引入了另一种解决方案:

How to add node to another node's child in FXML?