在TableView中以每行不同的值动态填充ComboBoxTableCell

时间:2018-08-30 02:02:07

标签: uitableview tableview javafx-8

在我的TableView中,ComboBoxTableCell需要在每一行中具有不同的内容。我已修改了Uluk Biy在此问题中建议的代码:Populate combo box list dynamically for each row in javaFx table view。我的代码如下所示。

对我来说,问题是我实际上无法在ComboBox中进行其他选择。在上面提到的问题中,这也是一个问题。

一个建议的解决方案是:' ...从组合框更改值之后,单元格仍处于编辑模式,您需要从单元格中移出焦点,因此combobox.focusProperty可以commitEdit。或者,您可以根据需要将commitEdit()放在组合框项目changeListener上。'。有人可以给我一个想法,或者以其他方式帮助我使我的代码正常工作吗?

此外,即使用户动态更改列宽,如何使ComboBox适应单元格的宽度?

我当前的代码:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
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.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ComboBoxCellTableExample extends Application {

    private final TableView<Attribute> table = new TableView<>();
    private Attribute attribute1 = new Attribute("2222", "attribute1", "1111|2222|3333");
    private Attribute attribute2 = new Attribute("bbbb", "attribute2", "aaaa|bbbb|cccc");
    private Attribute attribute3 = new Attribute("6666", "attribute3", "4444|5555|6666");
    private Attribute attribute4 = new Attribute("7777", "attribute4", "7777|8888|99999");
    private Attribute attribute5 = new Attribute("hhhh", "attribute5", "hhhh|jjjj|kkkk");
    private final ObservableList<Attribute> data
            = FXCollections.observableArrayList(attribute1, attribute2, attribute3, attribute4, attribute5);

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setWidth(800);
        stage.setHeight(550);
        table.setEditable(true);
        table.setMinWidth(750.0);

        TableColumn colName = new TableColumn("Name");
        colName.setMinWidth(100);
        colName.setEditable(false);
        colName.setCellValueFactory(new PropertyValueFactory<>("name"));
        colName.setCellFactory(TextFieldTableCell.forTableColumn());

        Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
            @Override
            public TableCell call(TableColumn p) {
                return new ComboBoxCell();
            }
        };
        TableColumn colValue = new TableColumn("Value");
        colValue.setMinWidth(100);
        colValue.setCellValueFactory(new PropertyValueFactory<>("value"));
        colValue.setCellFactory(cellFactory);
        colValue.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Attribute, String>>() {
            @Override
            public void handle(TableColumn.CellEditEvent<Attribute, String> tableColumn) {
                ((Attribute) tableColumn.getTableView().getItems().
                        get(tableColumn.getTablePosition().getRow())).setValue(tableColumn.getNewValue());
            }
        });

        table.setItems(data);
        table.getColumns().addAll(colName, colValue);
        ((Group) scene.getRoot()).getChildren().add(table);
        stage.setScene(scene);
        stage.show();
    }

    class ComboBoxCell extends TableCell<Attribute, String> {

        private ComboBox<String> comboBox;

        public ComboBoxCell() {
            comboBox = new ComboBox<>();
        }

        @Override
        public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                comboBox.setItems(getTableView().getItems().get(getIndex()).getOptionsList());
                comboBox.getSelectionModel().select(getItem());
                comboBox.focusedProperty().addListener(new ChangeListener<Boolean>() {
                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
                            Boolean newValue) {
                        if (newValue) {
                            commitEdit(comboBox.getSelectionModel().getSelectedItem());
                        }
                    }
                });
                setText(null);
                setGraphic(comboBox);
            }
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setText((String) getItem());
            setGraphic(null);
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    setText(null);
                    setGraphic(comboBox);
                } else {
                    setText(getItem());
                    setGraphic(null);
                }
            }
        }

    }

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

    public class Attribute {

        private String value;
        private String name;
        private String options;
        private ObservableList<String> optionsList;

        private Attribute(String value, String name, String options) {
            this.value = value;
            this.name = name;
            this.options = options;
            this.optionsList = parseOptions(options);
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public ObservableList<String> getOptionsList() {
            return optionsList;
        }

        public void setOptionsList(ObservableList<String> optionsList) {
            this.optionsList = optionsList;
        }

        public void setOptions(String options) {
            this.options = options;
        }

        public String getOptions() {
            return options;
        }

        public ObservableList<String> parseOptions(String options) {
            ObservableList<String> model = FXCollections.observableArrayList();
            int startPos = 0;
            int endPos = 0;
            while (endPos >= 0) {
                endPos = options.indexOf('|', startPos);
                if (endPos >= 0) {
                    model.add(options.substring(startPos, endPos));
                    startPos = endPos + 1;
                } else {
                    model.add(options.substring(startPos, options.length()));
                }
            }

            return model;
        }
    }
}

任何能帮助我完成此代码的评论都将不胜感激。

关于Stuart M

0 个答案:

没有答案