【问题标题】:Java SWT Tree Menu Shown only for one level of the treeJava SWT 树形菜单 仅针对树的一层显示
【发布时间】:2016-08-30 06:44:51
【问题描述】:

我正在制作一个使用 java SWT 的 Tree 结构的程序。这棵树是建立在从外部文件和用户输入中读取的数据之上的。 在这棵树上,我还附加了一个右键菜单。

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

我还想为不同的树级别设置不同的菜单或菜单选项。

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

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级

谢谢。

【问题讨论】:

    标签: java menu tree swt


    【解决方案1】:

    无需比较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;
    }
    

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

    【讨论】:

    • getLevelOfItem 来自哪里?这是我应该做的功能吗?
    • @Justplayit94 向下滚动,代码就在那里。
    • 如果我想要树的第 2 级完全不同的菜单怎么办?
    • @Justplayit94 我的代码已经这样做了。看看setMenu() 方法就知道了。
    • 哦,你什么都想好了。奇怪的是,如果我应用相同的思维方式,树的第一级每次都应该有getParentItem() 等于null,其他级别应该返回一个TreeItem,但是当我在监听器中使用它时,每个在 menuDetect() 方法中返回的树的项目 null。我认为这与 SWT 考虑选择的方式有关,右键单击不是选择。
    【解决方案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;
                        }
                    }
                }
    
            });
    

    element 是我的树数据结构中的一个节点。 希望对遇到同样问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-21
      • 2011-08-11
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多