]> source.dussan.org Git - vaadin-framework.git/commitdiff
In debug mode, toolkit now prints error to std err if component hierarchy has invalid...
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 4 Nov 2008 13:06:12 +0000 (13:06 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 4 Nov 2008 13:06:12 +0000 (13:06 +0000)
svn changeset:5807/svn branch:trunk

src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java
src/com/itmill/toolkit/terminal/gwt/server/DebugUtilities.java [new file with mode: 0644]

index e2f11b29a0cc5e4dfab73378b58ff74627954de5..0c7da3346623a6a8bed104e18b9e5e1cebedf745 100644 (file)
@@ -327,6 +327,8 @@ public class CommunicationManager implements Paintable.RepaintRequestListener {
 
         outWriter.print("\"changes\":[");
 
+        ArrayList<Paintable> paintables = null;
+
         // If the browser-window has been closed - we do not need to paint it at
         // all
         if (!window.getName().equals(closingWindowName)) {
@@ -343,9 +345,8 @@ public class CommunicationManager implements Paintable.RepaintRequestListener {
                     !repaintAll);
 
             // Paints components
-            ArrayList paintables;
             if (repaintAll) {
-                paintables = new ArrayList();
+                paintables = new ArrayList<Paintable>();
                 paintables.add(window);
 
                 // Reset sent locales
@@ -547,6 +548,16 @@ public class CommunicationManager implements Paintable.RepaintRequestListener {
         }
         outWriter.flush();
         outWriter.close();
+
+        if (applicationServlet.isDebugMode()) {
+            if (paintables != null) {
+                for (Paintable paintable : paintables) {
+                    DebugUtilities
+                            .validateComponentRelativeSizes((Component) paintable);
+                }
+            }
+        }
+
     }
 
     /**
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/DebugUtilities.java b/src/com/itmill/toolkit/terminal/gwt/server/DebugUtilities.java
new file mode 100644 (file)
index 0000000..95ceb60
--- /dev/null
@@ -0,0 +1,156 @@
+package com.itmill.toolkit.terminal.gwt.server;
+
+import java.util.Iterator;
+
+import com.itmill.toolkit.terminal.Sizeable;
+import com.itmill.toolkit.ui.Component;
+import com.itmill.toolkit.ui.ComponentContainer;
+import com.itmill.toolkit.ui.GridLayout;
+import com.itmill.toolkit.ui.OrderedLayout;
+import com.itmill.toolkit.ui.Panel;
+import com.itmill.toolkit.ui.Window;
+
+public class DebugUtilities {
+
+    /**
+     * Recursively checks given component and its subtree for invalid layout
+     * setups. Prints errors to std err stream.
+     * 
+     * @param component
+     *            component to check
+     */
+    static void validateComponentRelativeSizes(Component component) {
+
+        String msg = null;
+
+        Component parent = component.getParent();
+        if (!(component instanceof Window)) {
+            if (hasRelativeWidth(component) && hasUndefinedWidth(parent)) {
+                if (parent instanceof OrderedLayout) {
+                    OrderedLayout ol = (OrderedLayout) parent;
+                    if (ol.getOrientation() == OrderedLayout.ORIENTATION_HORIZONTAL) {
+                        msg = "Relative width for component inside non sized horizontal ordered layout.";
+                    } else if (!hasNonRelativeWidthComponent(ol)) {
+                        msg = "At least one of vertical orderedlayout's components must have non relative width if layout has no width defined";
+                    } else {
+                        // valid situation, other components defined width
+                    }
+                } else if (!(parent instanceof GridLayout)) {
+                    // TODO make grid layout check (each col should have at
+                    // least one non relatively sized component)
+
+                    // default error for non sized parent issue
+                    msg = "Relative width component's parent should not have undefined width.";
+                }
+            }
+            // if no error found yet, check for height
+            if (msg == null) {
+                if (hasRelativeHeight(component) && hasUndefinedHeight(parent)) {
+                    if (parent instanceof OrderedLayout) {
+                        OrderedLayout ol = (OrderedLayout) parent;
+                        if (ol.getOrientation() == OrderedLayout.ORIENTATION_VERTICAL) {
+                            msg = "Relative height for component inside non sized vertical ordered layout.";
+                        } else if (!hasNonRelativeHeightComponent(ol)) {
+                            msg = "At least one of horizontal orderedlayout's components must have non relative height if layout has no height defined";
+                        } else {
+                            // valid situation, other components defined height
+                        }
+                    } else if (!(parent instanceof GridLayout)) {
+                        // TODO make grid layout check (each row should have at
+                        // least one non relatively sized component)
+
+                        // default error for non sized parent issue
+                        msg = "Relative height component's parent should not have undefined height.";
+                    }
+                }
+            }
+        }
+        if (msg != null) {
+            StringBuffer err = new StringBuffer();
+            err
+                    .append("IT MILL Toolkit DEBUG: Invalid layout detected. Components may be invisible or not render as expected.\n");
+            err.append("\t Component : ");
+            err.append(component);
+            err.append(", Caption: ");
+            err.append(component.getCaption());
+            err.append(" DebugId : ");
+            err.append(component.getDebugId());
+            err.append("\n\t Parent    : ");
+            err.append(parent);
+            err.append(", Caption: ");
+            err.append(parent.getCaption());
+            err.append(" DebugId : ");
+            err.append(parent.getDebugId());
+            err.append("\n\t Error     : ");
+            err.append(msg);
+            System.err.println(err);
+            return;
+        }
+
+        if (component instanceof Panel) {
+            Panel panel = (Panel) component;
+            validateComponentRelativeSizes(panel.getLayout());
+        } else if (component instanceof ComponentContainer) {
+            ComponentContainer lo = (ComponentContainer) component;
+            Iterator it = lo.getComponentIterator();
+            while (it.hasNext()) {
+                validateComponentRelativeSizes((Component) it.next());
+            }
+        }
+
+    }
+
+    private static boolean hasNonRelativeHeightComponent(OrderedLayout ol) {
+        Iterator it = ol.getComponentIterator();
+        while (it.hasNext()) {
+            if (!hasRelativeHeight((Component) it.next())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasUndefinedHeight(Component parent) {
+        if (parent instanceof Window) {
+            Window w = (Window) parent;
+            if (w.getParent() == null) {
+                // main window is considered to have size
+                return false;
+            }
+        }
+        return parent.getHeight() < 0;
+    }
+
+    private static boolean hasRelativeHeight(Component component) {
+        return (component.getHeightUnits() == Sizeable.UNITS_PERCENTAGE && component
+                .getHeight() > 0);
+    }
+
+    private static boolean hasNonRelativeWidthComponent(OrderedLayout ol) {
+        Iterator it = ol.getComponentIterator();
+        while (it.hasNext()) {
+            if (!hasRelativeWidth((Component) it.next())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasRelativeWidth(Component paintable) {
+        return paintable.getWidth() > 0
+                && paintable.getWidthUnits() == Sizeable.UNITS_PERCENTAGE;
+    }
+
+    private static boolean hasUndefinedWidth(Component parent) {
+        if (parent instanceof Window) {
+            Window w = (Window) parent;
+            if (w.getParent() == null) {
+                // main window is considered to have size
+                return false;
+            }
+
+        }
+        return parent.getWidth() < 0;
+    }
+
+}