JavaFX:获取ComboBoxTableCell的ComboBox

时间:2016-11-24 11:57:52

标签: java javafx javafx-8

我想在JavaFX8中ComboBox的{​​{1}}内向ComboBoxTableCell添加处理程序。我可以看到TableView类中存在私有ComboBox值,但我不知道如何访问它。我告诉专栏通过ComboBoxTableCell方法使用ComboBoxTableCell。有没有办法获得setCellFactory

编辑:我想在ComboBox添加一个监听器,通过输入密钥来选择项目。我已经有一个正常的ComboBox,我想对ComboBox中的ComboBox重复使用它。

1 个答案:

答案 0 :(得分:1)

据我所知,无法获得ComboBox ComboBoxTableCell的引用。如果这是真的,就不可能为它添加一个监听器。

另一种方法是创建包含ComboBox的自定义单元格。使用这种方法,您可以以任何方式操纵ComboBox

import java.util.function.BiConsumer;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class ComboBoxTable extends Application {
    @Override
    public void start(Stage stage) {
        int numOfCols = 2;

        ObservableList<ObservableList<String>> tableData = FXCollections.observableArrayList();

        // Generate dummy data.
        for (int i = 0; i < 10; i++) {
            ObservableList<String> row = FXCollections.observableArrayList();

            for (int j = 0; j < numOfCols; j++)
                row.add("Row" + i + "Col" + j);

            tableData.add(row);
        }

        TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();

        // Add columns to the table.
        for (int i = 0; i < numOfCols; i++) {
            final int j = i;
            // The fourth argument in the method, the BiConsumer, might require
            // an explanation. Basically we are saying that when the BiConsumer
            // are given an ObservableList<String> and a String, we set the
            // value of the String as the value of the element at position "j"
            // of the row, where "j" will be the column index.
            table.getColumns().add(addComboBoxColumn(i, "Column " + i, row -> new SimpleStringProperty(row.get(j)),
                    (row, newText) -> row.set(j, newText)));
        }

        table.getItems().addAll(tableData);

        Scene scene = new Scene(table);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * Returns a TableColumn with ComboBoxCells.
     */
    private TableColumn<ObservableList<String>, String> addComboBoxColumn(int index, String name,
            Function<ObservableList<String>, ObservableValue<String>> property,
            BiConsumer<ObservableList<String>, String> updater) {

        TableColumn<ObservableList<String>, String> col = new TableColumn<ObservableList<String>, String>(name);

        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));

        col.setCellFactory(e -> new ComboBoxCell(updater, index));

        return col;
    }

    /**
     * A TableCell with a ComboBox in it.
     */
    public class ComboBoxCell extends TableCell<ObservableList<String>, String> {
        private ComboBox<String> comboBox = new ComboBox<String>();

        /**
         * @param updater
         *            The updater makes sure that the cell value corresponds
         *            with the value in the ComboBox.
         * @param colIndex
         *            The index of this column.
         */
        public ComboBoxCell(BiConsumer<ObservableList<String>, String> updater, int colIndex) {
            comboBox.setEditable(true);

            comboBox.getEditor().textProperty().addListener((old, oldValue, newValue) -> {
                if (getIndex() >= 0) {
                    // We provide the BiConsumer.accept() with an
                    // ObservableList<String> and a String. The BiConsumer will
                    // do the operation specified in the definition we provided
                    // in addColumn() using these two objects.
                    updater.accept(getTableView().getItems().get(getIndex()), (String) newValue);
                }
            });
        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setGraphic(null);
            } else {
                // If we don't check if this value is the same as the old one,
                // the cursor is moved to the beginning of the editor every time
                // anything is typed.
                if (!item.equals(comboBox.getEditor().getText())) {
                    comboBox.getEditor().setText(item);
                }
                setGraphic(comboBox);
            }
        }
    }

    public static void main(String[] args) {
        launch();
    }
}