Results 1 to 7 of 7

Thread: Per item tooltip on tree?

  1. #1

    Default Per item tooltip on tree?

    I'm binding a Tree to a TreeStore and ran into a dead end on getting a per-tree item tooltip. I extended TreeBinder.update() to set TreeItem.setToolTip(String), but no tool tip is displayed.

    Any suggestions (either GWT 1.2 or 2.0 M1) would be appreciated.

  2. #2
    Sencha User
    Join Date
    May 2009
    Posts
    12

    Default

    I set this listener to the Tree that I want to catch mouse move events on. This works for the most part, but has the negative side effect of catching the parent folder as well.

    Code:
    static public class ToolTipListener? implements Listener
        {
            public void handleEvent(BaseEvent? event)
            {
                if (event.type == Events.OnMouseOver?)
                {
                    TreeEvent? treeEvent = (TreeEvent?) event;
                    Tree tree = treeEvent.container;
                    List<TreeItem?> items = tree.getItem(0).getItems();
                    for (TreeItem? item : items)
                    {
                        if (item.getAbsoluteLeft() <= treeEvent.getClientX() && treeEvent.getClientX() <= item.getAbsoluteLeft() + item.getOffsetWidth())
                        {
                            if (item.getAbsoluteTop() <= treeEvent.getClientY() && treeEvent.getClientY() <= item.getAbsoluteTop() + item.getOffsetHeight())
                            {
                                ModelData? modelData = item.getModel();
                                Map<String, Object> map = modelData.getProperties();
                                String name = (String) map.get("name");
                                ToolTipConfig? ttc = new ToolTipConfig?();
                                ttc.setTitle(name);
                                ttc.setText("Something meaningful goes here");
                                ttc.setTrackMouse(true);
                                tree.setToolTip(ttc);
                                tree.getToolTip().hide();
                                tree.getToolTip().show();
                            }
                        }
                    }
                }
            }
        }

  3. #3
    Ext User
    Join Date
    Jan 2009
    Location
    Luxembourg
    Posts
    13

    Default

    This is how I did it:
    -subclass TreeItemUI and override method onOverChange()
    -set the "ui" field (protected) of TreeItem to my own subclass of TreeItemUI


    Code:
    public class MyTreeItemUI extends TreeItemUI {
    
            public MyTreeItemUI(TreeItem item) {
                super(item);
            }
    
            @Override
            public void onOverChange(boolean over) {
                super.onOverChange(over);
                if (! rendered) {
                    return;
                }
                if (tree.getToolTip() != null) {
                    tree.getToolTip().hide();
                }
                if (over) {
                    ToolTipConfig ttc = new ToolTipConfig();
                    ttc.setText("whatever");
                    ttc.setTrackMouse(true);
                    tree.setToolTip(ttc);
                    tree.getToolTip().show();
                }
            }
        }
    Then when creating the TreeItem:

    Code:
            TreeItem item = new TreeItem("A TreeItem") {
                {
                    ui = new MyTreeItemUI(this);
                }
            };

  4. #4
    Ext User
    Join Date
    Jan 2009
    Location
    Luxembourg
    Posts
    13

    Default

    My previous solution seems to break sometimes in show() because targetXY is null... This doesn't happen in regular tooltips because you get a MOUSEMOVE event before showing the tooltip, but since here we call show() directly, we can't make sure that targetXY is not null. The best solution would be to call delayShow() instead, but since it is protected I had to mimic its behavior i.e. register a Timer and call it after the default showDelay.

    This solution is also better than the previous one because it subclasses GXT's TreeItem, so all you have to do is import this one instead of the standard one and then call setToolTip(String) on your TreeItem like you would normally, and that should do the trick.

    Code:
    /**
     * A replacement for {@link lu.vdl.vdlfmk.gwt.client.t2ui.tree.TreeItem} that handles tooltips.
     * Usage: just call {@link TreeItem#setToolTip(String)} or {@link TreeItem#setToolTip(com.extjs.gxt.ui.client.widget.tips.ToolTipConfig)}
     * like you would normally.
     *
     * @author ogerardin
     */
    public class TreeItem extends com.extjs.gxt.ui.client.widget.tree.TreeItem {
    
        // We have to keep a copy of the toolTipConfig because we need it when
        // activating the ToolTip (and it's private in Component)
        private ToolTipConfig toolTipConfig = null;
    
        public TreeItem() {
            ui = new MyTreeItemUI();
        }
    
        public TreeItem(String text) {
            super(text);
            ui = new MyTreeItemUI();
        }
    
        @Override
        public void setToolTip(String text) {
            if (toolTipConfig == null) {
              toolTipConfig = new ToolTipConfig();
            }
            toolTipConfig.setText(text);
        }
    
        @Override
        public void setToolTip(ToolTipConfig config) {
            toolTipConfig = config;
        }
    
        /**
         * A replacement for {@link TreeItemUI} that displays the {@link TreeItem}'s tooltip text using
         * the {@link com.extjs.gxt.ui.client.widget.tree.Tree Tree}'s {@link com.extjs.gxt.ui.client.widget.tips.ToolTip ToolTip}
         * instance.
         */
        private class MyTreeItemUI extends TreeItemUI {
    
            public MyTreeItemUI() {
                super(TreeItem.this);
            }
    
            @Override
            public void onOverChange(boolean over) {
                super.onOverChange(over);
                if (!rendered || toolTipConfig == null) {
                    return;
                }
                if (tree.getToolTip() != null) {
                    tree.getToolTip().hide();
                }
                if (over) {
                    // change the tooltip's config with the TreeItem's config
                    tree.setToolTip(toolTipConfig);
                    // schedule the display after showDelay
                    Timer showTimer = new Timer() {
                        public void run() {
                            tree.getToolTip().show();
                        }
                    };
                    showTimer.schedule(toolTipConfig.getShowDelay());
                }
            }
        }
    }

  5. #5
    Ext User
    Join Date
    Jan 2009
    Location
    Luxembourg
    Posts
    13

    Default

    This is my latest and hopefully last version. It takes care of special cases, for example when some TreeItems don't have a tooltip, and includes workarounds for various oddities of GXT (as usual). If anyone has a simpler solution, please post!

    Code:
    /**
     * A replacement for {@link lu.vdl.vdlfmk.gwt.client.t2ui.tree.TreeItem} that handles tooltips.
     * Usage: just call {@link TreeItem#setToolTip(String)} or {@link TreeItem#setToolTip(com.extjs.gxt.ui.client.widget.tips.ToolTipConfig)}
     * like you would normally.
     * @author ogerardin
     */
    public class TreeItem extends com.extjs.gxt.ui.client.widget.tree.TreeItem {
    
        private static final ToolTipConfig DISABLED_TOOLTIP_CONFIG = new ToolTipConfig() {
            {
                setEnabled(false);
                setShowDelay(Integer.MAX_VALUE);
            }
        };
    
    
        // We have to keep a copy of the toolTipConfig because we need it when
        // activating the ToolTip (and it's private in Component)
        private ToolTipConfig toolTipConfig = null;
    
        public TreeItem() {
            ui = new MyTreeItemUI();
        }
    
        public TreeItem(String text) {
            super(text);
            ui = new MyTreeItemUI();
        }
    
        @Override
        public void setToolTip(String text) {
            if (toolTipConfig == null) {
                toolTipConfig = new ToolTipConfig();
            }
            toolTipConfig.setText(text);
        }
    
        @Override
        public void setToolTip(ToolTipConfig config) {
            toolTipConfig = config;
        }
    
        /**
         * A replacement for {@link TreeItemUI} that displays the {@link TreeItem}'s tooltip text using
         * the {@link com.extjs.gxt.ui.client.widget.tree.Tree Tree}'s {@link com.extjs.gxt.ui.client.widget.tips.ToolTip ToolTip}
         * instance.
         */
        private class MyTreeItemUI extends TreeItemUI {
            private Timer showTimer = null;
    
            public MyTreeItemUI() {
                super(TreeItem.this);
            }
    
            @Override
            public void onOverChange(boolean over) {
                super.onOverChange(over);
                if (!rendered) {
                    return;
                }
    
                if (over && toolTipConfig != null) {
                    // Entering the TreeItem
    
                    // Change the tree's tooltip config with the TreeItem's config
                    // except "enabled" (we will take care of showing the tooltip)
                    toolTipConfig.setEnabled(false);
                    tree.setToolTip(toolTipConfig);
    
                    // Schedule the display after showDelay
                    showTimer = new Timer() {
                        public void run() {
                            if (tree.getToolTip().isEnabled()) {
                                tree.getToolTip().show();
                            }
                        }
                    };
                    showTimer.schedule(toolTipConfig.getShowDelay());
                }
                else {
                    // Leaving the TreeItem
                    if (showTimer != null) {
                        // if there was a timer, cancel it
                        showTimer.cancel();
                        showTimer = null;
                    }
    
                    // Disable the exising tooltip. This will hide it if it's displayed
                    tree.setToolTip(DISABLED_TOOLTIP_CONFIG);
                }
            }
        }
    }

  6. #6
    Sencha Premium Member
    Join Date
    Dec 2008
    Location
    Munich, Germany
    Posts
    183

    Default

    You could to the following if you don't mind using the browsers built-in tooltips:
    Code:
    public class TooltipTreeBinder<M extends ModelData> extends TreeBinder<FooModel> {
        public TooltipTreeBinder(Tree tree, TreeStore<FooModel> store) {
            super(tree, store);
        }
    
        @Override
        protected TreeItem createItem(FooModel element) {
            TreeItem item = super.createItem(element);
    
            item.setTitle(element.getDesiredProperty());
    
            return item;
        }
    }
    This solution was provided by "frederic.bastide" in this thread.

  7. #7
    Ext User
    Join Date
    Jan 2009
    Location
    Luxembourg
    Posts
    13

    Default

    Yes that's a simpler solution, but you have to give up the control that ToolTip provides (display duration, mouse tracking, , etc.), and the cross-browser compatibility isn't guaranteed.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •