From 37c64aa647a4d5891f83f23c1719543362abfde7 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Tue, 4 Nov 2008 13:06:12 +0000 Subject: [PATCH] In debug mode, toolkit now prints error to std err if component hierarchy has invalid combination of layouts and relative sizes. svn changeset:5807/svn branch:trunk --- .../gwt/server/CommunicationManager.java | 15 +- .../terminal/gwt/server/DebugUtilities.java | 156 ++++++++++++++++++ 2 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/com/itmill/toolkit/terminal/gwt/server/DebugUtilities.java diff --git a/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java b/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java index e2f11b29a0..0c7da33466 100644 --- a/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java +++ b/src/com/itmill/toolkit/terminal/gwt/server/CommunicationManager.java @@ -327,6 +327,8 @@ public class CommunicationManager implements Paintable.RepaintRequestListener { outWriter.print("\"changes\":["); + ArrayList 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(); 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 index 0000000000..95ceb60e29 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/server/DebugUtilities.java @@ -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; + } + +} -- 2.39.5