Reputation: 2644
I have a javafx application with a TableView
. Only the first column (dataTypeColumn
) is editable and it contains a ComboBox
for editing. Now the TableView
does what it is supposed to do, however there is a combination of weird bugs when i start editing a cell and then scroll it out of view without commiting the edit. I am pretty sure it is because of the way TableView
reuses the cells. However I haven't found any way to intervene with it, for example to forbid reuse of cells that are currently editing. Can you help me with that.
Even though I am pretty sure it is because of cell reuse, I will write the whole problem below, in case the source of the problem is a different.
The column in question contains Values of the enum DataType
I have a cell Factory for that column looking like this:
dataTypeColumn.setCellFactory(param -> new ComboBoxTableCell<>(DataType.values()));
The values for the column get read like this:
dataTypeColumn.setCellValueFactory(param -> Bindings.valueAt(configuration, param.getValue()));
In case this is confusing, the items that I give my TableView
are Integers
(from 0 to n-1), and in the different column CellValueFactories
the actual values will be loaded depending on the Integer
assoziated with the current column.
So when editing it, it shows a ComboBox
with all the Values that DataType
can have and let's the user select one. I have a callback on the column that reacts to the Edit commited event and looks like this:
public void editCommited(TableColumn.CellEditEvent<Integer, DataType> event) {
//configuration is an ObservableList containing DataType elements
configuration.set(event.getRowValue(), event.getNewValue());
}
So about the problems that occur. At the beginning all cells in that column have the same value: "nothing selected". It is a special value of the enum reserved for this case, as I didn't find a setPlaceholder function on the ComboBoxTableCell
class. When I know start editing one of the cells and then scroll it out of view, one of the next rows will suddendly be in the editing state as well, even though that row has not been touched before. If I scroll further an cell in the editing state will appear every time the previous one scrolls out of view. I can also go back and will find the same cells in the editing state. If I edit the cell that should not be in the editing state, it will not change, but instead the cell that I originally tried to edit will change it's value. This might be due to the underlying ObservableList
, that automatically updates the value in the column.
If I start editing a cell that has a different value (from a previous edit), something even more weird happens. When scrolling it out of view again a new row will have a cell in the editing page, however with the default value "nothing selected". If I scroll backwards the cell that i tried to edit originally will no longer be in the editing state however it's value has changed to "nothing selected". As if the new cell that got the editing state somehow commited it's own value.
Please some help with this :)
Upvotes: 1
Views: 873
Reputation: 82451
This indeed seems to be a bug. Rather surprising, if you move the scroll bar with the mouse, the edit is properly canceled, but not, if you use the mouse wheel to scroll.
You can easily create a workaround for this buf however, since you simply have to cancel the edit, when the item is replaced. You could e.g. use this method to create the cellFactory
on your own:
public static <S, T> Callback<TableColumn<S, T>, TableCell<S, T>> comboBoxCellFactory(ObservableList<T> items) {
if (items == null) {
throw new IllegalArgumentException();
}
return column -> new ComboBoxTableCell<S, T>(items) {
@Override
public void updateIndex(int i) {
cancelEdit();
super.updateIndex(i);
}
};
}
Upvotes: 3