Java SWT树菜单仅为树的一个级别显示

Java SWT树菜单仅为树的一个级别显示,java,menu,tree,swt,Java,Menu,Tree,Swt,我正在制作一个利用JavaSWT树结构的程序。这是一个基于从外部文件和用户输入中读取的数据构建的树。 在这棵树上,我还附加了一个右键单击菜单 主要的问题是,这棵树的菜单跨越了他的所有项目,我希望它只显示在某个层次上 我还想有不同的菜单或菜单选项为不同的树级别 所有树的创建都在一个函数中: public void createTree(final Composite container){ try{ for(Object element : container.getChi

我正在制作一个利用JavaSWT树结构的程序。这是一个基于从外部文件和用户输入中读取的数据构建的树。 在这棵树上,我还附加了一个右键单击菜单

主要的问题是,这棵树的菜单跨越了他的所有项目,我希望它只显示在某个层次上

我还想有不同的菜单或菜单选项为不同的树级别

所有树的创建都在一个函数中:

public void createTree(final Composite container){
    try{
        for(Object element : container.getChildren()){
            if(element instanceof Tree){
                ((Tree) element).dispose();
            }
        }
        // function to verify if the tree is still in my container composite, and if so, I'll dispose the tree, because I am going to construct a new one

        final Tree variantTree = new Tree(container, SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL);//creating new tree object
        variantTree.setBounds(10, 65, 400, 400);//dimensions
        //variantTree.setData("variant"); -- wanted to abuse this method to make a difference between the tree's level, 
             //but this attribute is shared across all the tree, and I cannot make a distinction between my levels

        if(..){
            //here I am using the data saved in a tree data structure to populate my SWT Tree
        }

        variantTree.addListener(SWT.Selection, new Listener(){
            //this is a listener used for the tree's checkboxes, using them to select different items from my tree
        });

        final Menu treeMenu = new Menu(variantTree);
        variantTree.setMenu(treeMenu);//adding the right click menu

        treeMenu.addMenuListener(new MenuAdapter(){
            //the menu's items are declared here: the buttons that I want to have and the their listeners
            //i am disposing the menu's items if there are any

                MenuItem newItem = new MenuItem(treeMenu, SWT.NONE);
                newItem.setText("new button...  ");
                newItem.addListener(SWT.Selection, new Listener(){

                    @Override
                    public void handleEvent(Event event) {
                            String item = variantTree.getSelection()[0].getText();//can I use this to make different menus for different tree levels?
                            for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
                                if(element.getName().equals(item)){
                            //opening a file dialog here and doing some operations
                            }
                      }
                });
        });

        //this is where I want to make the distinction between the levels of the tree, such as that I will have this menu show up only for the root of my tree, or the first level of the tree, since I will have multiple trees
        variantTree.addMenuDetectListener(new MenuDetectListener(){

            @Override
            public void menuDetected(MenuDetectEvent event) {
                // TODO Auto-generated method stub
                if(/*condition*/){ //I messed around with the tree's methods and attributes, nothing so far has come in handy to help me make a distinction between my tree's levels
                    event.doit = true;
                    //System.out.println(variantTree.getSelectionCount()); --I don't know if this can help me either, I tried to see if this will return differently for every level of the tree, but the return values is always 0
                    //find some kind of handle
                }else{
                    event.doit = false;
                }
            }

        });
另外,我想为树的第二级显示另一个菜单,是否可以使用
String item=variantTree.getSelection()[0].getText(),以某种方式修改以满足我的需要?比方说,
String item=variantTree.getSelection()[1].getText()用于第二级

我的SWT树每个根的最大深度为3,它看起来像这样:

root1-只需要此项目的菜单
|---儿童-1级
|------儿童-2级

root2-只希望此项的菜单
|---儿童-1级
|-------儿童-2级


谢谢。

我用以下方法解决了我的问题。 如果您实际看到了我的代码,则有以下几行:

for(Node element : TestControl.getTree().getChildren()){//getting the tree data structure that I have saved in a static way via a class
   if(element.getName().equals(item)){
         //opening a file dialog here and doing some operations
   }
}
我获取树数据结构的第一级,然后验证SWT树的根名称是否等于树数据结构的根

使用相同的方法,这将导致SWT树的菜单侦听器结束:

variantTree.addMenuDetectListener(new MenuDetectListener(){

            @Override
            public void menuDetected(MenuDetectEvent event) {
                // TODO Auto-generated method stub
                for(Node element : TestControl.getTree().getChildren()){
                    if(variantTree.getSelection()[0].getText().equals(element.getName())){
                        event.doit = true;
                        break;//need this, because it will propagate only to the last item, or it will have a strange behaviour
                    }else{
                        event.doit = false;
                    }
                }
            }

        });
其中
元素
是我的树数据结构中的一个节点。
希望它能帮助任何有同样问题的人。

无需比较
TreeItem
文本,只需通过检查是否有父项来检查项目的级别

public static void main(String[] args)
{
    Display display = Display.getDefault();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout());

    final Tree tree = new Tree(shell, SWT.NONE);

    for (int i = 0; i < 10; i++)
    {
        TreeItem item = new TreeItem(tree, SWT.NONE);
        item.setText("Parent " + i);

        for (int j = 0; j < 3; j++)
        {
            TreeItem child = new TreeItem(item, SWT.NONE);
            child.setText("Child " + i + " " + j);

            for (int k = 0; k < 3; k++)
            {
                TreeItem grandChild = new TreeItem(child, SWT.NONE);
                grandChild.setText("Child " + i + " " + j + " " + k);
            }
        }
    }

    final Menu menu = new Menu(tree);
    tree.setMenu(menu);
    tree.addMenuDetectListener(new MenuDetectListener()
    {
        @Override
        public void menuDetected(MenuDetectEvent e)
        {
            TreeItem treeItem = tree.getSelection()[0];

            e.doit = getLevelOfItem(treeItem) < 2;
        }
    });
    menu.addMenuListener(new MenuAdapter()
    {
        public void menuShown(MenuEvent e)
        {
            TreeItem item = tree.getSelection()[0];

            setMenu(menu, item);
        }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

private static void setMenu(Menu menu, TreeItem item)
{
    int level = getLevelOfItem(item);

    MenuItem[] items = menu.getItems();
    for (MenuItem i : items)
    {
        i.dispose();
    }

    switch (level)
    {
        case 0:
            for(int i = 0; i < 2; i++)
            {
                MenuItem newItem = new MenuItem(menu, SWT.NONE);
                newItem.setText("Menu item " + i);
            }
            break;
        case 1:
            for(int i = 0; i < 4; i++)
            {
                MenuItem newItem = new MenuItem(menu, SWT.NONE);
                newItem.setText("Menu item " + i);
            }
            break;
    }
}

private static int getLevelOfItem(TreeItem item)
{
    int counter = 0;

    while(item.getParentItem() != null)
    {
        item = item.getParentItem();
        counter++;
    }

    return counter;
}
publicstaticvoidmain(字符串[]args)
{
Display=Display.getDefault();
最终外壳=新外壳(显示);
shell.setText(“StackOverflow”);
setLayout(新的FillLayout());
最终树=新树(shell,SWT.NONE);
对于(int i=0;i<10;i++)
{
TreeItem=新的TreeItem(树,SWT.NONE);
项目.setText(“父项”+i);
对于(int j=0;j<3;j++)
{
TreeItem子项=新的TreeItem(项目,SWT.NONE);
setText(“child”+i+“”+j);
对于(int k=0;k<3;k++)
{
TreeItem孙子=新的TreeItem(子项,SWT.NONE);
孙子.setText(“子项”+i+“”+j+“”+k);
}
}
}
最终菜单=新菜单(树);
设置菜单(菜单);
addMenuDetectListener(新的MenuDetectListener()
{
@凌驾
公共无效菜单检测(菜单检测事件)
{
TreeItem TreeItem=tree.getSelection()[0];
e、 doit=getLevelOfItem(treeItem)<2;
}
});
menu.addMenuListener(新的MenuAdapter()
{
公共无效menuShown(MenuEvent e)
{
TreeItem=tree.getSelection()[0];
设置菜单(菜单,项目);
}
});
shell.pack();
shell.open();
而(!shell.isDisposed())
{
如果(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
私有静态无效设置菜单(菜单菜单,树项)
{
int level=getLevelOfItem(项目);
MenuItem[]items=menu.getItems();
用于(菜单项i:项目)
{
i、 处置();
}
开关(电平)
{
案例0:
对于(int i=0;i<2;i++)
{
MenuItem newItem=newmenuitem(菜单,SWT.NONE);
newItem.setText(“菜单项”+i);
}
打破
案例1:
对于(int i=0;i<4;i++)
{
MenuItem newItem=newmenuitem(菜单,SWT.NONE);
newItem.setText(“菜单项”+i);
}
打破
}
}
私有静态int getLevelOfItem(TreeItem项)
{
int计数器=0;
while(item.getParentItem()!=null)
{
item=item.getParentItem();
计数器++;
}
返回计数器;
}

这将为0级和1级显示不同的菜单,而为2级显示没有菜单。

getLevelOfItem
从何而来?这是我应该做的一个函数吗?@Justplayit94向下滚动,代码就在那里。如果我想为树的第2级创建一个完全不同的菜单呢?@Justplayit94我的代码已经这样做了。只要看看
setMenu()
方法就可以了。哦,你已经考虑过了。奇怪的是,如果我采用相同的思维方式,那么树的第一级每次都应该让
getParentItem()
等于
null
,而其他级别应该返回
TreeItem
,但是当我在侦听器中使用它时,
menuDetect()
方法中树的每个项目都返回
null
。我认为这与SWT考虑选择的方式有关,右键单击不是选择。