001 /*
002 * This file is part of the Echo Point Project. This project is a
003 * collection of Components that have extended the Echo Web Application
004 * Framework Version 3.
005 *
006 * Version: MPL 1.1
007 *
008 * The contents of this file are subject to the Mozilla Public License Version
009 * 1.1 (the "License"); you may not use this file except in compliance with
010 * the License. You may obtain a copy of the License at
011 * http://www.mozilla.org/MPL/
012 *
013 * Software distributed under the License is distributed on an "AS IS" basis,
014 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
015 * for the specific language governing rights and limitations under the
016 * License.
017 */
018
019 package echopoint;
020
021 import echopoint.internal.AbstractContainer;
022 import nextapp.echo.app.Component;
023 import nextapp.echo.app.IllegalChildException;
024
025 import java.util.LinkedHashMap;
026 import java.util.List;
027 import java.util.Map;
028
029 /**
030 * An implementation of {@link java.awt.BorderLayout} using a HTML table with
031 * three rows, and three columns. Note that similar to pane containers, this
032 * component supports only one child component per region.
033 *
034 * <p>The following shows sample use of this container component.</p>
035 * <pre>
036 * import echopoint.BorderLayout;
037 * import echopoint.HtmlLabel;
038 * import nextapp.echo.app.Alignment;
039 * import nextapp.echo.app.Color;
040 * import nextapp.echo.app.Extent;
041 * import nextapp.echo.app.layout.TableLayoutData;
042 *
043 * ...
044 * final BorderLayout container = new BorderLayout();
045 * container.setWidth( new Extent( 500 ) );
046 *
047 * HtmlLabel label = new HtmlLabel( "North" );
048 * TableLayoutData layout = new TableLayoutData();
049 * layout.setAlignment( Alignment.ALIGN_CENTER );
050 * layout.setBackground( new Color( 0x0000ff ) );
051 * label.setLayoutData( layout );
052 * container.add( label, BorderLayout.Region.north );
053 *
054 * ...
055 *
056 * parent.add( container );
057 * </pre>
058 *
059 * @author Rakesh 2009-04-02
060 * @version $Id: BorderLayout.java 146 2009-04-07 16:00:41Z sptrakesh $
061 * @since 3.0.0a11
062 */
063 public class BorderLayout extends AbstractContainer
064 {
065 private static final long serialVersionUID = 1L;
066
067 /** Enumeration for the regions in a border layout. */
068 public enum Region
069 {
070 /** The region that represents the north (top) area of the layout container. */
071 north,
072
073 /** The region that represents the west (left) area of the layout container. */
074 west,
075
076 /** The region that represents the centre (default) area of the layout container. */
077 center,
078
079 /** The region that represents the east (right) area of the layout container. */
080 east,
081
082 /** The region that represents the south (bottom) area of the layout container. */
083 south
084 }
085
086 /** A map used to maintain the regions to the component indices. */
087 private Map<Region,Integer> regionToIndex = new LinkedHashMap<Region,Integer>( 5 );
088
089 /** A map used to maintain the mapping of component index to region. */
090 private Map<Integer,Region> indexToRegion = new LinkedHashMap<Integer,Region>( 5 );
091
092 /** Default constructor. No special actions required. */
093 public BorderLayout() {}
094
095 /**
096 * Create a new instance using the specified list of child components in
097 * order {@link Region#north}, {@link Region#west}, {@link Region#center},
098 * {@link Region#east}, and {@link Region#south}. If the specified list has
099 * only one child, it is added to the {@link Region#center} area.
100 *
101 * @param list The list of child components.
102 * @throws IllegalArgumentException If the list contains more than 5 components.
103 */
104 public BorderLayout( final List<Component> list )
105 {
106 if ( list.size() > 5 )
107 {
108 throw new IllegalArgumentException(
109 "BorderLayout can contain only 5 child components" );
110 }
111
112 if ( list.size() == 1 )
113 {
114 add( list.get( 0 ) );
115 }
116 else
117 {
118 for ( int i = 0; i < list.size(); ++i )
119 {
120 Region region;
121
122 switch ( i )
123 {
124 case 0:
125 region = Region.north;
126 break;
127 case 1:
128 region = Region.west;
129 break;
130 case 3:
131 region = Region.east;
132 break;
133 case 4:
134 region = Region.south;
135 break;
136 default:
137 region = Region.center;
138 break;
139 }
140
141 add( list.get( i ), region );
142 }
143 }
144 }
145
146 /**
147 * Add the specified child component to the specified region.
148 *
149 * @param component The child component to add to the layout container.
150 * @param region The region to which the component is to be added.
151 * @throws IllegalArgumentException If a component already exists at the
152 * specified region index.
153 */
154 public void add( final Component component, final Region region )
155 {
156 if ( regionToIndex.containsKey( region ) )
157 {
158 throw new IllegalArgumentException(
159 "Component " + component + " illegally added to BorderLayout " +
160 "at region: " + region );
161 }
162
163 int index = getComponentCount();
164 super.add( component, index );
165 regionToIndex.put( region, index );
166 indexToRegion.put( index, region );
167 }
168
169 /**
170 * Over-ridden to add the component to {@link Region#center}.
171 *
172 * {@inheritDoc}
173 * @throws IllegalArgumentException If invoked more than once or if the
174 * index is greater than 0.
175 */
176 @Override
177 public void add( final Component component, final int index )
178 throws IllegalChildException
179 {
180 if ( index > 0 )
181 {
182 throw new IllegalArgumentException(
183 "Component " + component + " illegally added to BorderLayout " +
184 "at region: center" );
185 }
186
187 add( component, Region.center );
188 }
189
190 /**
191 * Over-ridden to add the component to {@link Region#center}.
192 *
193 * {@inheritDoc}
194 * @throws IllegalArgumentException If invoked more than once.
195 */
196 @Override
197 public void add( final Component component )
198 {
199 add( component, Region.center );
200 }
201
202 /**
203 * Return the child component for the specified region.
204 *
205 * @param region The region for which the child component is to be retrieved.
206 * @return Returns the child component or {@code null} if no child exists.
207 */
208 public Component getComponent( final Region region )
209 {
210 if ( ! regionToIndex.containsKey( region ) ) return null;
211 return getComponent( regionToIndex.get( region ) );
212 }
213
214 /**
215 * Over-ridden to clear the maps used to maintain region to child index
216 * relationships.
217 *
218 * {@inheritDoc}
219 */
220 @Override
221 public void dispose()
222 {
223 regionToIndex.clear();
224 indexToRegion.clear();
225 super.dispose();
226 }
227
228 /**
229 * Return the mappings for the region to child index.
230 *
231 * @return The map with the region as key.
232 */
233 Map<Region,Integer> getRegionToIndex()
234 {
235 return regionToIndex;
236 }
237
238 /**
239 * Return the mappings for the child index to region.
240 *
241 * @return The map with the child index as key
242 */
243 Map<Integer,Region> getIndexToRegion()
244 {
245 return indexToRegion;
246 }
247 }