簡體   English   中英

組件構造函數參數fxml javafx

[英]Component constructor arguments 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"/>

所以我的問題是,如果我使用我的組件啟動程序,如何更改標簽'Titel'的文本? 標題應該像修復:id。

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

概觀

盡管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%知道這將按預期運作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM