Как программно выбрать значение ComboBox в Cell Factory? - PullRequest
0 голосов
/ 22 октября 2018

My TableView использует пользовательский CellFactory для отображения ComboBox в одном столбце, что позволяет пользователю выбирать из доступных параметров.Эти параметры загружаются после того, как заполнено TableView (поскольку они могут меняться в зависимости от выбора пользователя в другом месте сцены).

В MCVE ниже у меня есть два столбца для моегоItem класс: Name и Color.В столбце 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 голосов
/ 22 октября 2018

Я действительно воспользовался советом Клеопатры и обновил свою модель данных, добавив вместо нее значение по умолчанию.Я согласен, что это более чистый и более подходящий подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...