From daa1a774a8f059c48108760ad64cec529a29a983 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Dec 2008 14:56:27 +0000 Subject: [PATCH] #2248 OrderedLayout split into AbstractOrderedLayout & OrderedLayout. Added VerticalLayout and HorizontalLayout which extend AbstractOrderedLayout. svn changeset:6055/svn branch:trunk --- .../toolkit/ui/AbstractOrderedLayout.java | 329 +++++++++++++++++ .../itmill/toolkit/ui/HorizontalLayout.java | 32 ++ src/com/itmill/toolkit/ui/OrderedLayout.java | 335 +----------------- src/com/itmill/toolkit/ui/VerticalLayout.java | 25 ++ 4 files changed, 396 insertions(+), 325 deletions(-) create mode 100644 src/com/itmill/toolkit/ui/AbstractOrderedLayout.java create mode 100644 src/com/itmill/toolkit/ui/HorizontalLayout.java create mode 100644 src/com/itmill/toolkit/ui/VerticalLayout.java diff --git a/src/com/itmill/toolkit/ui/AbstractOrderedLayout.java b/src/com/itmill/toolkit/ui/AbstractOrderedLayout.java new file mode 100644 index 0000000000..cb3d277222 --- /dev/null +++ b/src/com/itmill/toolkit/ui/AbstractOrderedLayout.java @@ -0,0 +1,329 @@ +/* +@ITMillApache2LicenseForJavaFiles@ + */ + +package com.itmill.toolkit.ui; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; + +import com.itmill.toolkit.terminal.PaintException; +import com.itmill.toolkit.terminal.PaintTarget; +import com.itmill.toolkit.terminal.Sizeable; + +public abstract class AbstractOrderedLayout extends AbstractLayout implements + Layout.AlignmentHandler, Layout.SpacingHandler { + + private static final int ALIGNMENT_DEFAULT = ALIGNMENT_TOP + ALIGNMENT_LEFT; + + /** + * Custom layout slots containing the components. + */ + protected LinkedList components = new LinkedList(); + + /* Child component alignments */ + + /** + * Mapping from components to alignments (horizontal + vertical). + */ + private final Map componentToAlignment = new HashMap(); + + private final Map componentToExpandRatio = new HashMap(); + + /** + * Is spacing between contained components enabled. Defaults to false. + */ + private boolean spacing = false; + + /** + * Gets the component UIDL tag. + * + * @return the Component UIDL tag as string. + */ + public String getTag() { + return "orderedlayout"; + } + + /** + * Add a component into this container. The component is added to the right + * or under the previous component. + * + * @param c + * the component to be added. + */ + public void addComponent(Component c) { + super.addComponent(c); + components.add(c); + requestRepaint(); + } + + /** + * Adds a component into this container. The component is added to the left + * or on top of the other components. + * + * @param c + * the component to be added. + */ + public void addComponentAsFirst(Component c) { + super.addComponent(c); + components.addFirst(c); + requestRepaint(); + } + + /** + * Adds a component into indexed position in this container. + * + * @param c + * the component to be added. + * @param index + * the Index of the component position. The components currently + * in and after the position are shifted forwards. + */ + public void addComponent(Component c, int index) { + super.addComponent(c); + components.add(index, c); + requestRepaint(); + } + + /** + * Removes the component from this container. + * + * @param c + * the component to be removed. + */ + public void removeComponent(Component c) { + super.removeComponent(c); + components.remove(c); + componentToAlignment.remove(c); + componentToExpandRatio.remove(c); + requestRepaint(); + } + + /** + * Gets the component container iterator for going trough all the components + * in the container. + * + * @return the Iterator of the components inside the container. + */ + public Iterator getComponentIterator() { + return components.iterator(); + } + + /** + * Paints the content of this component. + * + * @param target + * the Paint Event. + * @throws PaintException + * if the paint operation failed. + */ + public void paintContent(PaintTarget target) throws PaintException { + super.paintContent(target); + + // Add spacing attribute (omitted if false) + if (spacing) { + target.addAttribute("spacing", spacing); + } + + final String[] alignmentsArray = new String[components.size()]; + final Integer[] expandRatioArray = new Integer[components.size()]; + float sum = getExpandRatioSum(); + boolean equallyDivided = false; + int realSum = 0; + if (sum == 0 && components.size() > 0) { + // no component has been expanded, all components have same expand + // rate + equallyDivided = true; + float equalSize = 1 / (float) components.size(); + int myRatio = Math.round(equalSize * 1000); + for (int i = 0; i < expandRatioArray.length; i++) { + expandRatioArray[i] = myRatio; + } + realSum = myRatio * components.size(); + } + + // Adds all items in all the locations + int index = 0; + for (final Iterator i = components.iterator(); i.hasNext();) { + final Component c = (Component) i.next(); + if (c != null) { + // Paint child component UIDL + c.paint(target); + alignmentsArray[index] = String + .valueOf(getComponentAlignment(c)); + if (!equallyDivided) { + int myRatio = Math.round((getExpandRatio(c) / sum) * 1000); + expandRatioArray[index] = myRatio; + realSum += myRatio; + } + index++; + } + } + + // correct possible rounding error + if (expandRatioArray.length > 0) { + expandRatioArray[0] -= realSum - 1000; + } + + // Add child component alignment info to layout tag + target.addAttribute("alignments", alignmentsArray); + target.addAttribute("expandRatios", expandRatioArray); + } + + private float getExpandRatioSum() { + float sum = 0; + for (Iterator> iterator = componentToExpandRatio + .entrySet().iterator(); iterator.hasNext();) { + sum += iterator.next().getValue(); + } + return sum; + } + + /* Documented in superclass */ + public void replaceComponent(Component oldComponent, Component newComponent) { + + // Gets the locations + int oldLocation = -1; + int newLocation = -1; + int location = 0; + for (final Iterator i = components.iterator(); i.hasNext();) { + final Component component = (Component) i.next(); + + if (component == oldComponent) { + oldLocation = location; + } + if (component == newComponent) { + newLocation = location; + } + + location++; + } + + if (oldLocation == -1) { + addComponent(newComponent); + } else if (newLocation == -1) { + removeComponent(oldComponent); + addComponent(newComponent, oldLocation); + } else { + if (oldLocation > newLocation) { + components.remove(oldComponent); + components.add(newLocation, oldComponent); + components.remove(newComponent); + componentToAlignment.remove(newComponent); + components.add(oldLocation, newComponent); + } else { + components.remove(newComponent); + components.add(oldLocation, newComponent); + components.remove(oldComponent); + componentToAlignment.remove(oldComponent); + components.add(newLocation, oldComponent); + } + + requestRepaint(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.itmill.toolkit.ui.Layout.AlignmentHandler#setComponentAlignment(com + * .itmill.toolkit.ui.Component, int, int) + */ + public void setComponentAlignment(Component childComponent, + int horizontalAlignment, int verticalAlignment) { + componentToAlignment.put(childComponent, new Integer( + horizontalAlignment + verticalAlignment)); + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see + * com.itmill.toolkit.ui.Layout.AlignmentHandler#getComponentAlignment(com + * .itmill.toolkit.ui.Component) + */ + public int getComponentAlignment(Component childComponent) { + final Integer bitMask = (Integer) componentToAlignment + .get(childComponent); + if (bitMask != null) { + return bitMask.intValue(); + } else { + return ALIGNMENT_DEFAULT; + } + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.ui.Layout.SpacingHandler#setSpacing(boolean) + */ + public void setSpacing(boolean enabled) { + spacing = enabled; + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.itmill.toolkit.ui.Layout.SpacingHandler#isSpacingEnabled() + */ + public boolean isSpacingEnabled() { + return spacing; + } + + /** + *

+ * This method is used to control how excess space in layout is distributed + * among components. Excess space may exist if layout is sized and contained + * non relatively sized components don't consume all available space. + * + *

+ * Example how to distribute 1:3 (33%) for component1 and 2:3 (67%) for + * component2 : + * + * + * layout.setExpandRatio(component1, 1);
+ * layout.setExpandRatio(component2, 2); + *
+ * + *

+ * If no ratios have been set, the excess space is distributed evenly among + * all components. + * + *

+ * Note, that width or height (depending on orientation) needs to be defined + * for this method to have any effect. + * + * @see Sizeable + * + * @param component + * the component in this layout which expand ratio is to be set + * @param ratio + */ + public void setExpandRatio(Component component, float ratio) { + if (components.contains(component)) { + componentToExpandRatio.put(component, ratio); + } else { + throw new IllegalArgumentException( + "Component must be added to layout before using setExpandRatio()"); + } + }; + + /** + * Returns the expand ratio of given component. + * + * @param component + * which expand ratios is requested + * @return expand ratio of given component, 0.0f by default + */ + public float getExpandRatio(Component component) { + Float ratio = componentToExpandRatio.get(component); + return (ratio == null) ? 0 : ratio.floatValue(); + } + +} diff --git a/src/com/itmill/toolkit/ui/HorizontalLayout.java b/src/com/itmill/toolkit/ui/HorizontalLayout.java new file mode 100644 index 0000000000..499712d81c --- /dev/null +++ b/src/com/itmill/toolkit/ui/HorizontalLayout.java @@ -0,0 +1,32 @@ +package com.itmill.toolkit.ui; + +import com.itmill.toolkit.terminal.PaintException; +import com.itmill.toolkit.terminal.PaintTarget; + +/** + * Horizontal layout + * + * HorizontalLayout is a component container, which shows the + * subcomponents in the order of their addition (horizontally). + * + * @author IT Mill Ltd. + * @version + * @VERSION@ + * @since 5.3 + */ +public class HorizontalLayout extends AbstractOrderedLayout { + + public HorizontalLayout() { + + } + + @Override + public void paintContent(PaintTarget target) throws PaintException { + super.paintContent(target); + + // Adds the attributes: orientation + target.addAttribute("orientation", "horizontal"); + + } + +} diff --git a/src/com/itmill/toolkit/ui/OrderedLayout.java b/src/com/itmill/toolkit/ui/OrderedLayout.java index c069124324..bf2bfdee11 100644 --- a/src/com/itmill/toolkit/ui/OrderedLayout.java +++ b/src/com/itmill/toolkit/ui/OrderedLayout.java @@ -1,18 +1,7 @@ -/* -@ITMillApache2LicenseForJavaFiles@ - */ - package com.itmill.toolkit.ui; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.Map.Entry; - import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; -import com.itmill.toolkit.terminal.Sizeable; /** * Ordered layout. @@ -25,9 +14,7 @@ import com.itmill.toolkit.terminal.Sizeable; * @VERSION@ * @since 3.0 */ -public class OrderedLayout extends AbstractLayout implements - Layout.AlignmentHandler, Layout.SpacingHandler { - +public class OrderedLayout extends AbstractOrderedLayout { /* Predefined orientations */ /** @@ -40,32 +27,11 @@ public class OrderedLayout extends AbstractLayout implements */ public static final int ORIENTATION_HORIZONTAL = 1; - private static final int ALIGNMENT_DEFAULT = ALIGNMENT_TOP + ALIGNMENT_LEFT; - - /** - * Custom layout slots containing the components. - */ - protected LinkedList components = new LinkedList(); - - /* Child component alignments */ - - /** - * Mapping from components to alignments (horizontal + vertical). - */ - private final Map componentToAlignment = new HashMap(); - - private final Map componentToExpandRatio = new HashMap(); - /** * Orientation of the layout. */ private int orientation; - /** - * Is spacing between contained components enabled. Defaults to false. - */ - private boolean spacing = false; - /** * Creates a new ordered layout. The order of the layout is * ORIENTATION_VERTICAL. @@ -88,156 +54,6 @@ public class OrderedLayout extends AbstractLayout implements } } - /** - * Gets the component UIDL tag. - * - * @return the Component UIDL tag as string. - */ - public String getTag() { - return "orderedlayout"; - } - - /** - * Add a component into this container. The component is added to the right - * or under the previous component. - * - * @param c - * the component to be added. - */ - public void addComponent(Component c) { - super.addComponent(c); - components.add(c); - requestRepaint(); - } - - /** - * Adds a component into this container. The component is added to the left - * or on top of the other components. - * - * @param c - * the component to be added. - */ - public void addComponentAsFirst(Component c) { - super.addComponent(c); - components.addFirst(c); - requestRepaint(); - } - - /** - * Adds a component into indexed position in this container. - * - * @param c - * the component to be added. - * @param index - * the Index of the component position. The components currently - * in and after the position are shifted forwards. - */ - public void addComponent(Component c, int index) { - super.addComponent(c); - components.add(index, c); - requestRepaint(); - } - - /** - * Removes the component from this container. - * - * @param c - * the component to be removed. - */ - public void removeComponent(Component c) { - super.removeComponent(c); - components.remove(c); - componentToAlignment.remove(c); - componentToExpandRatio.remove(c); - requestRepaint(); - } - - /** - * Gets the component container iterator for going trough all the components - * in the container. - * - * @return the Iterator of the components inside the container. - */ - public Iterator getComponentIterator() { - return components.iterator(); - } - - /** - * Paints the content of this component. - * - * @param target - * the Paint Event. - * @throws PaintException - * if the paint operation failed. - */ - public void paintContent(PaintTarget target) throws PaintException { - super.paintContent(target); - - // Adds the attributes: orientation - // note that the default values (b/vertical) are omitted - if (orientation == ORIENTATION_HORIZONTAL) { - target.addAttribute("orientation", "horizontal"); - } - - // Add spacing attribute (omitted if false) - if (spacing) { - target.addAttribute("spacing", spacing); - } - - final String[] alignmentsArray = new String[components.size()]; - final Integer[] expandRatioArray = new Integer[components.size()]; - float sum = getExpandRatioSum(); - boolean equallyDivided = false; - int realSum = 0; - if (sum == 0 && components.size() > 0) { - // no component has been expanded, all components have same expand - // rate - equallyDivided = true; - float equalSize = 1 / (float) components.size(); - int myRatio = Math.round(equalSize * 1000); - for (int i = 0; i < expandRatioArray.length; i++) { - expandRatioArray[i] = myRatio; - } - realSum = myRatio * components.size(); - } - - // Adds all items in all the locations - int index = 0; - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component c = (Component) i.next(); - if (c != null) { - // Paint child component UIDL - c.paint(target); - alignmentsArray[index] = String - .valueOf(getComponentAlignment(c)); - if (!equallyDivided) { - int myRatio = Math.round((getExpandRatio(c) / sum) * 1000); - expandRatioArray[index] = myRatio; - realSum += myRatio; - } - index++; - } - } - - // correct possible rounding error - if (expandRatioArray.length > 0) { - expandRatioArray[0] -= realSum - 1000; - } - - // Add child component alignment info to layout tag - target.addAttribute("alignments", alignmentsArray); - target.addAttribute("expandRatios", expandRatioArray); - } - - private float getExpandRatioSum() { - float sum = 0; - for (Iterator> iterator = componentToExpandRatio - .entrySet().iterator(); iterator.hasNext();) { - sum += iterator.next().getValue(); - } - return sum; - } - /** * Gets the orientation of the container. * @@ -253,8 +69,10 @@ public class OrderedLayout extends AbstractLayout implements * * @param orientation * the New value of property orientation. - * @deprecated define orientation in constructor instead + * @deprecated Use VerticalLayout/HorizontalLayout or define orientation in + * constructor instead */ + @Deprecated public void setOrientation(int orientation) { setOrientation(orientation, true); } @@ -278,148 +96,15 @@ public class OrderedLayout extends AbstractLayout implements } } - /* Documented in superclass */ - public void replaceComponent(Component oldComponent, Component newComponent) { - - // Gets the locations - int oldLocation = -1; - int newLocation = -1; - int location = 0; - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component component = (Component) i.next(); - - if (component == oldComponent) { - oldLocation = location; - } - if (component == newComponent) { - newLocation = location; - } - - location++; - } - - if (oldLocation == -1) { - addComponent(newComponent); - } else if (newLocation == -1) { - removeComponent(oldComponent); - addComponent(newComponent, oldLocation); - } else { - if (oldLocation > newLocation) { - components.remove(oldComponent); - components.add(newLocation, oldComponent); - components.remove(newComponent); - componentToAlignment.remove(newComponent); - components.add(oldLocation, newComponent); - } else { - components.remove(newComponent); - components.add(oldLocation, newComponent); - components.remove(oldComponent); - componentToAlignment.remove(oldComponent); - components.add(newLocation, oldComponent); - } - - requestRepaint(); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.itmill.toolkit.ui.Layout.AlignmentHandler#setComponentAlignment(com - * .itmill.toolkit.ui.Component, int, int) - */ - public void setComponentAlignment(Component childComponent, - int horizontalAlignment, int verticalAlignment) { - componentToAlignment.put(childComponent, new Integer( - horizontalAlignment + verticalAlignment)); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see - * com.itmill.toolkit.ui.Layout.AlignmentHandler#getComponentAlignment(com - * .itmill.toolkit.ui.Component) - */ - public int getComponentAlignment(Component childComponent) { - final Integer bitMask = (Integer) componentToAlignment - .get(childComponent); - if (bitMask != null) { - return bitMask.intValue(); - } else { - return ALIGNMENT_DEFAULT; - } - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.ui.Layout.SpacingHandler#setSpacing(boolean) - */ - public void setSpacing(boolean enabled) { - spacing = enabled; - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.itmill.toolkit.ui.Layout.SpacingHandler#isSpacingEnabled() - */ - public boolean isSpacingEnabled() { - return spacing; - } + @Override + public void paintContent(PaintTarget target) throws PaintException { + super.paintContent(target); - /** - *

- * This method is used to control how excess space in layout is distributed - * among components. Excess space may exist if layout is sized and contained - * non relatively sized components don't consume all available space. - * - *

- * Example how to distribute 1:3 (33%) for component1 and 2:3 (67%) for - * component2 : - * - * - * layout.setExpandRatio(component1, 1);
- * layout.setExpandRatio(component2, 2); - *
- * - *

- * If no ratios have been set, the excess space is distributed evenly among - * all components. - * - *

- * Note, that width or height (depending on orientation) needs to be defined - * for this method to have any effect. - * - * @see Sizeable - * - * @param component - * the component in this layout which expand ratio is to be set - * @param ratio - */ - public void setExpandRatio(Component component, float ratio) { - if (components.contains(component)) { - componentToExpandRatio.put(component, ratio); - } else { - throw new IllegalArgumentException( - "Component must be added to layout before using setExpandRatio()"); + // Adds the orientation attributes (the default is vertical) + if (orientation == ORIENTATION_HORIZONTAL) { + target.addAttribute("orientation", "horizontal"); } - }; - /** - * Returns the expand ratio of given component. - * - * @param component - * which expand ratios is requested - * @return expand ratio of given component, 0.0f by default - */ - public float getExpandRatio(Component component) { - Float ratio = componentToExpandRatio.get(component); - return (ratio == null) ? 0 : ratio.floatValue(); } } diff --git a/src/com/itmill/toolkit/ui/VerticalLayout.java b/src/com/itmill/toolkit/ui/VerticalLayout.java new file mode 100644 index 0000000000..d2cf580e22 --- /dev/null +++ b/src/com/itmill/toolkit/ui/VerticalLayout.java @@ -0,0 +1,25 @@ +package com.itmill.toolkit.ui; + +/** + * Vertical layout + * + * VerticalLayout is a component container, which shows the + * subcomponents in the order of their addition (vertically). A vertical layout + * is by default 100% wide. + * + * @author IT Mill Ltd. + * @version + * @VERSION@ + * @since 5.3 + */ +public class VerticalLayout extends AbstractOrderedLayout { + + public VerticalLayout() { + setWidth("100%"); + } + + /* + * An AbstractOrderedLayout is by default vertical so we do not need to + * override paintContent for that + */ +} -- 2.39.5