简体   繁体   English

javafx创建ComboBox TableCell

[英]javafx create ComboBox TableCell

I'm trying to create a custom TableCell in my TableView. 我正在尝试在TableView中创建自定义TableCell。 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. 我希望它显示一个ComboBox,我可以在其中选择一个String值,然后显示String值,就好像它是一个用户输入。 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. 这个想法是用户不知道哪些是允许的值,所以他可以简单地在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 ! 谢谢 !

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());
        };
    }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM