2015-04-03 38 views
2

我正在写一个自定义控件,显示错误图标和工具提示中的消息,如果在窗体验证失败。我没有自定义控件的版本是这样的:javafx 8订单儿童在自定义控制

<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> 

结果是这样的:

validation error

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

<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中使用该控件,但是我添加的子组件始终是最后一个子组件,意味着错误图标显示在其左侧。

On the wrong side

我的控制使用这样的:

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

我如何得到它显示在右边的图标?

+0

有多种方法可以实现这一点。一种方法是将“HBox”作为根。在它的内部还有另一个'HBox'和你的标签。覆盖'getChildren()'并从中返回子节点'HBox'的子节点。 – ItachiUchiha 2015-04-03 17:42:10

+0

在使用自定义控件的第二个版本中,包含TextField和错误图标的父节点是什么?您可以在布局TextField和错误图标的位置显示fxml/Java布局吗? – Aaron 2015-04-03 20:59:53

+0

@IchichiUchiha:我试过你的解决方案。在初始化期间,java使用getChildren来构建fxmlDOM [sic?],这意味着子HBox将成为它自己的父类。最后是一个IllegalArgumentException:子项:检测到循环:parent = HBox [id = content],node = HBox [id = content] – 2015-04-05 08:20:40

回答

0

现在我明白你的问题了。当你在FXML添加ValidatedControl这可能不是解决您的问题,但是当你做编程试试这个:

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

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

忘了我的第一个答案;)

+0

我试过 ...版本。这产生了与我仅将它用作占位符的相同结果,以告知编译器/运行库将要添加到控件的子项的位置。对不起,如果我没有正确解释。 的场景Builder是没有太大的自定义控制帮助:-( – 2015-04-03 17:21:57

+0

我明白了,你可以发表你的自定义控件的Java代码,请 – Tobi 2015-04-03 17:32:17

+0

我已经添加的代码后面。 顺便说一句,你为什么拖可怜的场景生成器呢?它既不是问题的一部分,也不是解决方案。 – 2015-04-05 08:36:02