TableView, setting editable cells

北战南征 提交于 2019-12-04 11:49:24

The issue is that TextFieldTableCell.forTableColumn() is typed to a String value. See the default implementation:

public static <S> Callback<TableColumn<S,String>, TableCell<S,String>> forTableColumn() {
    return forTableColumn(new DefaultStringConverter());
}

What you need is the TextFieldTableCell with an IntegerStringConverter, for example:

ageColumn.setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));

I searched through a lot of answers and I've borrowed/extended/merged to this solution. Edits are committed when focus moves from edited cell. I have a public class for each datatype that can be represented in a table: EditingTextCell, EditingIntegerCell etc. These public classes can be applied to any table provided that the data is represented as an observable list of a class that accesses the data to be displayed as properties. I publish this solution because I was faced with creating a class for each column of each table in my application. Currently, the double value and combobox cell versions are tied to specific columns of specific tables. I'll do a generalized version of these as time permits. Please forgive my not presenting the source links -- I forgot to bookmark them as I perused them.

Java documentation suggests that easier ways of doing this are forthcoming.

Example usage for Integer field:

    TableColumn<Factor, Number> noLevelsCol =
            new TableColumn<>("No. Levels");
    noLevelsCol.setCellValueFactory(
            new PropertyValueFactory("numberLevels"));
    noLevelsCol.setMinWidth(40);
    noLevelsCol.setCellFactory(col -> new EditingIntegerCell<>());
    noLevelsCol.setOnEditCommit((CellEditEvent<Factor, Number> t) -> {
        ((Factor) t.getTableView().getItems().get(
                t.getTablePosition().getRow())
                ).setNumberLevels(t.getNewValue().intValue());
    });

Example usage for String field:

    TableColumn<Factor, String> nameCol = new TableColumn<>("Name");
    nameCol.setMinWidth(60);
    nameCol.setCellValueFactory(
          new PropertyValueFactory("factorName"));
    nameCol.setCellFactory(cellFactory);
    nameCol.setOnEditCommit((CellEditEvent<Factor, String> t) -> {
        ((Factor) t.getTableView().getItems().get(
                t.getTablePosition().getRow())
                ).setFactorName(t.getNewValue());
    });

Definition of Factor class: public class Factor {

private final IntegerProperty factorID = new SimpleIntegerProperty();
public IntegerProperty getFactorID() {     return factorID;    }

private StringProperty factorName = new SimpleStringProperty();
public void setFactorName(String value) {
           factorNameProperty().set(value); }
public String getFactorName() { return factorNameProperty().get(); }
public StringProperty factorNameProperty() { 
    if (factorName == null) factorName = 
        new SimpleStringProperty(this, "factorName");
    return factorName; 
}

private IntegerProperty numberLevels = new SimpleIntegerProperty();
public void setNumberLevels(int value) {
         numberLevelsProperty().set(value); }
public IntegerProperty getNumberLevels() { return numberLevels;    }
public IntegerProperty numberLevelsProperty() { 
    if (numberLevels == null) numberLevels =
          new SimpleIntegerProperty(this, "numberLevels");
    return numberLevels; 
}

private StringProperty listOfLevels = new SimpleStringProperty();
public void setListOfLevels(String value) {
         listOfLevelsProperty().set(value); }
public String getListOfLevels() { return listOfLevelsProperty().get(); }
public StringProperty listOfLevelsProperty() { 
    if (listOfLevels == null) listOfLevels = 
          new SimpleStringProperty(this, "listOfLevels");
    return listOfLevels; 
}


// Constructors
public Factor(int factorID, String factorName) {
    this.factorID.set(factorID);
    this.factorName.set(factorName);
    this.numberLevels.set(1);
    this.listOfLevels.set("-1, 1");
}

public Factor(int factorID, String factorName, int numberLevels,
                String listOfLevels) {
    this.factorID.set(factorID);
    this.factorName.set(factorName);
    this.numberLevels.set(numberLevels);
    this.listOfLevels.set(listOfLevels);
}

@Override
public String toString() {
    return "Factor{" + "factorName=" + factorName + '}';
}

public String[] getLevels() {
    return listOfLevels.getValue().split(",");
}

}

Loading the data into the table final ObservableList factorList = FXCollections.observableArrayList( new Factor(1, "Factor1", 2, "-1, 1") );

    factorTableView.setEditable(true);
    factorTableView.getColumns().clear();
    factorTableView.setItems(factorList);
    boolean addAll;
    addAll = factorTableView.getColumns().addAll(idCol,
                   nameCol, noLevelsCol, levelsCol);

The EditingIntegerCell class public class EditingIntegerCell extends TableCell {

    private TextField textField;
    private final Pattern intPattern = Pattern.compile("-?\\d+");

    public EditingIntegerCell() {
    }

    @Override
    public void startEdit() {
        if (!isEmpty()) {
            super.startEdit();
            createTextField();
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }
    }

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

        setText((String) getItem().toString());
        setGraphic(null);
    }

    @Override
    public void updateItem(Number item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if (isEditing()) {
                if (textField != null) {
                    textField.setText(getString());
                }
                setText(null);
                setGraphic(textField);
            } else {
                setText(getString());
                setGraphic(null);
            }
        }
    }

    private void createTextField() {
        textField = new TextField(getString());
        textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
        textField.focusedProperty().addListener(
            (ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) 
                        -> {
            if (!arg2) {
                processEdit();
            }
        });
    }

    private void processEdit() {
        String text = textField.getText();
        if (intPattern.matcher(text).matches()) {
            commitEdit(Integer.parseInt(text));
        } else {
            cancelEdit();
        }
    }

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

** The EditingTextCell class ** public class EditingTextCell extends TableCell {

    private TextField textField;

    public EditingTextCell() {
    }

    @Override
    public void startEdit() {
        if (!isEmpty()) {
            super.startEdit();
            createTextField();
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }
    }

    @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()) {
                if (textField != null) {
                    textField.setText(getString());
                }
                setText(null);
                setGraphic(textField);
            } else {
                setText(getString());
                setGraphic(null);
            }
        }
    }

    private void createTextField() {
        textField = new TextField(getString());
        textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
        textField.focusedProperty().addListener(
            (ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) 
                        -> {
            if (!arg2) {
                commitEdit(textField.getText());
            }
        });
    }

    private String getString() {
        return getItem() == null ? "" : getItem();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!