Announcement Announcement Module
Collapse
No announcement yet.
Node aware popup menu Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Node aware popup menu

    I recently downloaded RCP and have been modifying PetClinic into an order entry app. I have my CustomerView (based on OwnersView) that displays a tree of customers and their orders. Right now, the same popup menu displays for both types of node. I would like to list different commands in the popup depending on the node type.

    What is the 'best practice' approach to doing this? My Swing experiences were a long time ago, and the collaboration structure of the popup is still pretty fuzzy. Seems I have a dual learning curve to overcome. :shock:

    Thanks.

  • #2
    To create a context based popupmenu, you can use the PopupMenuMouseListener helper class.

    The PopupMenuMouseListener can be used in two ways:
    1. use a static PopupMenu: Use the constructor:
    Code:
    JTree tree = ...;
    JPopupMenu popupMenu = ...;
    tree.addMouseListener(new PopupMenuMouseListener(popupMenu));
    2. use a dynamic PopupMenu: Create an anonymous inner class:
    Code:
    JTree tree = ...;
    tree.addMouseListener(new PopupMenuMouseListener() {
        protected JPopupMenu getPopupMenu() {
            // create your popup menu here based on the selection
        }
    });


    To create a PopupMenu, you first have to create a CommandGroup. The CommandGroup has utility methods to create a ToolBar, PopupMenu, and so on, ...

    Code:
    CommandGroup group = getWindowCommandManager().createCommandGroup("ownerCommandGroup",
                    new Object[] { renameCommand, "separator", "deleteCommand", "separator", "propertiesCommand" });
    JPopupMenu poupMenu = group.createPopupMenu();

    So you would be creating two different CommandGroups (one for Customer, and one for Order), and return the correct PopupMenu for the selected node.

    Hope this helps.

    Peter

    Comment


    • #3
      to pdbruycker

      But in command body,such as in renameCommand,is there a way to get the reference of the tree(not use inner class)?
      thanks.

      Comment


      • #4
        If you don't want to use inner classes for your commands, create a normal class, but provide a constructor to pass your view/tree/whatever:

        Code:
        public class RenameCommand extends ... {
            private OwnerManagerView view;
            public RenameCommand(OwnerManagerView view) {
                 this.view = view;
            }
        
            ...
        }
        Now you can use the methods on OwnerManagerView. If you need to manipulate the treecontrol, provide methods on the view class that have this functionality.

        Hope this helps,

        Peter

        Comment


        • #5
          thanks pdbruycker.
          it may be the only method that I can use now,
          but I think the component infomation may be involved in ActionCommand .
          thanks again.

          Comment


          • #6
            Peter, thanks for the tip! 8)
            Here's final version:
            Code:
                    customersTree.addMouseListener(new PopupMenuMouseListener() {
                        protected JPopupMenu getPopupMenu() {
                            JPopupMenu popupToShow = null;
                            if ( getSelectedNode().getUserObject() instanceof Customer) {
                                popupToShow = createCustomerPopupContextMenu();
                            } else {
                                popupToShow = createOrderPopupContextMenu();
                            }
                            return popupToShow;
                        }});
            I had everything in place except overriding the mouse listener. :oops:

            In looking at the code, it seems problemmatic to do something like this if you didn't have direct access to the component. If the MouseEvent were propagated to the getPopupMenu method, I think it would be more flexible.

            Comment


            • #7
              I think that if you don't have direct access to the component, there still would be no way to get access to the MouseEvent, or am I missing something :?

              Comment


              • #8
                If you change getPopupMenu() to getPopupMenu(MouseEvent e) you could get the component via e.getComponent() and drill-down that way instead of having to keep a reference to the tree itself.

                For instance, if I had multiple views, I could refactor out the mouselistener and not have to duplicate the code or give it its own reference to the tree.

                Granted I could override showPopupMenu(), but that's not as convenient.

                Comment


                • #9
                  rstearns01,

                  PopupMenuMouseListener has a method onAboutToShow(MouseEvent event) which can be used to access the mouse event that caused the popup.

                  Ollie

                  Comment


                  • #10
                    Ollie,

                    True, you could override that as well, but it's even further up the logic chain than showPopupMenu(). Plus, it doesn't really fit the pupose of that method (see the JavaDoc comment) and with the menu instance variable private, you can't set it there. getPopupMenu() is the correct method to override to provide dynamic menus.

                    Peter's alternative method of handling this issue, have a subclass with an instance variable containing the tree, is perfectly legit. I just think we're missing a bet in making the class more flexible by not providing it the mouse event.

                    Cheers.

                    Comment


                    • #11
                      Randy,

                      I agree it does make more sence pass the mouse event into getPopupMenu so I've added a getPopupMenu(MouseEvent e) method to PopupMenuMouseListener :-)

                      Ollie

                      Comment


                      • #12
                        Cool. 8)

                        Comment

                        Working...
                        X