简体   繁体   English

组件构造函数参数fxml javafx

[英]Component constructor arguments fxml javafx

First, I give you the code I have. 首先,我给你我的代码。

COMPONENT 零件

public class Schuiver extends VBox{

private final SchuiverCompanion companion;

public Schuiver(String text) {
    try {
        FXMLLoader loader = new FXMLLoader(
                Schuiver.class.getResource("nuleenschuiver.fxml"));
        loader.setRoot(this);
        this.companion = new SchuiverCompanion();
        loader.setController(companion);
        companion.setText(text);

        loader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }

  }
}

COMPONENTCONTROLLER COMPONENTCONTROLLER

public class SchuiverCompanion {

   public TextField kleurveld;
   public Label titel;
   public Slider schuiver;

   public void initialize() {
        kleurveld.textProperty().bindBidirectional(schuiver.valueProperty(),
            new NumberStringConverter());
   }

   public void setText(String text){
       titel.setText(text);
   }

}

COMPONENTFXML COMPONENTFXML

 <?xml version="1.0" encoding="UTF-8"?>

 <?import javafx.geometry.*?>
 <?import javafx.scene.control.*?>
 <?import java.lang.*?>
 <?import javafx.scene.layout.*?>

 <fx:root fx:id="vbox" minHeight="-1.0" prefHeight="-1.0" prefWidth="-1.0" spacing="5.0" type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kleurenkiezer.SchuiverCompanion">
  <children>
  <Label fx:id="titel" alignment="TOP_LEFT" text="Hier een titel" />
  <HBox prefHeight="44.0" prefWidth="299.0">
     <children>
        <Slider fx:id="schuiver" prefHeight="14.0" prefWidth="215.0" />
        <TextField fx:id="kleurveld" prefHeight="25.0" prefWidth="76.0" />
     </children>
  </HBox>
  </children>
  </fx:root>

Like you see my Component asks a String that will be placed in a Label, the problem is that you can't pass arguments in an fxml file if you create the objects like this: 就像你看到我的Component询问将放置在Label中的String一样,问题是如果你创建这样的对象,你就不能在fxml文件中传递参数:

 <Schuiver  fx:id="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
 <Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1"/>

So my question is how can I change the text of the label 'Titel' if I start a program using my Component? 所以我的问题是,如果我使用我的组件启动程序,如何更改标签'Titel'的文本? The titel should be like the fix:id. 标题应该像修复:id。

In JavaFX 8 you can do this by annotating the constructor argument with @NamedArg(...) : 在JavaFX 8中,您可以通过使用@NamedArg(...)注释构造函数参数来完成此操作:

public class Schuiver extends VBox{

    private final SchuiverCompanion companion;

    public Schuiver(@NamedArg("text") String text) {

        // ...
    }

}

And then you can use the parameter in FXML: 然后你可以在FXML中使用参数:

<Schuiver  fx:id="red" text="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1">
    <text>
        <String fx:value="blue" />
    </text>
</Schuiver>

Overview 概观

Although OP already selected an answer as best, from the comments it appears that there was some confusion and the selected answer did not outright answer their question and is missing information so I am posting what I believe to be the full/complete answer: 尽管OP已经选择了最佳答案,但从评论中可能会出现一些混乱,所选答案并没有完全回答他们的问题并且缺少信息,因此我发布了我认为完整/完整的答案:

When creating a custom component in JavaFX and you'd like to provide one or more default values to the component upon it's creation, you cannot simply add a parameter to the default constructor as it is used behind the scenes when JavaFX is doing it's FXML loading thing. 在JavaFX中创建自定义组件并且您希望在创建组件时为组件提供一个或多个默认值时,您不能简单地将参数添加到默认构造函数中,因为当JavaFX执行FXML加载时它将在幕后使用事情。

To handle this conundrum we're provided with the ability to add parameters to the default constructor only if they are annotated with the @NamedArg("name of parameter here") annotation. 为了处理这个难题,我们只有在使用@NamedArg(“参数名称”)注释注释时才能向默认构造函数添加参数。 This allows one to provide custom components with values at run-time when they are constructed either programmatically or through FXML. 这允许在以编程方式或通过FXML构造时,在运行时为自定义组件提供值。

Details and Examples 细节和例子

Custom Component Controller Constructor 自定义组件控制器构造函数

public MyCustomComponent(@NamedArg("foo") String foo) { }

Behind the scenes, JavaFX recognizes that the component's constructor now has a parameter annotated with @NamedArg and this will be reflected wherever the component is currently being used. 在幕后,JavaFX认识到组件的构造函数现在有一个用@NamedArg注释的参数,这将反映在当前使用组件的任何地方。 Find or create a FXML document and put your component into the text. 查找或创建FXML文档并将您的组件放入文本中。 You should then be able to set the named argument from the FXML and your IDE's intellisense should support this as well. 然后,您应该能够从FXML设置命名参数,并且IDE的intellisense也应该支持它。

Adding the value to the component via FXML 通过FXML将值添加到组件

<MyCustomComponent foo="myStringValue"/>

You can set the parameter programmatically: 您可以以编程方式设置参数:

MyCustomComponent myComp = new MyCustomComponent("myStringValue");

Now, the current selected answer to OP's question does not mention this, but as far as I know, there is one more step you have to take care of or none of this will work. 现在,对OP问题的当前选择答案没有提到这一点,但据我所知,还有一个步骤你必须要处理,否则这些都不会起作用。 The controller class must have a property that matches the named argument. 控制器类必须具有与命名参数匹配的属性。 I believe this is required for initializing the FXML behind the scenes but I could be wrong. 我认为这是在幕后初始化FXML所必需的,但我可能是错的。 Properties in Java, for the most part, look like so: 在大多数情况下,Java中的属性如下所示:

private StringProperty foo = new SimpleStringProperty();

public String getFoo()
{
  return foo.get();
}

public void setFoo(String value)
{
  this.foo.set(value);
}

public StringProperty fooProperty()
{
  return foo;
}

Conclusion 结论

I wanted to add this here because the previous answer does answer the question but not completely and while it does appear that OP was able to figure out the issue, the answer makes no mention of what OP realized/changed to get it to work because at first it did not solve the issue. 我想在这里添加这个,因为之前的答案确实回答了问题,但并不完全,虽然看起来OP确实能够找出问题,但答案却没有提及OP实现/改变了什么以使其工作,因为在首先它没有解决问题。 I know 100% that this will function as intended. 我100%知道这将按预期运作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM