]> source.dussan.org Git - vaadin-framework.git/commitdiff
Split Tree into widget + paintable
authorArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 07:58:31 +0000 (09:58 +0200)
committerArtur Signell <artur@vaadin.com>
Tue, 31 Jan 2012 08:00:15 +0000 (10:00 +0200)
src/com/vaadin/terminal/gwt/client/ui/VTree.java
src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java [new file with mode: 0644]
src/com/vaadin/ui/Tree.java

index de7f6c652a2309a9fac20224e79df1a240f13666..be337ae0cb3eda17c49be5d8bc4573bdda90d8e9 100644 (file)
@@ -40,10 +40,10 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.TooltipInfo;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.VTooltip;
 import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
 import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler;
@@ -58,9 +58,9 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
 /**
  * 
  */
-public class VTree extends FocusElementPanel implements VPaintableWidget,
-        VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler,
-        KeyDownHandler, SubPartAware, ActionOwner {
+public class VTree extends FocusElementPanel implements VHasDropHandler,
+        FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
+        SubPartAware, ActionOwner {
 
     public static final String CLASSNAME = "v-tree";
 
@@ -71,17 +71,17 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
 
     private static final int CHARCODE_SPACE = 32;
 
-    private final FlowPanel body = new FlowPanel();
+    final FlowPanel body = new FlowPanel();
 
-    private Set<String> selectedIds = new HashSet<String>();
-    private ApplicationConnection client;
-    private String paintableId;
-    private boolean selectable;
-    private boolean isMultiselect;
+    Set<String> selectedIds = new HashSet<String>();
+    ApplicationConnection client;
+    String paintableId;
+    boolean selectable;
+    boolean isMultiselect;
     private String currentMouseOverKey;
-    private TreeNode lastSelection;
-    private TreeNode focusedNode;
-    private int multiSelectMode = MULTISELECT_MODE_DEFAULT;
+    TreeNode lastSelection;
+    TreeNode focusedNode;
+    int multiSelectMode = MULTISELECT_MODE_DEFAULT;
 
     private final HashMap<String, TreeNode> keyToNode = new HashMap<String, TreeNode>();
 
@@ -91,23 +91,23 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
      */
     private final HashMap<String, String> actionMap = new HashMap<String, String>();
 
-    private boolean immediate;
+    boolean immediate;
 
-    private boolean isNullSelectionAllowed = true;
+    boolean isNullSelectionAllowed = true;
 
-    private boolean disabled = false;
+    boolean disabled = false;
 
-    private boolean readonly;
+    boolean readonly;
 
-    private boolean rendering;
+    boolean rendering;
 
     private VAbstractDropHandler dropHandler;
 
-    private int dragMode;
+    int dragMode;
 
     private boolean selectionHasChanged = false;
 
-    private String[] bodyActionKeys;
+    String[] bodyActionKeys;
 
     public VLazyExecutor iconLoaded = new VLazyExecutor(50,
             new ScheduledCommand() {
@@ -206,24 +206,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
         }
     }
 
-    private void updateActionMap(UIDL c) {
-        final Iterator<?> it = c.getChildIterator();
-        while (it.hasNext()) {
-            final UIDL action = (UIDL) it.next();
-            final String key = action.getStringAttribute("key");
-            final String caption = action.getStringAttribute("caption");
-            actionMap.put(key + "_c", caption);
-            if (action.hasAttribute("icon")) {
-                // TODO need some uri handling ??
-                actionMap.put(key + "_i", client.translateVaadinUri(action
-                        .getStringAttribute("icon")));
-            } else {
-                actionMap.remove(key + "_i");
-            }
-        }
-
-    }
-
     public String getActionCaption(String actionKey) {
         return actionMap.get(actionKey + "_c");
     }
@@ -232,94 +214,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
         return actionMap.get(actionKey + "_i");
     }
 
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        // Ensure correct implementation and let container manage caption
-        if (client.updateComponent(this, uidl, true)) {
-            return;
-        }
-
-        rendering = true;
-
-        this.client = client;
-
-        if (uidl.hasAttribute("partialUpdate")) {
-            handleUpdate(uidl);
-            rendering = false;
-            return;
-        }
-
-        paintableId = uidl.getId();
-
-        immediate = uidl.hasAttribute("immediate");
-
-        disabled = uidl.getBooleanAttribute("disabled");
-        readonly = uidl.getBooleanAttribute("readonly");
-
-        dragMode = uidl.hasAttribute("dragMode") ? uidl
-                .getIntAttribute("dragMode") : 0;
-
-        isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
-
-        if (uidl.hasAttribute("alb")) {
-            bodyActionKeys = uidl.getStringArrayAttribute("alb");
-        }
-
-        body.clear();
-        // clear out any references to nodes that no longer are attached
-        keyToNode.clear();
-        TreeNode childTree = null;
-        UIDL childUidl = null;
-        for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
-            childUidl = (UIDL) i.next();
-            if ("actions".equals(childUidl.getTag())) {
-                updateActionMap(childUidl);
-                continue;
-            } else if ("-ac".equals(childUidl.getTag())) {
-                updateDropHandler(childUidl);
-                continue;
-            }
-            childTree = new TreeNode();
-            childTree.updateFromUIDL(childUidl, client);
-            body.add(childTree);
-            childTree.addStyleDependentName("root");
-            childTree.childNodeContainer.addStyleDependentName("root");
-        }
-        if (childTree != null && childUidl != null) {
-            boolean leaf = !childUidl.getTag().equals("node");
-            childTree.addStyleDependentName(leaf ? "leaf-last" : "last");
-            childTree.childNodeContainer.addStyleDependentName("last");
-        }
-        final String selectMode = uidl.getStringAttribute("selectmode");
-        selectable = !"none".equals(selectMode);
-        isMultiselect = "multi".equals(selectMode);
-
-        if (isMultiselect) {
-            multiSelectMode = uidl.getIntAttribute("multiselectmode");
-        }
-
-        selectedIds = uidl.getStringArrayVariableAsSet("selected");
-
-        // Update lastSelection and focusedNode to point to *actual* nodes again
-        // after the old ones have been cleared from the body. This fixes focus
-        // and keyboard navigation issues as described in #7057 and other
-        // tickets.
-        if (lastSelection != null) {
-            lastSelection = keyToNode.get(lastSelection.key);
-        }
-        if (focusedNode != null) {
-            setFocusedNode(keyToNode.get(focusedNode.key));
-        }
-
-        if (lastSelection == null && focusedNode == null
-                && !selectedIds.isEmpty()) {
-            setFocusedNode(keyToNode.get(selectedIds.iterator().next()));
-            focusedNode.setFocused(false);
-        }
-
-        rendering = false;
-
-    }
-
     /**
      * Returns the first root node of the tree or null if there are no root
      * nodes.
@@ -366,7 +260,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
 
         drag.getDropDetails().put("itemIdOver", currentMouseOverKey);
         if (currentMouseOverKey != null) {
-            TreeNode treeNode = keyToNode.get(currentMouseOverKey);
+            TreeNode treeNode = getNodeByKey(currentMouseOverKey);
             VerticalDropLocation detail = treeNode.getDropDetail(drag
                     .getCurrentGwtEvent());
             Boolean overTreeNode = null;
@@ -388,7 +282,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
         return treeNode == null ? null : treeNode.key;
     }
 
-    private void updateDropHandler(UIDL childUidl) {
+    void updateDropHandler(UIDL childUidl) {
         if (dropHandler == null) {
             dropHandler = new VAbstractDropHandler() {
 
@@ -430,7 +324,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
                                             .getDropDetails().get("detail");
                                     if (curDetail == detail
                                             && newKey.equals(currentMouseOverKey)) {
-                                        keyToNode.get(newKey).emphasis(detail);
+                                        getNodeByKey(newKey).emphasis(detail);
                                     }
                                     /*
                                      * Else drag is already on a different
@@ -452,7 +346,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
 
                 private void cleanUp() {
                     if (currentMouseOverKey != null) {
-                        keyToNode.get(currentMouseOverKey).emphasis(null);
+                        getNodeByKey(currentMouseOverKey).emphasis(null);
                         currentMouseOverKey = null;
                     }
                 }
@@ -465,7 +359,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
 
                 @Override
                 public VPaintableWidget getPaintable() {
-                    return VTree.this;
+                    return VPaintableMap.get(client).getPaintable(VTree.this);
                 }
 
                 public ApplicationConnection getApplicationConnection() {
@@ -477,24 +371,12 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
         dropHandler.updateAcceptRules(childUidl);
     }
 
-    private void handleUpdate(UIDL uidl) {
-        final TreeNode rootNode = keyToNode.get(uidl
-                .getStringAttribute("rootKey"));
-        if (rootNode != null) {
-            if (!rootNode.getState()) {
-                // expanding node happened server side
-                rootNode.setState(true, false);
-            }
-            rootNode.renderChildNodes(uidl.getChildIterator());
-        }
-    }
-
     public void setSelected(TreeNode treeNode, boolean selected) {
         if (selected) {
             if (!isMultiselect) {
                 while (selectedIds.size() > 0) {
                     final String id = selectedIds.iterator().next();
-                    final TreeNode oldSelection = keyToNode.get(id);
+                    final TreeNode oldSelection = getNodeByKey(id);
                     if (oldSelection != null) {
                         // can be null if the node is not visible (parent
                         // collapsed)
@@ -563,15 +445,15 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
 
         public String key;
 
-        private String[] actionKeys = null;
+        String[] actionKeys = null;
 
-        private boolean childrenLoaded;
+        boolean childrenLoaded;
 
-        private Element nodeCaptionDiv;
+        Element nodeCaptionDiv;
 
         protected Element nodeCaptionSpan;
 
-        private FlowPanel childNodeContainer;
+        FlowPanel childNodeContainer;
 
         private boolean open;
 
@@ -760,14 +642,14 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
             }
 
             if (target == nodeCaptionSpan) {
-                client.handleTooltipEvent(event, VTree.this, key);
+                client.handleWidgetTooltipEvent(event, VTree.this, key);
             }
 
             final boolean inCaption = target == nodeCaptionSpan
                     || (icon != null && target == icon.getElement());
             if (inCaption
-                    && client
-                            .hasEventListeners(VTree.this, ITEM_CLICK_EVENT_ID)
+                    && client.hasWidgetEventListeners(VTree.this,
+                            ITEM_CLICK_EVENT_ID)
 
                     && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
                 fireClick(event);
@@ -828,7 +710,8 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
                     if (mouseDownEvent != null) {
                         // start actual drag on slight move when mouse is down
                         VTransferable t = new VTransferable();
-                        t.setDragSource(VTree.this);
+                        t.setDragSource(VPaintableMap.get(client).getPaintable(
+                                VTree.this));
                         t.setData("itemId", key);
                         VDragEvent drag = VDragAndDropManager.get().startDrag(
                                 t, mouseDownEvent, true);
@@ -944,71 +827,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
             setWidget(childNodeContainer);
         }
 
-        public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-            setText(uidl.getStringAttribute("caption"));
-            key = uidl.getStringAttribute("key");
-
-            keyToNode.put(key, this);
-
-            if (uidl.hasAttribute("al")) {
-                actionKeys = uidl.getStringArrayAttribute("al");
-            }
-
-            if (uidl.getTag().equals("node")) {
-                if (uidl.getChildCount() == 0) {
-                    childNodeContainer.setVisible(false);
-                } else {
-                    renderChildNodes(uidl.getChildIterator());
-                    childrenLoaded = true;
-                }
-            } else {
-                addStyleName(CLASSNAME + "-leaf");
-            }
-            if (uidl.hasAttribute("style")) {
-                addStyleName(CLASSNAME + "-" + uidl.getStringAttribute("style"));
-                Widget.setStyleName(nodeCaptionDiv, CLASSNAME + "-caption-"
-                        + uidl.getStringAttribute("style"), true);
-                childNodeContainer.addStyleName(CLASSNAME + "-children-"
-                        + uidl.getStringAttribute("style"));
-            }
-
-            String description = uidl.getStringAttribute("descr");
-            if (description != null && client != null) {
-                // Set tooltip
-                TooltipInfo info = new TooltipInfo(description);
-                client.registerTooltip(VTree.this, key, info);
-            } else {
-                // Remove possible previous tooltip
-                client.registerTooltip(VTree.this, key, null);
-            }
-
-            if (uidl.getBooleanAttribute("expanded") && !getState()) {
-                setState(true, false);
-            }
-
-            if (uidl.getBooleanAttribute("selected")) {
-                setSelected(true);
-                // ensure that identifier is in selectedIds array (this may be a
-                // partial update)
-                selectedIds.add(key);
-            }
-
-            if (uidl.hasAttribute("icon")) {
-                if (icon == null) {
-                    icon = new Icon(client);
-                    DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
-                            icon.getElement(), nodeCaptionSpan);
-                }
-                icon.setUri(uidl.getStringAttribute("icon"));
-            } else {
-                if (icon != null) {
-                    DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv),
-                            icon.getElement());
-                    icon = null;
-                }
-            }
-        }
-
         public boolean isLeaf() {
             String[] styleNames = getStyleName().split(" ");
             for (String styleName : styleNames) {
@@ -1019,7 +837,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
             return false;
         }
 
-        private void setState(boolean state, boolean notifyServer) {
+        void setState(boolean state, boolean notifyServer) {
             if (open == state) {
                 return;
             }
@@ -1050,38 +868,14 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
             }
         }
 
-        private boolean getState() {
+        boolean getState() {
             return open;
         }
 
-        private void setText(String text) {
+        void setText(String text) {
             DOM.setInnerText(nodeCaptionSpan, text);
         }
 
-        private void renderChildNodes(Iterator<?> i) {
-            childNodeContainer.clear();
-            childNodeContainer.setVisible(true);
-            while (i.hasNext()) {
-                final UIDL childUidl = (UIDL) i.next();
-                // actions are in bit weird place, don't mix them with children,
-                // but current node's actions
-                if ("actions".equals(childUidl.getTag())) {
-                    updateActionMap(childUidl);
-                    continue;
-                }
-                final TreeNode childTree = new TreeNode();
-                childTree.updateFromUIDL(childUidl, client);
-                childNodeContainer.add(childTree);
-                if (!i.hasNext()) {
-                    childTree
-                            .addStyleDependentName(childTree.isLeaf() ? "leaf-last"
-                                    : "last");
-                    childTree.childNodeContainer.addStyleDependentName("last");
-                }
-            }
-            childrenLoaded = true;
-        }
-
         public boolean isChildrenLoaded() {
             return childrenLoaded;
         }
@@ -1231,6 +1025,34 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
             Util.scrollIntoViewVertically(nodeCaptionDiv);
         }
 
+        public void setIcon(String iconUrl) {
+            if (iconUrl != null) {
+                // Add icon if not present
+                if (icon == null) {
+                    icon = new Icon(client);
+                    DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
+                            icon.getElement(), nodeCaptionSpan);
+                }
+                icon.setUri(iconUrl);
+            } else {
+                // Remove icon if present
+                if (icon != null) {
+                    DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv),
+                            icon.getElement());
+                    icon = null;
+                }
+            }
+        }
+
+        public void setNodeStyleName(String styleName) {
+            addStyleName(TreeNode.CLASSNAME + "-" + styleName);
+            setStyleName(nodeCaptionDiv, TreeNode.CLASSNAME + "-caption-"
+                    + styleName, true);
+            childNodeContainer.addStyleName(TreeNode.CLASSNAME + "-children-"
+                    + styleName);
+
+        }
+
     }
 
     public VDropHandler getDropHandler() {
@@ -2243,7 +2065,22 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
         }
     }
 
-    public Widget getWidgetForPaintable() {
-        return this;
+    public void registerAction(String key, String caption, String iconUrl) {
+        actionMap.put(key + "_c", caption);
+        if (iconUrl != null) {
+            actionMap.put(key + "_i", iconUrl);
+        } else {
+            actionMap.remove(key + "_i");
+        }
+
     }
+
+    public void registerNode(TreeNode treeNode) {
+        keyToNode.put(treeNode.key, treeNode);
+    }
+
+    public void clearNodeToKeyMap() {
+        keyToNode.clear();
+    }
+
 }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
new file mode 100644 (file)
index 0000000..c058a15
--- /dev/null
@@ -0,0 +1,228 @@
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import java.util.Iterator;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.TooltipInfo;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.ui.VTree.TreeNode;\r
+\r
+public class VTreePaintable extends VAbstractPaintableWidget {\r
+\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        // Ensure correct implementation and let container manage caption\r
+        if (client.updateComponent(this, uidl, true)) {\r
+            return;\r
+        }\r
+\r
+        getWidgetForPaintable().rendering = true;\r
+\r
+        getWidgetForPaintable().client = client;\r
+\r
+        if (uidl.hasAttribute("partialUpdate")) {\r
+            handleUpdate(uidl);\r
+            getWidgetForPaintable().rendering = false;\r
+            return;\r
+        }\r
+\r
+        getWidgetForPaintable().paintableId = uidl.getId();\r
+\r
+        getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");\r
+\r
+        getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");\r
+        getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");\r
+\r
+        getWidgetForPaintable().dragMode = uidl.hasAttribute("dragMode") ? uidl\r
+                .getIntAttribute("dragMode") : 0;\r
+\r
+        getWidgetForPaintable().isNullSelectionAllowed = uidl\r
+                .getBooleanAttribute("nullselect");\r
+\r
+        if (uidl.hasAttribute("alb")) {\r
+            getWidgetForPaintable().bodyActionKeys = uidl\r
+                    .getStringArrayAttribute("alb");\r
+        }\r
+\r
+        getWidgetForPaintable().body.clear();\r
+        // clear out any references to nodes that no longer are attached\r
+        getWidgetForPaintable().clearNodeToKeyMap();\r
+        TreeNode childTree = null;\r
+        UIDL childUidl = null;\r
+        for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {\r
+            childUidl = (UIDL) i.next();\r
+            if ("actions".equals(childUidl.getTag())) {\r
+                updateActionMap(childUidl);\r
+                continue;\r
+            } else if ("-ac".equals(childUidl.getTag())) {\r
+                getWidgetForPaintable().updateDropHandler(childUidl);\r
+                continue;\r
+            }\r
+            childTree = getWidgetForPaintable().new TreeNode();\r
+            updateNodeFromUIDL(childTree, childUidl);\r
+            getWidgetForPaintable().body.add(childTree);\r
+            childTree.addStyleDependentName("root");\r
+            childTree.childNodeContainer.addStyleDependentName("root");\r
+        }\r
+        if (childTree != null && childUidl != null) {\r
+            boolean leaf = !childUidl.getTag().equals("node");\r
+            childTree.addStyleDependentName(leaf ? "leaf-last" : "last");\r
+            childTree.childNodeContainer.addStyleDependentName("last");\r
+        }\r
+        final String selectMode = uidl.getStringAttribute("selectmode");\r
+        getWidgetForPaintable().selectable = !"none".equals(selectMode);\r
+        getWidgetForPaintable().isMultiselect = "multi".equals(selectMode);\r
+\r
+        if (getWidgetForPaintable().isMultiselect) {\r
+            getWidgetForPaintable().multiSelectMode = uidl\r
+                    .getIntAttribute("multiselectmode");\r
+        }\r
+\r
+        getWidgetForPaintable().selectedIds = uidl\r
+                .getStringArrayVariableAsSet("selected");\r
+\r
+        // Update lastSelection and focusedNode to point to *actual* nodes again\r
+        // after the old ones have been cleared from the body. This fixes focus\r
+        // and keyboard navigation issues as described in #7057 and other\r
+        // tickets.\r
+        if (getWidgetForPaintable().lastSelection != null) {\r
+            getWidgetForPaintable().lastSelection = getWidgetForPaintable()\r
+                    .getNodeByKey(getWidgetForPaintable().lastSelection.key);\r
+        }\r
+        if (getWidgetForPaintable().focusedNode != null) {\r
+            getWidgetForPaintable().setFocusedNode(\r
+                    getWidgetForPaintable().getNodeByKey(\r
+                            getWidgetForPaintable().focusedNode.key));\r
+        }\r
+\r
+        if (getWidgetForPaintable().lastSelection == null\r
+                && getWidgetForPaintable().focusedNode == null\r
+                && !getWidgetForPaintable().selectedIds.isEmpty()) {\r
+            getWidgetForPaintable().setFocusedNode(\r
+                    getWidgetForPaintable().getNodeByKey(\r
+                            getWidgetForPaintable().selectedIds.iterator()\r
+                                    .next()));\r
+            getWidgetForPaintable().focusedNode.setFocused(false);\r
+        }\r
+\r
+        getWidgetForPaintable().rendering = false;\r
+\r
+    }\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VTree.class);\r
+    }\r
+\r
+    @Override\r
+    public VTree getWidgetForPaintable() {\r
+        return (VTree) super.getWidgetForPaintable();\r
+    }\r
+\r
+    private void handleUpdate(UIDL uidl) {\r
+        final TreeNode rootNode = getWidgetForPaintable().getNodeByKey(\r
+                uidl.getStringAttribute("rootKey"));\r
+        if (rootNode != null) {\r
+            if (!rootNode.getState()) {\r
+                // expanding node happened server side\r
+                rootNode.setState(true, false);\r
+            }\r
+            renderChildNodes(rootNode, (Iterator) uidl.getChildIterator());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Registers action for the root and also for individual nodes\r
+     * \r
+     * @param uidl\r
+     */\r
+    private void updateActionMap(UIDL uidl) {\r
+        final Iterator<?> it = uidl.getChildIterator();\r
+        while (it.hasNext()) {\r
+            final UIDL action = (UIDL) it.next();\r
+            final String key = action.getStringAttribute("key");\r
+            final String caption = action.getStringAttribute("caption");\r
+            String iconUrl = null;\r
+            if (action.hasAttribute("icon")) {\r
+                iconUrl = getConnection().translateVaadinUri(\r
+                        action.getStringAttribute("icon"));\r
+            }\r
+            getWidgetForPaintable().registerAction(key, caption, iconUrl);\r
+        }\r
+\r
+    }\r
+\r
+    public void updateNodeFromUIDL(TreeNode treeNode, UIDL uidl) {\r
+        String nodeKey = uidl.getStringAttribute("key");\r
+        treeNode.setText(uidl.getStringAttribute("caption"));\r
+        treeNode.key = nodeKey;\r
+\r
+        getWidgetForPaintable().registerNode(treeNode);\r
+\r
+        if (uidl.hasAttribute("al")) {\r
+            treeNode.actionKeys = uidl.getStringArrayAttribute("al");\r
+        }\r
+\r
+        if (uidl.getTag().equals("node")) {\r
+            if (uidl.getChildCount() == 0) {\r
+                treeNode.childNodeContainer.setVisible(false);\r
+            } else {\r
+                renderChildNodes(treeNode, (Iterator) uidl.getChildIterator());\r
+                treeNode.childrenLoaded = true;\r
+            }\r
+        } else {\r
+            treeNode.addStyleName(TreeNode.CLASSNAME + "-leaf");\r
+        }\r
+        if (uidl.hasAttribute("style")) {\r
+            treeNode.setNodeStyleName(uidl.getStringAttribute("style"));\r
+        }\r
+\r
+        String description = uidl.getStringAttribute("descr");\r
+        if (description != null && getConnection() != null) {\r
+            // Set tooltip\r
+            TooltipInfo info = new TooltipInfo(description);\r
+            getConnection().registerTooltip(this, nodeKey, info);\r
+        } else {\r
+            // Remove possible previous tooltip\r
+            getConnection().registerTooltip(this, nodeKey, null);\r
+        }\r
+\r
+        if (uidl.getBooleanAttribute("expanded") && !treeNode.getState()) {\r
+            treeNode.setState(true, false);\r
+        }\r
+\r
+        if (uidl.getBooleanAttribute("selected")) {\r
+            treeNode.setSelected(true);\r
+            // ensure that identifier is in selectedIds array (this may be a\r
+            // partial update)\r
+            getWidgetForPaintable().selectedIds.add(nodeKey);\r
+        }\r
+\r
+        treeNode.setIcon(uidl.getStringAttribute("icon"));\r
+    }\r
+\r
+    void renderChildNodes(TreeNode containerNode, Iterator<UIDL> i) {\r
+        containerNode.childNodeContainer.clear();\r
+        containerNode.childNodeContainer.setVisible(true);\r
+        while (i.hasNext()) {\r
+            final UIDL childUidl = i.next();\r
+            // actions are in bit weird place, don't mix them with children,\r
+            // but current node's actions\r
+            if ("actions".equals(childUidl.getTag())) {\r
+                updateActionMap(childUidl);\r
+                continue;\r
+            }\r
+            final TreeNode childTree = getWidgetForPaintable().new TreeNode();\r
+            updateNodeFromUIDL(childTree, childUidl);\r
+            containerNode.add(childTree);\r
+            if (!i.hasNext()) {\r
+                childTree\r
+                        .addStyleDependentName(childTree.isLeaf() ? "leaf-last"\r
+                                : "last");\r
+                childTree.childNodeContainer.addStyleDependentName("last");\r
+            }\r
+        }\r
+        containerNode.childrenLoaded = true;\r
+    }\r
+}\r
index 554afda97c19a09e422add4397d85fbacbec695d..4ea66cc6bf88a6fbb01d36f067ed1660ad5fc608 100644 (file)
@@ -45,6 +45,7 @@ import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VTree;
+import com.vaadin.terminal.gwt.client.ui.VTreePaintable;
 import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
 import com.vaadin.terminal.gwt.client.ui.dd.VTargetInSubtree;
 import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
@@ -60,7 +61,7 @@ import com.vaadin.tools.ReflectTools;
  * @since 3.0
  */
 @SuppressWarnings({ "serial", "deprecation" })
-@ClientWidget(VTree.class)
+@ClientWidget(VTreePaintable.class)
 public class Tree extends AbstractSelect implements Container.Hierarchical,
         Action.Container, ItemClickSource, ItemClickNotifier, DragSource,
         DropTarget {