[英]Javafx: Reusable collections using FXML
我想將單個集合綁定到 FXML 中的多個 ChoiceBox。 但是,我知道如何使用的唯一方法是:
<ChoiceBox fx:id="cb00" prefWidth="150.0" GridPane.rowIndex="0" GridPane.columnIndex="0">
<items>
<FXCollections fx:id="test" fx:factory="observableArrayList">
<String fx:value="1" />
<String fx:value="2" />
<String fx:value="3" />
<String fx:value="4" />
<String fx:value="5" />
<String fx:value="6" />
<String fx:value="7" />
<String fx:value="8" />
<String fx:value="9" />
</FXCollections>
</items>
</ChoiceBox>
是否可以在控制器中聲明集合並在 FXML 中引用它而不是為每個 ChoiceBox 復制集合?
您可以在控制器中定義項目:
public class Controller {
private ListProperty<String> choiceBoxItems = new SimpleListProperty(FXCollections.observableArrayList());
public Controller() {
IntStream.range(1,10).mapToObj(i -> Integer.toString(i))
.forEach(choiceBoxItems::add);
}
public ListProperty<String> choiceBoxItemsProperty() {
return choiceBoxItems ;
}
public ObservableList<String> getChoiceBoxItems() {
return choiceBoxItemsProperty().get() ;
}
public void setComboBoxItems(ObservableList<String> choiceBoxItems) {
choiceBoxItemsProperty().set(choiceBoxItems) ;
}
// ...
}
然后(這沒有經過測試,但我認為它會起作用):
<ChoiceBox fx:id="cb00" items="${controller.choiceBoxItems}" prefWidth="150.0" GridPane.rowIndex="0" GridPane.columnIndex="0">
請參閱 FXML 文檔中的表達式綁定。 (實際上並沒有證明控制器在 FXML 命名空間中可用,鍵為controller
,但我認為使用它是安全的。)
您也可以使用fx:define
在 FXML 中定義列表:
<fx:define>
<FXCollections fx:id="choiceBoxItems" fx:factory="observableArrayList">
<String fx:value="1"/>
<String fx:value="2"/>
<String fx:value="3"/>
<!-- ... -->
</FXCollections>
</fx:define>
然后在每個選擇框中引用它:
<ChoiceBox fx:id="cb00" items="${choiceBoxItems}" prefWidth="150.0" GridPane.rowIndex="0" GridPane.columnIndex="0">
它可以在控制器或任何其他類中(該示例適用於組合框。同樣可以應用於選擇框):
組合文件
<?import javafx.scene.control.ComboBox?>
<ComboBox fx:id="combo1" items="${itemLoader.items}" prefWidth="150.0"
xmlns:fx="http://javafx.com/fxml/1" >
</ComboBox>
加載器類
public class ComboLoader {
private ObservableList<String> obsStrings;
public ComboLoader() {
obsStrings = FXCollections.observableArrayList(createStrings());
}
private List<String> createStrings() {
return IntStream.rangeClosed(0, 5)
.mapToObj(i -> "String "+i)
.map(String::new)
.collect(Collectors.toList());
}
//name of this method corresponds to itemLoader.items in xml.
//if xml name was itemLoader.a this method should have been
//getA(). A bit odd
public ObservableList<String> getItems(){
return obsStrings;
}
}
測試它:
public class ComboTest extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setTitle("Populate combo from custom builder");
Group group = new Group();
GridPane grid = new GridPane();
grid.setPadding(new Insets(25, 25, 25, 25));
group.getChildren().add(grid);
FXMLLoader loader = new FXMLLoader(getClass().getResource("combo.fxml"));
loader.getNamespace().put("itemLoader", new ComboLoader());
ComboBox<String>combo = loader.load();
grid.add(combo, 0, 0);
Scene scene = new Scene(group, 450, 175);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
您可以使用<fx:reference>
通過fx:id
引用現有對象。 使用這個標簽你可以重用ObservableList
:
<HBox xmlns:fx="http://javafx.com/fxml/1" spacing="10">
<children>
<ChoiceBox prefWidth="150.0">
<items>
<FXCollections fx:id="test" fx:factory="observableArrayList">
<String fx:value="1" />
<String fx:value="2" />
<String fx:value="3" />
<String fx:value="4" />
<String fx:value="5" />
<String fx:value="6" />
<String fx:value="7" />
<String fx:value="8" />
<String fx:value="9" />
</FXCollections>
</items>
</ChoiceBox>
<ChoiceBox prefWidth="150.0">
<items>
<fx:reference source="test" /> <!-- reuse other list here -->
</items>
</ChoiceBox>
</children>
</HBox>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.