I’ve got a TreeView. I’ve added context menus to the items in the tree and I react to a menu selection by adding a node. For some reason, the first time I click on the context menu, the menu does not disappear and the TreeView UI is not updated. If I click again the context menu disappear and 2 items are added to the tree. If I go to the context menu again and click it adds 1 item normally every subsequent time. Any advice?
I use TreeItem.getChildren().add() to add sub-TreeItems. Here is the code that creates the TreeCell factory (which creates the context menu.
public NodeTreeView(NodeView rootNodeView) {
setRoot(rootNodeView);
setCellFactory(new Callback<TreeView<String>,TreeCell<String>>() {
@Override
public TreeCell<String> call(TreeView<String> p) {
return new TextFieldTreeCellImpl();
}
});
getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
getSelectionModel().selectedItemProperty().addListener(this);
}
@Override
public void changed(
ObservableValue<? extends TreeItem<String>> ov,
TreeItem<String> deselectedTreeItem,
TreeItem<String> selectedTreeItem) {
NodeView nodeView = null;
nodeView = (NodeView) selectedTreeItem;
System.out.println("Display properties for " + nodeView.getController().getType());
}
private final class TextFieldTreeCellImpl extends TreeCell<String> {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
NodeMenuController nodeMenuController = null;
nodeMenuController = new NodeMenuController(getController());
setText(getString());
setGraphic(getTreeItem().getGraphic());
setContextMenu(nodeMenuController.getView());
}
Finally, here’s how the menu items are built:
public class NodeMenuController {
private NodeController nodeController;
public NodeMenuController(NodeController controller) {
this.nodeController = controller;
}
public ContextMenu getView() {
ContextMenu contextMenu = null;
contextMenu = new ContextMenu();
if (ChildMap.hasAllowedChildren(nodeController.getType())) {
contextMenu.getItems().add(getAddChildMenuItem());
}
return contextMenu;
}
private MenuItem getAddChildMenuItem() {
Menu menu = null;
List<String> allowedChildList = null;
menu = new Menu("+ Child");
allowedChildList = ChildMap.get(nodeController.getType());
for (final String allowedChildType : allowedChildList) {
MenuItem menuItem = null;
menuItem = new MenuItem(allowedChildType);
menuItem.setOnAction(new EventHandler() {
@Override
public void handle(Event t) {
NodeController newNodeController = null;
newNodeController = new NodeController(new NodeModel(allowedChildType));
nodeController.add(newNodeController);
}
});
menu.getItems().add(menuItem);
}
return menu;
}
}
It turned out I had a NullPointerException in the selection handler that I hadn’t noticed. If anyone has this problem, that’s one thing to check.