001: /* *************************************************************************
002:
003: Millstone(TM)
004: Open Sourced User Interface Library for
005: Internet Development with Java
006:
007: Millstone is a registered trademark of IT Mill Ltd
008: Copyright (C) 2000-2005 IT Mill Ltd
009:
010: *************************************************************************
011:
012: This library is free software; you can redistribute it and/or
013: modify it under the terms of the GNU Lesser General Public
014: license version 2.1 as published by the Free Software Foundation.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: *************************************************************************
026:
027: For more information, contact:
028:
029: IT Mill Ltd phone: +358 2 4802 7180
030: Ruukinkatu 2-4 fax: +358 2 4802 7181
031: 20540, Turku email: info@itmill.com
032: Finland company www: www.itmill.com
033:
034: Primary source for MillStone information and releases: www.millstone.org
035:
036: ********************************************************************** */
037:
038: package org.millstone.base.ui;
039:
040: import org.millstone.base.terminal.PaintTarget;
041: import org.millstone.base.terminal.PaintException;
042: import java.util.Iterator;
043: import java.util.HashMap;
044:
045: /** <p>A container component with freely designed layout and style. The
046: * container consists of items with textually represented locations. Each
047: * item contains one sub-component. The adapter and theme are resposible for
048: * rendering the layout with given style by placing the items on the screen
049: * in defined locations.</p>
050: *
051: * <p>The definition of locations is not fixed - the each style can define
052: * its locations in a way that is suitable for it. One typical example would
053: * be to create visual design for a website as a custom layout: the visual
054: * design could define locations for "menu", "body" and "title" for example.
055: * The layout would then be implemented as XLS-template with for given
056: * style.</p>
057: *
058: * <p>The default theme handles the styles that are not defined by just
059: * drawing the subcomponents with flowlayout.</p>
060: *
061: * @author IT Mill Ltd.
062: * @version 3.1.1
063: * @since 3.0
064: */
065: public class CustomLayout extends AbstractComponentContainer implements
066: Layout {
067:
068: /** Custom layout slots containing the components */
069: private HashMap slots = new HashMap();
070:
071: /** Constructor for custom layout with given style */
072: public CustomLayout(String style) {
073: setStyle(style);
074: }
075:
076: /** Get component UIDL tag.
077: * @return Component UIDL tag as string.
078: */
079: public String getTag() {
080: return "customlayout";
081: }
082:
083: /** Add a component into this container to given location.
084: * @param c The component to be added.
085: * @param location The location of the component
086: */
087: public void addComponent(Component c, String location) {
088: Component old = (Component) slots.get(location);
089: if (old != null) {
090: removeComponent(old);
091: }
092: slots.put(location, c);
093: c.setParent(this );
094: fireComponentAttachEvent(c);
095: requestRepaint();
096: }
097:
098: /** Add a component into this container. The component is added without
099: * specifying the location (empty string is then used as location). Only
100: * one component can be added to the default "" location and adding
101: * more components into that location overwrites the old components.
102: * @param c The component to be added.
103: */
104: public void addComponent(Component c) {
105: this .addComponent(c, "");
106: }
107:
108: /** Remove a component from this container.
109: * @param c The component to be removed.
110: */
111: public void removeComponent(Component c) {
112: if (c == null)
113: return;
114: slots.values().remove(c);
115: c.setParent(null);
116: fireComponentDetachEvent(c);
117: requestRepaint();
118: }
119:
120: /** Remove a component from this container from given location.
121: * @param location Location identifier of the component
122: */
123: public void removeComponent(String location) {
124: this .removeComponent((Component) slots.get(location));
125: }
126:
127: /** Get component container iterator for going trough all the components in
128: * the container.
129: * @return Iterator of the components inside the container.
130: */
131: public Iterator getComponentIterator() {
132: return slots.values().iterator();
133: }
134:
135: /** Get child-component by its location.
136: *
137: * @param location The name of the location where the requested
138: * component resides
139: * @return Component in the given location or null if not found.
140: */
141: public Component getComponent(String location) {
142: return (Component) slots.get(location);
143: }
144:
145: /** Paint the content of this component.
146: * @param event PaintEvent.
147: * @throws PaintException The paint operation failed.
148: */
149: public void paintContent(PaintTarget target) throws PaintException {
150:
151: // Add all items in all the locations
152: for (Iterator i = slots.keySet().iterator(); i.hasNext();) {
153:
154: // Get the (location,component)
155: String location = (String) i.next();
156: Component c = (Component) slots.get(location);
157:
158: // Write the item
159: target.startTag("location");
160: target.addAttribute("name", location);
161: c.paint(target);
162: target.endTag("location");
163: }
164: }
165:
166: /* Documented in superclass */
167: public void replaceComponent(Component oldComponent,
168: Component newComponent) {
169:
170: // Get the locations
171: String oldLocation = null;
172: String newLocation = null;
173: for (Iterator i = slots.keySet().iterator(); i.hasNext();) {
174: String location = (String) i.next();
175: Component component = (Component) slots.get(location);
176: if (component == oldComponent)
177: oldLocation = location;
178: if (component == newComponent)
179: newLocation = location;
180: }
181:
182: if (oldLocation == null)
183: addComponent(newComponent);
184: else if (newLocation == null) {
185: removeComponent(oldLocation);
186: addComponent(newComponent, oldLocation);
187: } else {
188: slots.put(newLocation, oldComponent);
189: slots.put(oldLocation, newComponent);
190: requestRepaint();
191: }
192: }
193:
194: }
|