javafx 创建 ComboBox TableCell

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21860019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:07:02  来源:igfitidea点击:

javafx create ComboBox TableCell

javacomboboxjavafxtablecell

提问by Jerome

I'm trying to create a custom TableCell in my TableView. I'd like it to display a ComboBox where I can choose a String value, and then display the String value as if it was an user input. The idea is that ths user doesn't know which are the allowed values so he can simply pick one of them in the ComboBox.

我正在尝试在我的 TableView 中创建一个自定义 TableCell。我希望它显示一个 ComboBox,我可以在其中选择一个字符串值,然后显示字符串值,就好像它是用户输入一样。这个想法是用户不知道哪些是允许的值,所以他可以简单地在 ComboBox 中选择其中一个。

I tried to do that making my own "ComboBoxCell" but it doesn't work as expected :

我试图这样做制作我自己的“ComboBoxCell”,但它没有按预期工作:

public class ComboBoxCell extends TableCell<ClassesProperty, String> {

    private ComboBox<String> comboBox;

    public ComboBoxCell() {
    }

    @Override
    public void startEdit() {
        super.startEdit();

        if (comboBox == null) {
            createComboBox();
        }

        setGraphic(comboBox);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();

        setText(String.valueOf(getItem()));
        setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if (isEditing()) {
                if (comboBox != null) {
                    comboBox.setValue(getString());
                }
                setGraphic(comboBox);
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            } else {
                setText(getString());
                setContentDisplay(ContentDisplay.TEXT_ONLY);
            }
        }
    }

    private void createComboBox() {
        // ClassesController.getLevelChoice() is the observable list of String
        comboBox = new ComboBox<>(ClassesController.getLevelChoice());
        comboBox.setMinWidth(this.getWidth() - this.getGraphicTextGap()*2);
        comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent t) {
                if (t.getCode() == KeyCode.ENTER) {
                    commitEdit(comboBox.getSelectionModel().getSelectedItem());
                } else if (t.getCode() == KeyCode.ESCAPE) {
                    cancelEdit();
                }
            }
        });
    }

    private String getString() {
        return getItem() == null ? "" : getItem().toString();
    }
}

Then in my "main" app :

然后在我的“主”应用程序中:

levelChoice = FXCollections.observableArrayList(
        new String("Bla"),
        new String("Blo")
    );

// Level Column : String value
Callback<TableColumn, TableCell> comboBoxFactory = new Callback<TableColumn, TableCell>() {
        @Override
        public TableCell call(TableColumn p) {
            return new ComboBoxCell();
        }
    };

levelColumn.setCellValueFactory(
        new PropertyValueFactory<ClassesProperty, String>("level")
    );
levelColumn.setCellFactory(comboBoxFactory);

Any ideas? Thanks !

有任何想法吗?谢谢 !

采纳答案by Jerome

I've found the solution :

我找到了解决方案:

levelChoice = FXCollections.observableArrayList("Bla", "Blo");

levelColumn.setCellValueFactory(
    new PropertyValueFactory<ClassesProperty, String>("level")
);
levelColumn.setCellFactory(ComboBoxTableCell.forTableColumn(levelChoice));
levelColumn.setOnEditCommit(
    new EventHandler<CellEditEvent<ClassesProperty, String>>() {
        @Override
        public void handle(CellEditEvent<ClassesProperty, String> t) {
            ((ClassesProperty) t.getTableView().getItems().get(t.getTablePosition().getRow())).setLevel(t.getNewValue());
        };
    }
);