2017-06-02 142 views
0

我想在Dan Nicks的評論this question中提出一個自定義生成器。
這個想法是在構建組合數據之前設置組合數據。
的FXML文件:Javafx動態加載組合框

<?xml version="1.0" encoding="UTF-8"?> 
<?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 { 

    public ObservableList<Item> items; 

    public ComboLoader() { 

     items = FXCollections.observableArrayList(createItems()); 
    } 

    private List<Item> createItems() { 
      return IntStream.rangeClosed(0, 5) 
        .mapToObj(i -> "Item "+i) 
        .map(Item::new) 
        .collect(Collectors.toList()); 
     } 

    public ObservableList<Item> getItems(){ 

     return items; 
    } 

    public static class Item { 

     private final StringProperty name = new SimpleStringProperty(); 

     public Item(String name) { 
      this.name.set(name); 
     } 

     public final StringProperty nameProperty() { 
      return name; 
     } 

    } 
} 

而且測試:

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(); 
     ComboBox combo = loader.load(getClass().getResource("combo.fxml")); 
     loader.getNamespace().put("itemLoader", new ComboLoader()); 
     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); 
    } 
} 

產生任何錯誤,但組合不會填充。
缺什麼?


BTW:對作品類似的解決方案罰款:

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

<?import javafx.scene.control.TableView?> 
<?import javafx.scene.control.TableColumn?> 
<?import javafx.scene.control.cell.PropertyValueFactory?> 

<TableView items="${itemLoader.items}" xmlns:fx="http://javafx.com/fxml/1"> 
    <columns> 
     <TableColumn text="Item"> 
      <cellValueFactory><PropertyValueFactory property="name" /></cellValueFactory> 
     </TableColumn> 
    </columns> 
</TableView> 

回答

0

固定錯誤的裝載以及加入toString方法後,它工作得很好:

public class ComboLoader { 

    private ObservableList<Item> obsItems; 

    public ComboLoader() { 

     obsItems = FXCollections.observableArrayList(createItems()); 
    } 

    private List<Item> createItems() { 
      return IntStream.rangeClosed(0, 5) 
        .mapToObj(i -> "Item "+i) 
        .map(Item::new) 
        .collect(Collectors.toList()); 
    } 
    //name of this methods corresponds to itemLoader.items in fxml. 
    //if xml name was itemLoader.a this method should have been 
    //getA(). A bit odd 
    public ObservableList<Item> getItems(){ 

     return obsItems; 
    } 

    public static class Item { 

     private final StringProperty name = new SimpleStringProperty(); 

     public Item(String name) { 
      this.name.set(name); 
     } 

     public final StringProperty nameProperty() { 
      return name; 
     } 

     @Override 
     public String toString() { 
      return name.getValue(); 
     } 
    } 
} 


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