java - fxml 中定义的自定义控件 - 如何获取父 ID?

标签 java javafx custom-controls fxml

我有一个定义如下的自定义控件:

<fx:root type="javafx.scene.Group" xmlns:fx="http://javafx.com/fxml" fx:controller="com.theCorp.theTool.controllers.LimitsController">
  <Group id="Group" layoutX="0.0" layoutY="0.0">
    <children>
        <Group id="Count" layoutX="0.0" layoutY="20.0">
            <children>
                <Label layoutX="0.0" layoutY="3.0" prefWidth="59.0" text="Count" />
                <TextField id="Count.Min" fx:id="countMin" layoutX="59.0" layoutY="0.0" prefWidth="132.0" promptText="Min" />
                <TextField id="Count.Max" fx:id="countMax" layoutX="191.0" layoutY="0.0" prefWidth="132.0" promptText="Max" />
            </children>
        </Group>
        <Button id="SaveButton" fx:id="saveButton" layoutX="12.0" layoutY="85.0" mnemonicParsing="false" onAction="#save" text="Save" />
    </children>
  </Group>
</fx:root>

我有一个 Control 类,它以通常的方式加载它:

public class LimitsControl extends Group {
  private static final String fxmlFileName = "Limits.fxml";

  public LimitsControl() {
    super();
    URL fxml = getClass().getResource(fxmlFileName);
    if (fxml == null) {
      fxml = getClass().getResource("/fxml/" + fxmlFileName);
    }
    // Create the loader.
    FXMLLoader loader = new FXMLLoader(fxml);
    loader.setRoot(this);
    try {
      // Load the fxml.
      loader.load();
      // Pull back the controller.
      LimitsController controller = loader.getController();
      // Tell it about me.
      controller.setControl(this);
    } catch (IOException exception) {
      throw new RuntimeException(exception);
    }
  }

}

我有一个 Controller 类,看起来有点像这样:

public class LimitsController implements Initializable {
  // Control.
  private LimitsControl control;

  @FXML
  private TextField countMin;
  @FXML
  private TextField countMax;
  @FXML
  private Button saveButton;

  /**
   * Initializes the controller class.
   *
   * @param url
   * @param rb
   */
  @Override
  public void initialize(URL url, ResourceBundle rb) {
    log.info("Loading: " + url + " rb=" + rb+" control="+control);
    // Make the save button call my save.
    saveButton.setOnAction((ActionEvent e) -> {
      save(e);
    });
  }


  public void setControl(LimitsControl control) {
    log.info("Control="+control);
    this.control = control;
  }

  @FXML
  private void save(ActionEvent event) {
    // What is the ID of me?
    Parent myGroup = saveButton.getParent();
    // Pull the id of the control that enclosed my group.
    String myId = myGroup.getParent().getId();
    log.info("Saving: " + myId);
  }

}

我将这些控件插入场景中的多个位置,每次都使用不同的 id,如下所示:

        <TitledPane fx:id="Today" animated="false" text="Today">
          <tooltip>
            <Tooltip text="Parameters will only be used for today." />
          </tooltip>
          <content>
            <LimitsControl id="Today.Limits" />
          </content>
        </TitledPane>

我的问题是,这些控件必须由需要控件的 id 的数据填充,但当 Controller 初始化时,它没有父级。

按下保存按钮时,id 可用 - 请参阅 save 方法爬上父树以收集控件的 id。遗憾的是父级在初始化时为空。

当父 ID 可用时,如何正确初始化字段?或者我做错了,有一个正确的方法?

最佳答案

首先,注入(inject)控件,而不是使用设置方法耦合所有内容:

<fx:root type="javafx.scene.Group" xmlns:fx="http://javafx.com/fxml" fx:controller="com.theCorp.theTool.controllers.LimitsController" fx:id="control">

  // Control.
  @FXML
  private LimitsControl control;

如果我理解正确的话,您尝试获取的 id 是 LimitsControl 本身的 id。要使其“尽早”可用,请在 LimitsControl 的构造函数中定义一个参数并在那里设置 id:

  public LimitsControl(String id) {
    super();
    setId(id);
        // code as before...
      }

现在,因为您不再有默认构造函数,所以您需要为 LimitsControl 创建一个构建器:

public class LimitsControlBuilder {
    private String id ;
    private LimitsControlBuilder() {
        this.id = "" ;
    }
    public static LimitsControlBuilder create() {
        return new LimitsControlBuilder();
    }
    public LimitsControlBuilder id(String id) {
        this.id = id ;
        return this ;
    }

    public LimitsControl build() {
        return new LimitsControl(id);
    }
}

现在你可以做

<LimitsControl id="Today.Limits" />

并且一旦调用构造函数就会设置它。

您当然可以在此处创建自己的属性,而不是使用 id,这可能是 fxml 将信息传递到自定义控件实例而不是使用 css id 更合适的方式。

关于java - fxml 中定义的自定义控件 - 如何获取父 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23017604/

相关文章:

java - 二叉树和 NullPointerException

cocoa - 在 OS X 上的 Cocoa 中实现自定义 NSView

wpf - WPF中的自定义按钮模板

WebView 中 JavaFX 滚动条交叉点的颜色

c# - dll 中的 WPF 自定义控件

java - 在流中使用 Java 8 foreach 循环移至下一项

java - 检查 EasyMock 模拟是否处于重播模式/状态

java - 打印导致异常错误的特定字符

gradle - XMLStreamException : ParseError at [row, col] 打开新阶段时(新窗口)

maven - 在 ubuntu 上运行 javafx 跨平台 .jar