【问题标题】:Javafx: Reusable collections using FXMLJavafx:使用 FXML 的可重用集合
【发布时间】:2017-06-04 12:39:07
【问题描述】:

我想将一个集合绑定到 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复制集合?

【问题讨论】:

    标签: java javafx collections fxml


    【解决方案1】:

    您可以在控制器中定义项目:

    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 文档中的 expression binding。 (实际上并没有记录控制器在 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">
    

    【讨论】:

      【解决方案2】:

      它可以在控制器或任何其他类中(示例是组合框。同样可以应用于选择框):

      combo.fxml

      <?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);
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用&lt;fx:reference&gt; 通过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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-09
          • 1970-01-01
          • 1970-01-01
          • 2016-02-16
          • 1970-01-01
          • 2016-08-20
          相关资源
          最近更新 更多