我是JavaFX的新手。我使用此引用创建了自定义TreeCell:-

http://fxexperience.com/2012/05/listview-custom-cell-factories-and-context-menus/

它对我来说非常有效。但是我的情况是我不想将此上下文菜单应用于子节点。在开始时只有一个TreeItem,而在以后的阶段这些TreeItem具有子对象,因此尝试检查isLeaf()方法没有任何意义,因为在开始时TreeItem在叶级别,但是后来成为父级。

所以任何想法我怎么能做到这一点。

非常感谢。

更新:
在我的项目的初始阶段,有一棵树,有三个孩子(邮件服务提供商),如下所示:

--- Gmail
---雅虎
---雷迪夫


在我连接这些提供程序之后,它们将具有以下结构:-

邮箱
| ____收件箱
| ____已发送
雅虎
| ___收件箱
| ___已发送
| ___草稿
雷迪夫
| ___收件箱


现在我只希望在Gmail,Yahoo和rediff上使用上下文菜单,而不在收件箱或已发送邮件上。

我知道setContextmenu()方法,但是它可用于TreeView而不可用于TreeItem。

最佳答案

我将使您的树项成为TreeItem的后代类(如public class ProviderTreeItem extends TreeItem),并成为具有BoxBoxItem的框的后代。

这样,您将不会测试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();
}


}

关于javafx - 我可以在TreeItem中添加上下文菜单,然后在JavaFX中添加TreeView吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20676176/

10-09 01:13