Reputation:
I have been trying to prevent my program from deleting the root node of my tree view but when ever I try and do so my program gives me a "java.lang.reflect.InvocationTargetException" during its compiling and the program will not launch. I am not really sure why it will not launch.
Here is my TextFieldTreeCellImpl class where the error takes place:
private final class TextFieldTreeCellImpl extends TreeCell<String> {
private TextField textField;
private ContextMenu addMenu = new ContextMenu();
public TextFieldTreeCellImpl() {
MenuItem addMenuItem0 = new MenuItem("Add Folder");
addMenu.getItems().add(addMenuItem0);
addMenuItem0.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
TreeItem<String> newFolder =
new TreeItem<String>("New Folder",new ImageView(depIcon));
getTreeItem().getChildren().add(newFolder);
}
});
MenuItem addMenuItem1 = new MenuItem("Delete");
addMenu.getItems().add(addMenuItem1);
addMenuItem1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {//There is not error when the if statement is in here
getTreeItem().getParent().getChildren().remove(getTreeItem());
}
});
if(getTreeItem().getParent()==null){//The error is here-------------
addMenuItem1.disableProperty().set(true);
}
}
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(getTreeItem().getGraphic());
}
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(getTreeItem().getGraphic());
setContextMenu(addMenu);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}
Here is the error I get:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$48/128893786.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at application.CopyOfMain$TextFieldTreeCellImpl.<init>(CopyOfMain.java:82)
at application.CopyOfMain$1.call(CopyOfMain.java:48)
at application.CopyOfMain$1.call(CopyOfMain.java:1)
at com.sun.javafx.scene.control.skin.TreeViewSkin.createCell(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin.lambda$new$513(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin$$Lambda$115/979660402.call(Unknown Source)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCell(Unknown Source)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength(Unknown Source)
at com.sun.javafx.scene.control.skin.VirtualFlow.computeViewportOffset(Unknown Source)
at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(Unknown Source)
at javafx.scene.Parent.layout(Unknown Source)
at javafx.scene.Parent.layout(Unknown Source)
at javafx.scene.Parent.layout(Unknown Source)
at javafx.scene.Scene.doLayoutPass(Unknown Source)
at javafx.scene.Scene.preferredSize(Unknown Source)
at javafx.scene.Scene.impl_preferredSize(Unknown Source)
at javafx.stage.Window$9.invalidated(Unknown Source)
at javafx.beans.property.BooleanPropertyBase.markInvalid(Unknown Source)
at javafx.beans.property.BooleanPropertyBase.set(Unknown Source)
at javafx.stage.Window.setShowing(Unknown Source)
at javafx.stage.Window.show(Unknown Source)
at javafx.stage.Stage.show(Unknown Source)
at application.CopyOfMain.start(CopyOfMain.java:54)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$57/1520696636.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$44/1051754451.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1933975749.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$46/1775282465.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
... 1 more
Exception running application application.CopyOfMain
And here is my Main Class although I do not think that it is realavent:
public class Main extends Application {
private final Node rootIcon =
new ImageView(new Image(getClass().getResourceAsStream("folder.jpg")));
private final Image depIcon =
new Image(getClass().getResourceAsStream("folder.jpg"));
TreeItem<String> rootNode =
new TreeItem<String>("Resources", rootIcon);
public static void main(String[] args) {
Application.launch(args);
}
public void start(Stage stage) {
rootNode.setExpanded(true);
stage.setTitle("Tree View Sample");
VBox box = new VBox();
final Scene scene = new Scene(box, 400, 300);
scene.setFill(Color.LIGHTGRAY);
TreeView<String> treeView = new TreeView<String>(rootNode);
treeView.setEditable(true);
treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
public TreeCell<String> call(TreeView<String> p) {
return new TextFieldTreeCellImpl();
}
});
box.getChildren().add(treeView);
stage.setScene(scene);
stage.show();
}
One thing that I did notice is that if I put the if statment in one of the handle methods there is no error.
Upvotes: 0
Views: 2169
Reputation: 1938
At the time that the TextFieldTreeCellImpl
object is constructed, there isn't a TreeItem
associated to it. That typically happens shortly after construction and outside of your control. Regardless, the call to getTreeItem()
is returning null
and so the chained called to getParent()
is then causing the NPE. The reason it works when you move it inside the handler is because that code is only called when an event is triggered (i.e. clicking on addMenuItem1
) and by that time, the treeItem
is populated in the cell.
I would add another EventHandler
for the onShowing
event of the ContextMenu
and put the check and set inside of there. See the example in the docs: ContextMenu Javadoc
Upvotes: 2