组件构造函数参数fxml javafx

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组件构造函数参数fxml javafx相关的知识,希望对你有一定的参考价值。

首先,我给你我的代码。

零件

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

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

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

就像你看到我的Component询问将放置在Label中的String一样,问题是如果你创建这样的对象,你就不能在fxml文件中传递参数:

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

所以我的问题是如果我使用我的组件启动程序,如何更改标题'Title'的文本?标题应该像fix:id。

答案

概观

尽管OP已经选择了最佳答案,但从评论中可能会出现一些混乱,所选答案并没有完全回答他们的问题并且缺少信息,因此我发布了我认为完整/完整的答案:

在JavaFX中创建自定义组件并且您希望在创建组件时为组件提供一个或多个默认值时,您不能简单地将参数添加到默认构造函数中,因为当JavaFX执行FXML加载时它将在幕后使用事情。

为了处理这个难题,我们只有在使用@NamedArg(“参数名称”)注释注释时才能向默认构造函数添加参数。这允许在以编程方式或通过FXML构造时,在运行时为自定义组件提供值。

细节和例子

自定义组件控制器构造函数

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

在幕后,JavaFX认识到组件的构造函数现在有一个用@NamedArg注释的参数,这将反映在当前使用组件的任何地方。查找或创建FXML文档并将您的组件放入文本中。然后,您应该能够从FXML设置命名参数,并且IDE的intellisense也应该支持它。

通过FXML将值添加到组件

<MyCustomComponent foo="myStringValue"/>

您可以以编程方式设置参数:

MyCustomComponent myComp = new MyCustomComponent("myStringValue");

现在,对OP问题的当前选择答案没有提到这一点,但据我所知,还有一个步骤你必须要处理,否则这些都不会起作用。控制器类必须具有与命名参数匹配的属性。我认为这是在幕后初始化FXML所必需的,但我可能是错的。在大多数情况下,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;
}

结论

我想在这里添加这个,因为之前的答案确实回答了问题,但并不完全,虽然看起来OP确实能够找出问题,但答案却没有提及OP实现/改变了什么以使其工作,因为在首先它没有解决问题。我100%知道这将按预期运作。

另一答案

在JavaFX 8中,您可以通过使用@NamedArg(...)注释构造函数参数来完成此操作:

public class Schuiver extends VBox{

    private final SchuiverCompanion companion;

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

        // ...
    }

}

然后你可以在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>

以上是关于组件构造函数参数fxml javafx的主要内容,如果未能解决你的问题,请参考以下文章

在 JavaFX FXML 控制器中实现构造函数

Javafx只初始化一次控制器构造函数?

通过代码关闭 fxml 窗口,javafx

JavaFx,@FXML 的问题

JavaFX / FXML 将 ChoiceBox 添加到根窗格

JavaFX 8 - 每个选项卡带有单独的 FXML 和控制器的选项卡和选项卡