我是JavaFX的新手.我使用此引用制作了自定义TreeCell: -
http://fxexperience.com/2012/05/listview-custom-cell-factories-and-context-menus/
它对我来说非常有用.但我的情况是我不想将此上下文菜单应用于子节点.在开始时只有一个TreeItems,并且在稍后阶段这些TreeItems具有子项,因此尝试检查isLeaf()方法没有意义,因为在启动TreeItems时处于叶级但后来它们变为父级.
所以任何想法我怎样才能实现这一目标.
非常感谢.
更新:
在我的项目的初始阶段,有一个树有三个孩子(邮件服务提供商)如下: -
---Gmail ---Yahoo ---Rediff
在我连接这些提供商后,他们有这种结构: -
Gmail |____Inbox |____Sent Yahoo |___Inbox |___Sent |___Drafts Rediff |___Inbox
现在我只需要Gmail,Yahoo和rediff上下文菜单,而不是收件箱或已发送项目.
我知道setContextmenu()方法,但这可用于TreeView而不适用于TreeItem.
我会让你的树项成为TreeItem的后代类,public class ProviderTreeItem extends TreeItem
并使用像BoxTreeItem这样的框来创建不同的后代.
这样你就不会测试isLeaf,但你可以测试TreeItem类型.
if (thisTreeItem.getClass() == ProviderTreeItem.class) thisTreeItem.setContextmenu(providerContextMenu) else thisTreeItem.setContextmenu(boxContextMenu)
从子类TreeItem获取上下文菜单会更容易.
您实际上不需要继承TreeItem,您可以使用名称或类似userData对象来区分节点类型.如果是子类,则可以向不同的节点类型添加不同的方法和属性.
例如,这些框需要一个数据结构来保存电子邮件,但提供者不需要这样.提供商需要一个网址和密码等,但这些框不需要.
这是更新的例子.
import javafx.application.Application; import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.util.Callback; public class TVexample extends Application { public abstract class AbstractTreeItem extends TreeItem{ public abstract ContextMenu getMenu(); } public class ProviderTreeItem extends AbstractTreeItem{ // make class vars here like psswd public ProviderTreeItem(String name) { this.setValue(name); } @Override public ContextMenu getMenu(){ MenuItem addInbox = new MenuItem("add inbox"); addInbox.setOnAction(new EventHandler() { public void handle(Event t) { BoxTreeItem newBox = new BoxTreeItem("inbox"); getChildren().add(newBox); } }); return new ContextMenu(addInbox); } } public class BoxTreeItem extends AbstractTreeItem{ //private List<String> emails = new LinkedList<>(); public BoxTreeItem(String name) { this.setValue(name); } @Override public ContextMenu getMenu() { return new ContextMenu(new MenuItem("test")); } } private final class TreeCellImpl extends TreeCell<String> { @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { setText(getItem() == null ? "" : getItem().toString()); setGraphic(getTreeItem().getGraphic()); setContextMenu(((AbstractTreeItem) getTreeItem()).getMenu()); } } } @Override public void start(Stage primaryStage) { StackPane sceneRoot = new StackPane(); TreeItem treeRoot = new TreeItem(); treeRoot.setExpanded(true); ProviderTreeItem gm = new ProviderTreeItem("gmail"); ProviderTreeItem yh = new ProviderTreeItem("yahoo"); treeRoot.getChildren().addAll(gm,yh); TreeView<String> treeView = new TreeView<String>(treeRoot); treeView.setShowRoot(false); treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){ @Override public TreeCell<String> call(TreeView<String> p) { return new TreeCellImpl(); } }); sceneRoot.getChildren().add(treeView); Scene scene = new Scene(sceneRoot, 300, 500); primaryStage.setScene(scene); primaryStage.show(); }
}