如何测试树项是否是 javafx 中树视图的根节点?
How to test if a tree item is the root node for the treeview in javafx?
我一直试图阻止我的程序删除我的树视图的根节点,但每当我尝试这样做时,我的程序在编译期间都会给我一个 "java.lang.reflect.InvocationTargetException",并且程序将无法启动。我不太确定为什么它不会启动。
这是我的 TextFieldTreeCellImpl class 发生错误的地方:
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();
}
}
}
这是我得到的错误:
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$launchApplication7(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda/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.call(CopyOfMain.java:48)
at application.CopyOfMain.call(CopyOfMain.java:1)
at com.sun.javafx.scene.control.skin.TreeViewSkin.createCell(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin.lambda$new3(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin$$Lambda5/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.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$launchApplication13(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda/1520696636.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/1051754451.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null4(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/1933975749.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater5(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/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$null1(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda/1109371569.run(Unknown Source)
... 1 more
Exception running application application.CopyOfMain
这是我的主要 Class 虽然我不认为它是真实的:
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();
}
我确实注意到的一件事是,如果我将 if 语句放在其中一个句柄方法中,则没有错误。
在构造 TextFieldTreeCellImpl
对象时,没有 TreeItem
与之关联。这通常发生在施工后不久并且超出您的控制范围。无论如何,对 getTreeItem()
的调用将返回 null
,因此对 getParent()
的链式调用会导致 NPE。当您将它移到处理程序中时它起作用的原因是因为该代码仅在触发事件时调用(即单击 addMenuItem1
),到那时,treeItem
已填充到单元格中。
我会为 ContextMenu
的 onShowing
事件添加另一个 EventHandler
并将检查和设置放在里面。请参阅文档中的示例:ContextMenu Javadoc
我一直试图阻止我的程序删除我的树视图的根节点,但每当我尝试这样做时,我的程序在编译期间都会给我一个 "java.lang.reflect.InvocationTargetException",并且程序将无法启动。我不太确定为什么它不会启动。
这是我的 TextFieldTreeCellImpl class 发生错误的地方:
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();
}
}
}
这是我得到的错误:
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$launchApplication7(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda/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.call(CopyOfMain.java:48)
at application.CopyOfMain.call(CopyOfMain.java:1)
at com.sun.javafx.scene.control.skin.TreeViewSkin.createCell(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin.lambda$new3(Unknown Source)
at com.sun.javafx.scene.control.skin.TreeViewSkin$$Lambda5/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.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$launchApplication13(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda/1520696636.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/1051754451.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null4(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/1933975749.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater5(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda/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$null1(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda/1109371569.run(Unknown Source)
... 1 more
Exception running application application.CopyOfMain
这是我的主要 Class 虽然我不认为它是真实的:
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();
}
我确实注意到的一件事是,如果我将 if 语句放在其中一个句柄方法中,则没有错误。
在构造 TextFieldTreeCellImpl
对象时,没有 TreeItem
与之关联。这通常发生在施工后不久并且超出您的控制范围。无论如何,对 getTreeItem()
的调用将返回 null
,因此对 getParent()
的链式调用会导致 NPE。当您将它移到处理程序中时它起作用的原因是因为该代码仅在触发事件时调用(即单击 addMenuItem1
),到那时,treeItem
已填充到单元格中。
我会为 ContextMenu
的 onShowing
事件添加另一个 EventHandler
并将检查和设置放在里面。请参阅文档中的示例:ContextMenu Javadoc