代码之家  ›  专栏  ›  技术社区  ›  Zephyr

如何在单元工厂内编程选择组合框值?

  •  1
  • Zephyr  · 技术社区  · 7 年前

    我的 TableView 使用自定义 CellFactory 显示一个 ComboBox 在一列中,允许用户从可用选项中进行选择。这些选项已加载 之后 这个 表视图 填充(因为它们可以根据用户在场景中其他位置的选择进行更改)。

    在下面的mcve中,我有两列 Item 班级: Name Color . 内 颜色 专栏,我有 组合框 它将显示项目的当前值 itemColor 财产。

    你会看到 组合框 尚未用值列表填充,项“3”未选择值。

    我需要的是:

    当用户单击“加载可用颜色”按钮时, 组合框 创建。用户现在可以选择任何可用的颜色。但是,如果项目的颜色还没有值,我希望 ComboBoxes 自动选择;因此项目“3”现在将显示被选择的颜色“红色”。

    MCVE

    Item.java:

    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    
    public class Item {
    
        private StringProperty itemName = new SimpleStringProperty();
        private StringProperty itemColor = new SimpleStringProperty();
    
        public Item(String name, String color) {
            this.itemName.set(name);
            this.itemColor.set(color);
        }
    
        public String getItemName() {
            return itemName.get();
        }
    
        public void setItemName(String itemName) {
            this.itemName.set(itemName);
        }
    
        public StringProperty itemNameProperty() {
            return itemName;
        }
    
        public String getItemColor() {
            return itemColor.get();
        }
    
        public void setItemColor(String itemColor) {
            this.itemColor.set(itemColor);
        }
    
        public StringProperty itemColorProperty() {
            return itemColor;
        }
    }
    

    Main.java:

    import javafx.application.Application;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
        // List of items
        private static ObservableList<Item> listOfItems = FXCollections.observableArrayList();
    
        // List of available Colors. These will be selectable from the ComboBox
        private static ObservableList<String> availableColors = FXCollections.observableArrayList();
    
        public static void main(String[] args) {
            launch(args);
        }
    
        private static void buildSampleData() {
    
            availableColors.addAll("Red", "Blue", "Green", "Yellow", "Black");
        }
    
        @Override
        public void start(Stage primaryStage) {
    
            // Simple Interface
            VBox root = new VBox(10);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(10));
    
            // Build a list of sample data. This data is loaded from my data model and passed to the constructor
            // of this editor in my real application.
            listOfItems.addAll(
                    new Item("One", "Black"),
                    new Item("Two", "Black"),
                    new Item("Three", null),
                    new Item("Four", "Green"),
                    new Item("Five", "Red")
            );
    
            // TableView to display the list of items
            TableView<Item> tableView = new TableView<>();
    
            // Create the TableColumn
            TableColumn<Item, String> colName = new TableColumn<>("Name");
            TableColumn<Item, String> colColor = new TableColumn<>("Color");
    
            // Cell Property Factories
            colName.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemName()));
            colColor.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemColor()));
    
            // Add ComboBox to the Color column, populated with the list of availableColors
            colColor.setCellFactory(tc -> {
                ComboBox<String> comboBox = new ComboBox<>(availableColors);
                comboBox.setMaxWidth(Double.MAX_VALUE);
                TableCell<Item, String> cell = new TableCell<Item, String>() {
                    @Override
                    protected void updateItem(String color, boolean empty) {
                        super.updateItem(color, empty);
                        if (empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(comboBox);
                            comboBox.setValue(color);
                        }
                    }
                };
    
                // Set the action of the ComboBox to set the right Value to the ValuePair
                comboBox.setOnAction(event -> {
                    listOfItems.get(cell.getIndex()).setItemColor(comboBox.getValue());
                });
    
                return cell;
            });
    
            // Add the column to the TableView
            tableView.getColumns().addAll(colName, colColor);
            tableView.setItems(listOfItems);
    
            // Add button to load the data
            Button btnLoadData = new Button("Load Available Colors");
            btnLoadData.setOnAction(event -> {
                buildSampleData();
            });
            root.getChildren().add(btnLoadData);
    
            // Add the TableView to the root layout
            root.getChildren().add(tableView);
    
            Button btnPrintAll = new Button("Print All");
            btnPrintAll.setOnAction(event -> {
                for (Item item : listOfItems) {
                    System.out.println(item.getItemName() + " : " + item.getItemColor());
                }
            });
            root.getChildren().add(btnPrintAll);
    
            // Show the stage
            primaryStage.setScene(new Scene(root));
            primaryStage.setTitle("Sample");
            primaryStage.show();
        }
    }
    

    现在,用一个普通的 组合框 ,一个简单的调用 comboBox.getSelectionModel().selectFirst() 加载后 availableColors 就好了。但既然如此 组合框 在中创建 细胞工厂 ,我不知道如何在填充颜色列表后更新它。

    间接地,我用这个 细胞工厂 实现而不是 ComboBoxTableCell 因为我希望它们不必在 表视图 .

    1 回复  |  直到 7 年前
        1
  •  1
  •   Zephyr    7 年前

    实际上,我接受了Kleopatra的建议,并更新了我的数据模型以包含默认值。我同意这是一种更清洁、更合适的方法。