如何在Cell Factory中以编程方式选择ComboBox值?

时间:2018-10-22 04:05:11

标签: java javafx

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

在下面的MCVE中,我的Item类有两列:NameColor。在Color列中,我有ComboBox,它将显示项目的itemColor属性的当前值。

您将看到ComboBox尚未填充值列表,并且项目“三”没有选择值。

我需要的是

当用户单击“加载可用颜色”按钮时,将创建ComboBox的列表。用户现在可以选择任何可用的颜色。但是,如果该项目的颜色还没有值,我希望自动选择ComboBoxes中的第一种颜色。因此项目“三”现在将显示为“红色”。

  

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,在加载comboBox.getSelectionModel().selectFirst()之后对availableColors的简单调用就可以了。但是由于此ComboBox是在CellFactory中创建的,因此我不确定一旦填充颜色列表后如何更新它。

  

顺便说一句,我使用此CellFactory实施代替了ComboBoxTableCell,因为我希望它们可见而不必在TableView上进入编辑模式。

1 个答案:

答案 0 :(得分:1)

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