【问题标题】:javafx 8 order children in custom controljavafx 8在自定义控件中订购孩子
【发布时间】:2015-04-03 16:41:11
【问题描述】:

我正在编写一个自定义控件,如果表单中的验证失败,它会在工具提示中显示错误图标和消息。我没有自定义控件的版本如下所示:

<HBox>
    <TextField fx:id="name"></TextField>
    <Label fx:id="error" focusTraversable="false" visible="false">
        <graphic>
            <ImageView fitHeight="24.0" fitWidth="24.0" pickOnBounds="true" preserveRatio="true"/>
        </graphic>
        <tooltip>
            <Tooltip fx:id="errorTooltip"/>
        </tooltip>
    </Label>
</HBox>

结果是这样的:

我创建自定义控件的努力导致了这一点:

<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml">
    <children/>
    <Label fx:id="error" focusTraversable="false" visible="false">
        <graphic>
            <ImageView fitHeight="24.0" fitWidth="24.0" pickOnBounds="true" preserveRatio="true"/>
        </graphic>
        <tooltip>
            <Tooltip fx:id="errorToolTip"/>
        </tooltip>
    </Label>
</fx:root>

这是 fxml 背后的代码:

package control;

[imports omitted for brevity]

@DefaultProperty(value = "children")
public final class ValidatedControl extends HBox implements Initializable {

    @FXML
    private Label error;
    @FXML
    private Tooltip errorToolTip;
    private StringProperty errorToolTipProperty;

    public ValidatedControl() {
        final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ValidatedControl.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public void setErrorToolTip(final String errorToolTip) {
        this.getErrorToolTipProperty().setValue(errorToolTip);
    }

    public String getErrorToolTip() {
        return this.getErrorToolTipProperty().getValueSafe();
    }

    @Override
    public void initialize(final URL location, final ResourceBundle resources) {
        this.errorToolTip.textProperty().bind(this.getErrorToolTipProperty());
        this.error.visibleProperty().bind(this.getErrorToolTipProperty().isNotEmpty());
    }

    public StringProperty getErrorToolTipProperty() {
        if (this.errorToolTipProperty == null) {
            this.errorToolTipProperty = new SimpleStringProperty();
        }
        return this.errorToolTipProperty;
    }
}

我可以在 fxml 中使用控件,但我添加的子组件始终是最后一个子组件,这意味着错误图标显示在其左侧。

我的控件是这样使用的:

<ValidatedControl>
    <TextField>
    </TextField>
</ValidatedControl>

如何让它在右侧显示图标?

【问题讨论】:

  • 有多种方法可以实现这一点。一种方法是将HBox 作为根。其中有另一个HBox 以及您的标签。覆盖getChildren() 并从中返回子HBox 的子代。
  • 在使用自定义控件的第二个版本中,包含 TextField 和错误图标的父节点是什么?你能在你布局 TextField 和错误图标的地方显示 fxml/Java 布局吗?
  • @ItachiUchiha:我试过你的解决方案。在初始化过程中,java 使用 getChildren 来构建 fxmlDOM [原文如此?] 这意味着子 HBox 将是它自己的父级。结尾是 IllegalArgumentException: Children: cycle detected: parent = HBox[id=content], node = HBox[id=content]

标签: java javafx-8 fxml


【解决方案1】:

现在我明白你的问题了。当您在 FXML 中添加 ValidatedControl 时,这可能无法解决您的问题,但是当您以编程方式执行此操作时,请尝试以下操作:

ValidatedControl vc = new ValidatedControl();
TextField textField = new TextField();
vc.getChildren().add(textField);
textField.toBack();

另一种方法是采用 ItachiUchiha 的方式,并在您的 FXML 中添加 Pane 作为第一个孩子。但不要覆盖getChildren() 方法,而是编写一个新方法addNode(Node n) 并将节点添加到窗格中。

忘记我的第一个答案;)

【讨论】:

  • 我试过 ... 版本。这产生的结果与我仅将其用作占位符来告诉编译器/运行时将要添加到控件的子项放在何处的结果相同。对不起,如果我没有正确解释这一点。 Scene Builder 对自定义控件没有多大帮助:-(
  • 我明白了,你能把你的自定义控件的java代码贴出来
  • 我已经添加了后面的代码。顺便说一句,你为什么要把可怜的 Scene Builder 拖进去?这既不是问题的一部分,也不是解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2018-09-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多