]> source.dussan.org Git - vaadin-framework.git/commitdiff
Ensure updateCaption is invoked for new children (#10564) 28/528/1
authorLeif Åstrand <leif@vaadin.com>
Tue, 18 Dec 2012 09:34:14 +0000 (11:34 +0200)
committerLeif Åstrand <leif@vaadin.com>
Tue, 18 Dec 2012 09:34:23 +0000 (11:34 +0200)
* Change updateConnectorHierarchy to return a
ConnectorHierarchyUpdateResult that contains both the events as well as
a list of all children that have been moved to a new parent

Change-Id: Idee8192eaeab4df7c3a96d6089b9e6d543216177

client/src/com/vaadin/client/ApplicationConnection.java
client/src/com/vaadin/client/ui/AbstractComponentConnector.java

index 05cc88d0ee42f708435b5bb0b33318ab8959f627..ff59a76832d90789cab972b940831515e60941b1 100644 (file)
@@ -107,6 +107,14 @@ import com.vaadin.shared.ui.ui.UIConstants;
  */
 public class ApplicationConnection {
 
+    /**
+     * Helper used to return two values when updating the connector hierarchy.
+     */
+    private static class ConnectorHierarchyUpdateResult {
+        private List<ConnectorHierarchyChangeEvent> events = new LinkedList<ConnectorHierarchyChangeEvent>();
+        private List<ServerConnector> parentChanged = new LinkedList<ServerConnector>();
+    }
+
     public static final String MODIFIED_CLASSNAME = "v-modified";
 
     public static final String DISABLED_CLASSNAME = "v-disabled";
@@ -1441,18 +1449,21 @@ public class ApplicationConnection {
                         " * Update of connector states completed", 10);
 
                 // Update hierarchy, do not fire events
-                Collection<ConnectorHierarchyChangeEvent> pendingHierarchyChangeEvents = updateConnectorHierarchy(json);
+                ConnectorHierarchyUpdateResult connectorHierarchyUpdateResult = updateConnectorHierarchy(json);
 
                 updateDuration.logDuration(
                         " * Update of connector hierarchy completed", 10);
 
                 // Fire hierarchy change events
-                sendHierarchyChangeEvents(pendingHierarchyChangeEvents);
+                sendHierarchyChangeEvents(connectorHierarchyUpdateResult.events);
 
                 updateDuration.logDuration(
                         " * Hierarchy state change event processing completed",
                         10);
 
+                updateCaptions(pendingStateChangeEvents,
+                        connectorHierarchyUpdateResult.parentChanged);
+
                 delegateToWidget(pendingStateChangeEvents);
 
                 // Fire state change events.
@@ -1554,6 +1565,36 @@ public class ApplicationConnection {
 
             }
 
+            private void updateCaptions(
+                    Collection<StateChangeEvent> pendingStateChangeEvents,
+                    Collection<ServerConnector> parentChanged) {
+                /*
+                 * Find all components that might need a caption update based on
+                 * pending state and hierarchy changes
+                 */
+                HashSet<ServerConnector> needsCaptionUpdate = new HashSet<ServerConnector>(
+                        parentChanged);
+
+                // Find components with potentially changed caption state
+                for (StateChangeEvent event : pendingStateChangeEvents) {
+                    ServerConnector connector = event.getConnector();
+                    needsCaptionUpdate.add(connector);
+                }
+
+                // Update captions for all suitable candidates
+                for (ServerConnector child : needsCaptionUpdate) {
+                    if (child instanceof ComponentConnector
+                            && ((ComponentConnector) child)
+                                    .delegateCaptionHandling()) {
+                        ServerConnector parent = child.getParent();
+                        if (parent instanceof HasComponentsConnector) {
+                            ((HasComponentsConnector) parent)
+                                    .updateCaption((ComponentConnector) child);
+                        }
+                    }
+                }
+            }
+
             private void delegateToWidget(
                     Collection<StateChangeEvent> pendingStateChangeEvents) {
                 VConsole.log(" * Running @DelegateToWidget");
@@ -1924,15 +1965,16 @@ public class ApplicationConnection {
              * @param json
              *            The JSON containing the hierarchy information
              * @return A collection of events that should be fired when update
-             *         of hierarchy and state is complete
+             *         of hierarchy and state is complete and a list of all
+             *         connectors for which the parent has changed
              */
-            private Collection<ConnectorHierarchyChangeEvent> updateConnectorHierarchy(
+            private ConnectorHierarchyUpdateResult updateConnectorHierarchy(
                     ValueMap json) {
-                List<ConnectorHierarchyChangeEvent> events = new LinkedList<ConnectorHierarchyChangeEvent>();
+                ConnectorHierarchyUpdateResult result = new ConnectorHierarchyUpdateResult();
 
                 VConsole.log(" * Updating connector hierarchy");
                 if (!json.containsKey("hierarchy")) {
-                    return events;
+                    return result;
                 }
 
                 HashSet<ServerConnector> maybeDetached = new HashSet<ServerConnector>();
@@ -1976,6 +2018,7 @@ public class ApplicationConnection {
                             }
                             if (childConnector.getParent() != parentConnector) {
                                 childConnector.setParent(parentConnector);
+                                result.parentChanged.add(childConnector);
                                 // Not detached even if previously removed from
                                 // parent
                                 maybeDetached.remove(childConnector);
@@ -2007,7 +2050,7 @@ public class ApplicationConnection {
                                 event.setOldChildren(oldComponents);
                                 event.setConnector(parentConnector);
                                 ccc.setChildComponents(newComponents);
-                                events.add(event);
+                                result.events.add(event);
                             }
                         } else if (!newComponents.isEmpty()) {
                             VConsole.error("Hierachy claims "
@@ -2047,10 +2090,10 @@ public class ApplicationConnection {
                  * removed from its parent but not added to any other parent
                  */
                 for (ServerConnector removed : maybeDetached) {
-                    recursivelyDetach(removed, events);
+                    recursivelyDetach(removed, result.events);
                 }
 
-                return events;
+                return result;
 
             }
 
index d11be76a809651b3d3995205365433110dfbf4f7..f8088d63a2f88c6d23b0f04e8c3ef9b7b08b8cb4 100644 (file)
@@ -151,18 +151,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         // Style names
         updateWidgetStyleNames();
 
-        // Set captions
-        if (delegateCaptionHandling()) {
-            ServerConnector parent = getParent();
-            if (parent instanceof HasComponentsConnector) {
-                ((HasComponentsConnector) parent).updateCaption(this);
-            } else if (parent == null && !(this instanceof UIConnector)) {
-                VConsole.error("Parent of connector "
-                        + Util.getConnectorString(this)
-                        + " is null. This is typically an indication of a broken component hierarchy");
-            }
-        }
-
         /*
          * updateComponentSize need to be after caption update so caption can be
          * taken into account