View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Intersect Software Corporation
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.ui.swing.components;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Component;
23  import java.awt.Container;
24  import java.awt.Dimension;
25  import java.awt.Insets;
26  import java.awt.Rectangle;
27  
28  import javax.swing.JPanel;
29  import javax.swing.JRootPane;
30  
31  /*** 
32  * A custom layout for a JRootPane that handles the the layout of a 
33  * JRootPane's layeredPane, glassPane, and menuBar, and in addition
34  * handles four decorative components arranged in a border layout.
35  * Add the decorative components to the JRootPane using the directional
36  * constants; CENTER is reserved for the content pane and menu bar. 
37  *
38  * @author michael@mpowers.net
39  * @version $Revision: 904 $
40  */
41  public class BetterRootLayout extends BorderLayout
42  {
43  	/***
44  	 * Returns the amount of space the layout would like to have.
45  	 *
46  	 * @param the Container for which this layout manager is being used
47  	 * @return a Dimension object containing the layout's preferred size
48  	 * @throws ClassCastException if parent is not a JRootPane
49  	 */ 
50  	public Dimension preferredLayoutSize(Container parent) 
51  	{
52  		JRootPane rootPane = (JRootPane) parent;
53  		
54  		JPanel proxyPanel = new JPanel();
55  		proxyPanel.setLayout( new BorderLayout() );
56  		
57  		JPanel contentProxy = null;
58  		if(rootPane.getContentPane() != null) {
59  			contentProxy = new JPanel();
60  			contentProxy.setMinimumSize( 
61  				rootPane.getContentPane().getMinimumSize() );
62  			contentProxy.setMaximumSize( 
63  				rootPane.getContentPane().getMaximumSize() );
64  			contentProxy.setPreferredSize( 
65  				rootPane.getContentPane().getPreferredSize() );
66  			proxyPanel.add( contentProxy, CENTER );
67  		}
68  		JPanel menuProxy = null;
69  		if(rootPane.getJMenuBar() != null) {
70  			menuProxy = new JPanel();
71  			menuProxy.setMinimumSize( 
72  				rootPane.getJMenuBar().getMinimumSize() );
73  			menuProxy.setMaximumSize( 
74  				rootPane.getJMenuBar().getMaximumSize() );
75  			menuProxy.setPreferredSize( 
76  				rootPane.getJMenuBar().getPreferredSize() );
77  			proxyPanel.add( menuProxy, NORTH );
78  		}
79  		
80  		this.addLayoutComponent( proxyPanel, CENTER );
81  		
82  		Dimension result = super.preferredLayoutSize( parent );
83  
84  		this.removeLayoutComponent( proxyPanel );
85  		
86  		proxyPanel.removeAll();
87  		
88  		return result;
89  	}
90  	
91  	/***
92  	 * Returns the minimum amount of space the layout needs.
93  	 *
94  	 * @param the Container for which this layout manager is being used
95  	 * @return a Dimension object containing the layout's minimum size
96  	 * @throws ClassCastException if parent is not a JRootPane
97  	 */ 
98  	public Dimension minimumLayoutSize(Container parent) 
99  	{
100 		JRootPane rootPane = (JRootPane) parent;
101 		
102 		JPanel proxyPanel = new JPanel();
103 		proxyPanel.setLayout( new BorderLayout() );
104 		
105 		JPanel contentProxy = null;
106 		if(rootPane.getContentPane() != null) {
107 			contentProxy = new JPanel();
108 			contentProxy.setMinimumSize( 
109 				rootPane.getContentPane().getMinimumSize() );
110 			contentProxy.setMaximumSize( 
111 				rootPane.getContentPane().getMaximumSize() );
112 			contentProxy.setPreferredSize( 
113 				rootPane.getContentPane().getPreferredSize() );
114 			proxyPanel.add( contentProxy, CENTER );
115 		}
116 		JPanel menuProxy = null;
117 		if(rootPane.getJMenuBar() != null) {
118 			menuProxy = new JPanel();
119 			menuProxy.setMinimumSize( 
120 				rootPane.getJMenuBar().getMinimumSize() );
121 			menuProxy.setMaximumSize( 
122 				rootPane.getJMenuBar().getMaximumSize() );
123 			menuProxy.setPreferredSize( 
124 				rootPane.getJMenuBar().getPreferredSize() );
125 			proxyPanel.add( menuProxy, NORTH );
126 		}
127 		
128 		this.addLayoutComponent( proxyPanel, CENTER );
129 		
130 		Dimension result = super.minimumLayoutSize( parent );
131 
132 		this.removeLayoutComponent( proxyPanel );
133 		
134 		proxyPanel.removeAll();
135 		
136 		return result;
137 	}
138 	
139 	/***
140 	 * Returns the maximum amount of space the layout can use.
141 	 *
142 	 * @param the Container for which this layout manager is being used
143 	 * @return a Dimension object containing the layout's maximum size
144 	 * @throws ClassCastException if parent is not a JRootPane
145 	 */ 
146 	public Dimension maximumLayoutSize(Container target) 
147 	{
148 		JRootPane rootPane = (JRootPane) target;
149 		
150 		JPanel proxyPanel = new JPanel();
151 		proxyPanel.setLayout( new BorderLayout() );
152 		
153 		JPanel contentProxy = null;
154 		if(rootPane.getContentPane() != null) {
155 			contentProxy = new JPanel();
156 			contentProxy.setMinimumSize( 
157 				rootPane.getContentPane().getMinimumSize() );
158 			contentProxy.setMaximumSize( 
159 				rootPane.getContentPane().getMaximumSize() );
160 			contentProxy.setPreferredSize( 
161 				rootPane.getContentPane().getPreferredSize() );
162 			proxyPanel.add( contentProxy, CENTER );
163 		}
164 		JPanel menuProxy = null;
165 		if(rootPane.getJMenuBar() != null) {
166 			menuProxy = new JPanel();
167 			menuProxy.setMinimumSize( 
168 				rootPane.getJMenuBar().getMinimumSize() );
169 			menuProxy.setMaximumSize( 
170 				rootPane.getJMenuBar().getMaximumSize() );
171 			menuProxy.setPreferredSize( 
172 				rootPane.getJMenuBar().getPreferredSize() );
173 			proxyPanel.add( menuProxy, NORTH );
174 		}
175 		
176 		this.addLayoutComponent( proxyPanel, CENTER );
177 		
178 		Dimension result = super.maximumLayoutSize( target );
179 
180 		this.removeLayoutComponent( proxyPanel );
181 		
182 		proxyPanel.removeAll();
183 		
184 		return result;
185 	}
186 	
187 	/***
188 	 * Instructs the layout manager to perform the layout for the specified
189 	 * container.
190 	 *
191 	 * @param the Container for which this layout manager is being used
192 	 * @throws ClassCastException if parent is not a JRootPane
193 	 */ 
194 	public void layoutContainer(Container parent) 
195 	{
196 		JRootPane rootPane = (JRootPane) parent;
197 		
198 		Rectangle b = parent.getBounds();
199 		Insets i = rootPane.getInsets();
200 		int w = b.width - i.right - i.left;
201 		int h = b.height - i.top - i.bottom;
202 	
203 		// layout panes
204 
205 		if(rootPane.getLayeredPane() != null) {
206 			rootPane.getLayeredPane().setBounds(i.left, i.top, w, h);
207 		}
208 		if(rootPane.getGlassPane() != null) {
209 			rootPane.getGlassPane().setBounds(i.left, i.top, w, h);
210 		}
211 		
212 		// handle proxy panel
213 		
214 		JPanel proxyPanel = new JPanel();
215 		proxyPanel.setLayout( new BorderLayout() );
216 		
217 		this.addLayoutComponent( proxyPanel, CENTER );
218 		
219 		super.layoutContainer( parent );
220 
221 		// use proxy sizes to set sizes of layeredPane's children
222 
223 		Rectangle proxyRect = proxyPanel.getBounds();
224 		if(rootPane.getJMenuBar() != null) {
225 			Rectangle menuRect = proxyPanel.getBounds();
226 			menuRect.height = rootPane.getJMenuBar().getPreferredSize().height;
227 			rootPane.getJMenuBar().setBounds( menuRect );
228 			proxyRect.y += menuRect.height;
229 			proxyRect.height -= menuRect.height;
230 		}
231 		if(rootPane.getContentPane() != null) {
232 			rootPane.getContentPane().setBounds( proxyRect );
233 		}
234 
235 		this.removeLayoutComponent( proxyPanel );
236 		
237 		proxyPanel.removeAll();
238 	}
239 	
240 	/***
241 	* Passes NORTH, SOUTH, EAST, WEST and CENTER to super implementation,
242 	* and ignores all others.
243 	*/
244 	public void addLayoutComponent(Component comp, Object constraints) 
245 	{
246 		if ( NORTH.equals( constraints ) )
247 		{
248 			super.addLayoutComponent( comp, constraints );
249 		}
250 		else
251 		if ( SOUTH.equals( constraints ) )
252 		{
253 			super.addLayoutComponent( comp, constraints );
254 		}
255 		else
256 		if ( EAST.equals( constraints ) )
257 		{
258 			super.addLayoutComponent( comp, constraints );
259 		}
260 		else
261 		if ( WEST.equals( constraints ) )
262 		{
263 			super.addLayoutComponent( comp, constraints );
264 		}
265 		else
266 		if ( CENTER.equals( constraints ) )
267 		{
268 			super.addLayoutComponent( comp, constraints );
269 		}
270 		
271 		// otherwise, ignore
272 	}
273 }
274