List/TableColumn have default editCommit handlers, TreeView has none (see failing test below), introducing an inconsistency and breaking its spec:
"By default the TreeView edit commit handler is non-null with a default handler that attempts to overwrite the property value for the item in the currently-being-edited row."
Not having one might be the reason (wildly speculating ;) for
TreeCell to illegally take over the task in commitEdit and change the backing data (reported asJDK-8187309)
The fix for both is rather simple (and low risk, I think):
1. add a default handler like f.i.
treeView.setOnEditCommit(e -> {
TreeItem editItem = e.getTreeItem();
editItem.setValue(e.getNewValue());
});
2. remove interfering code in treeCell.commitEdit
// current code
// update the item within this cell, so that it represents the new value
// no, that's is wrong!
// if (treeItem != null) {
// treeItem.setValue(newValue);
// updateTreeItem(treeItem);
// updateItem(newValue, false);
// }
// replace with:
updateItem(newValue, false);
The tests (pass for List/TableColumn, fail for Tree)
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: Table
*/
@ConditionalIgnore (condition = IgnoreTableEdit.class)
@Test
public void testTableEditHandler() {
TableView<TableColumn> table = createEditableTable();
new StageLoader(table);
TableColumn control = table.getColumns().get(0);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("listView must have default commit handler", control.getOnEditCommit());
}
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: List
*/
@ConditionalIgnore (condition = IgnoreListEdit.class)
@Test
public void testListEditHandler() {
ListView<String> control = createEditableList();
new StageLoader(control);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("listView must have default commit handler", control.getOnEditCommit());
}
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: Tree - fails, probably reason for cell taking over itself
* (https://bugs.openjdk.java.net/browse/JDK-8187309)
*/
@ConditionalIgnore (condition = IgnoreTreeEdit.class)
@Test
public void testTreeEditHandler() {
TreeView<String> control = createEditableTree();
new StageLoader(control);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("treeView must have default commit handler", control.getOnEditCommit());
}
"By default the TreeView edit commit handler is non-null with a default handler that attempts to overwrite the property value for the item in the currently-being-edited row."
Not having one might be the reason (wildly speculating ;) for
TreeCell to illegally take over the task in commitEdit and change the backing data (reported as
The fix for both is rather simple (and low risk, I think):
1. add a default handler like f.i.
treeView.setOnEditCommit(e -> {
TreeItem editItem = e.getTreeItem();
editItem.setValue(e.getNewValue());
});
2. remove interfering code in treeCell.commitEdit
// current code
// update the item within this cell, so that it represents the new value
// no, that's is wrong!
// if (treeItem != null) {
// treeItem.setValue(newValue);
// updateTreeItem(treeItem);
// updateItem(newValue, false);
// }
// replace with:
updateItem(newValue, false);
The tests (pass for List/TableColumn, fail for Tree)
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: Table
*/
@ConditionalIgnore (condition = IgnoreTableEdit.class)
@Test
public void testTableEditHandler() {
TableView<TableColumn> table = createEditableTable();
new StageLoader(table);
TableColumn control = table.getColumns().get(0);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("listView must have default commit handler", control.getOnEditCommit());
}
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: List
*/
@ConditionalIgnore (condition = IgnoreListEdit.class)
@Test
public void testListEditHandler() {
ListView<String> control = createEditableList();
new StageLoader(control);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("listView must have default commit handler", control.getOnEditCommit());
}
/**
* Test default edit handlers: expected none for start/cancel,
* default that commits
*
* Here: Tree - fails, probably reason for cell taking over itself
* (https://bugs.openjdk.java.net/browse/JDK-8187309)
*/
@ConditionalIgnore (condition = IgnoreTreeEdit.class)
@Test
public void testTreeEditHandler() {
TreeView<String> control = createEditableTree();
new StageLoader(control);
assertNull(control.getOnEditCancel());
assertNull(control.getOnEditStart());
assertNotNull("treeView must have default commit handler", control.getOnEditCommit());
}
- duplicates
-
JDK-8187309 TreeCell must not change tree's data
- Resolved
- relates to
-
JDK-8280951 Testbug: fix commented asserts in XXViewTest.test_rt_29650
- Resolved