4
votes

I've got a JavaFX TableView which possesses two columns. This tables uses a ObservableList gasRatioMeasures as its model.

public class GasRatioMeasureBean {
    private String number;
    private String measure;
    public String getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = "Measure" + (number + 1) + "(%)";
    }
    public String getMeasure() {
        return measure;
    }
    public void setMeasure(String measure) {
        this.measure = measure;
    }
}

I'd like to set one of them editable and the other non-editable.

Firstly I tried the FXML way:

<TableView layoutX="24.0" layoutY="122.0" prefHeight="200.0" prefWidth="215.0" fx:id="measureTableView">
    <columns>
         <TableColumn editable="false" prefWidth="100.0" sortable="false" text="No" fx:id="measureNumbersColumn" />
         <TableColumn editable="true" prefWidth="110.0" sortable="false" text="Measures" fx:id="measuresColumn" />
    </columns>
</TableView>

But this didn't work. The table is always not editable.

I also tried out the java way:

private void initMeasuresTableView() {
    measureNumbersColumn.setCellValueFactory(new PropertyValueFactory<GasRatioMeasureBean, String>("number"));
    measureNumbersColumn.setEditable(false);
    measuresColumn.setCellValueFactory(new PropertyValueFactory<GasRatioMeasureBean, String>("measure"));
    measuresColumn.setOnEditCommit(
        new EventHandler<CellEditEvent<GasRatioMeasureBean, String>>() {
            public void handle(CellEditEvent<GasRatioMeasureBean, String> measure) {
                ((GasRatioMeasureBean) measure.getTableView().getItems().get(
                measure.getTablePosition().getRow())
                ).setMeasure(measure.getNewValue());
            }
        }
    );

    measureTableView.setItems(gasRatioMeasures);
    measureTableView.setEditable(true);
}

But this didn't work either. All the table kept uneditable.

If TableColumn has an editable property, then it should be able to be set separately.

Please help me if you know where I'm doing wrong. Thanks!

PS: the column measureNumbersColumn can already been displayed normally (when I haven't initialized measuresColumn).

PPS: I also tried instead of setOnEditCommit setOnEditStart . setOnEditCommit is not called, but setOnEditStart can be called just in editable column.

2
See Oracle's TableView tutorial for the part "Editing Data in the Table" where the partial editing has been implemented. - Uluk Biy

2 Answers

7
votes

You did not use a cell factory that supports editing. You need to do:

measureNumbersColumn.setCellFactory(TextFieldTableCell.forTableColumn()) 

This will make your column use a TextFieldTableCell instead of the default TableCell. TextFieldTableCell supports editing (look at the source code and look for startEdit method).

Alternatively if you are not happy with the behavior of the TextFieldTableCell, you can write your own implementation of TableCell, and override the startEdit, cancelEdit, and updateItem methods.

measureNumbersColumn.setCellFactory(new Callback<TableColumn<GasRatioMeasureBean,String>, TableCell<GasRatioMeasureBean,String>>() {

    @Override
    public TableCell<GasRatioMeasureBean, String> call(
            TableColumn<GasRatioMeasureBean, String> arg0) {
        return MyOwnTableCell(); 
    }
});
3
votes

This is the way by which you can make editable columns in TableView.

tblViewPerson.setEditable(true);

        // Making editable columns 
        // For ID

        tblColID.setCellFactory(TextFieldTableCell.forTableColumn());

        tblColID.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>() {
                public void handle(CellEditEvent<Person, String> t) {
                    ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())
                        ).setId(t.getNewValue());
                }
            }
        );