1 package org.catacomb.druid.swing.split;
2
3 import java.awt.*;
4 import java.util.Hashtable;
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 @SuppressWarnings("all")
73 public class SplitterLayout implements LayoutManager2, java.io.Serializable {
74
75 private static final long serialVersionUID = 1L;
76
77 public static final int VERTICAL = 0;
78 public static final int HORIZONTAL = 1;
79
80 protected static DSplitterBar dragee = null;
81
82 private int lastW = -1;
83 private int lastH = -1;
84 private boolean newComponentAdded = false;
85 private Hashtable<Component, Object> relations = null;
86
87
88 private int fieldOrientation = VERTICAL;
89
90
91
92 public SplitterLayout() {
93 this(VERTICAL);
94 }
95
96 public SplitterLayout(int orientation) {
97 setOrientation(orientation);
98 relations = new Hashtable<Component, Object>();
99 }
100
101
102
103
104 public final void addLayoutComponent(Component comp, Object cin) {
105 Object constraints = cin;
106 if (constraints == null) constraints = "1";
107 if (constraints instanceof Integer) {
108 relations.put(comp, constraints);
109 newComponentAdded = true;
110 }
111 else
112 addLayoutComponent((String)constraints, comp);
113 }
114
115
116
117
118 public final void addLayoutComponent(String name, Component comp) {
119 newComponentAdded = true;
120 if (comp instanceof DSplitterBar) {
121 ((DSplitterBar)comp).setOrientation(getOrientation());
122 }
123 else {
124 if (name == null) name = "1";
125 try {
126 relations.put(comp, Integer.decode(name));
127 }
128 catch (NumberFormatException e) {
129 relations.put(comp, new Integer(1));
130 }
131 }
132 }
133 public final Dimension checkLayoutSize(Container target, boolean getPrefSize) {
134 Dimension dim = new Dimension(0, 0);
135 Component c[] = target.getComponents();
136
137 Dimension d;
138 for (int i = 0; i < c.length; i++)
139 if (c[i].isVisible()) {
140 if (getPrefSize || (c[i] instanceof DSplitterBar))
141 d = c[i].getPreferredSize();
142 else
143 d = c[i].getMinimumSize();
144 if (getOrientation() == VERTICAL) {
145 dim.width = Math.max(d.width, dim.width);
146 dim.height += d.height;
147 }
148 else {
149 dim.height = Math.max(d.height, dim.height);
150 dim.width += d.width;
151 }
152 }
153
154 Insets insets = target.getInsets();
155 dim.width += insets.left + insets.right;
156 dim.height += insets.top + insets.bottom;
157
158 return dim;
159 }
160
161 public final float getLayoutAlignmentX(Container parent) {
162 return 0.5f;
163 }
164
165 public final float getLayoutAlignmentY(Container parent) {
166 return 0.5f;
167 }
168
169 public int getOrientation() {
170
171 return fieldOrientation;
172 }
173
174 public final void invalidateLayout(Container target) {}
175
176 public final void layoutContainer(Container target) {
177 Insets insets = target.getInsets();
178 Dimension dim = target.getSize();
179 int top = insets.top;
180 int bottom = dim.height - insets.bottom;
181 int left = insets.left;
182 int right = dim.width - insets.right;
183
184 boolean reScaleW = false, reScaleH=false;
185 float scaleW = 0, scaleH = 0;
186
187
188 if (lastW == -1) {
189 lastW = dim.width;
190 lastH = dim.height;
191 }
192 else {
193 if (lastW != dim.width) {
194 reScaleW = true;
195 scaleW = (float)dim.width/(float)lastW;
196 lastW = dim.width;
197 }
198 if (lastH != dim.height) {
199 reScaleH = true;
200 scaleH = (float)dim.height/(float)lastH;
201 lastH = dim.height;
202 }
203 }
204
205 dim.width = right - left;
206 dim.height = bottom - top;
207
208
209
210 int relativeSize = 0;
211 int numRelatives = 0;
212
213 Component c[] = target.getComponents();
214 Object pSize[] = new Object[c.length];
215 int orientation = getOrientation();
216 for (int i = 0; i < c.length; i++) {
217 if (c[i].isVisible())
218 if (c[i] instanceof DSplitterBar) {
219 ((DSplitterBar)c[i]).setOrientation(orientation);
220 pSize[i] = c[i].getPreferredSize();
221 if (orientation == VERTICAL) {
222 dim.height -= ((Dimension)pSize[i]).height;
223 if (reScaleH) {
224 Point p = c[i].getLocation();
225 c[i].setLocation(p.x,(int)((p.y)*scaleH));
226
227 }
228 }
229 else {
230 dim.width -= ((Dimension)pSize[i]).width;
231 if (reScaleW) {
232 Point p = c[i].getLocation();
233 c[i].setLocation((int)((p.x)*scaleW),p.y);
234
235 }
236 }
237 }
238 else {
239 pSize[i] = relations.get(c[i]);
240 relativeSize += ((Integer)pSize[i]).intValue();
241 numRelatives++;
242 }
243 }
244
245
246
247 for (int i = 0; i < c.length; i++)
248 if (c[i].isVisible()) {
249 Rectangle r = c[i].getBounds();
250 if (c[i] instanceof DSplitterBar)
251 if (orientation == VERTICAL) {
252 if (r.x != left || r.y != top || r.width != dim.width || r.height != ((Dimension)pSize[i]).height)
253 c[i].setBounds(left,top,dim.width,((Dimension)pSize[i]).height);
254 top += ((Dimension)pSize[i]).height;
255 }
256 else {
257 if (r.x != left || r.y != top || r.height != dim.height || r.width != ((Dimension)pSize[i]).width)
258 c[i].setBounds(left,top,((Dimension)pSize[i]).width,dim.height);
259 left += ((Dimension)pSize[i]).width;
260 }
261 else {
262 if (i == (c.length-1)) {
263 if (orientation == VERTICAL) {
264 if (r.x != left || r.y != top || r.width != dim.width || r.height != (bottom-top))
265 c[i].setBounds(left,top,dim.width,bottom-top);
266 }
267 else {
268 if (r.x != left || r.y != top || r.width != (right-left) || r.height != dim.height)
269 c[i].setBounds(left,top,right-left,dim.height);
270 }
271 }
272 else {
273
274 Point p = c[i+1].getLocation();
275 if (!newComponentAdded &&
276 (c[i+1] instanceof DSplitterBar) && (p.x != 0 || p.y != 0)) {
277 if (orientation == VERTICAL) {
278 if (r.x != left || r.y != top || r.width != dim.width || r.height != (p.y-top))
279 c[i].setBounds(left,top,dim.width,p.y-top);
280 top = p.y;
281 }
282 else {
283 if (r.x != left || r.y != top || r.width != (p.x-left) || r.height != dim.height)
284 c[i].setBounds(left,top,p.x-left,dim.height);
285 left = p.x;
286 }
287 }
288 else {
289 int rel = ((Integer)pSize[i]).intValue();
290 float ratio = ((float)rel/(float)relativeSize);
291 if (orientation == VERTICAL) {
292 ratio *= dim.height;
293 if (r.x != left || r.y != top || r.width != dim.width || r.height != (int)ratio)
294 c[i].setBounds(left,top,dim.width,(int)ratio);
295 top += (int)ratio;
296 }
297 else {
298 ratio *= dim.width;
299 if (r.x != left || r.y != top || r.width != (int)ratio || r.height != dim.height)
300 c[i].setBounds(left,top,(int)ratio,dim.height);
301 left += (int)ratio;
302 }
303 }
304 }
305 }
306 }
307 newComponentAdded = false;
308 }
309
310 public final Dimension maximumLayoutSize(Container target) {
311 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
312 }
313
314
315
316 public final Dimension minimumLayoutSize(Container target) {
317 return checkLayoutSize(target, true);
318 }
319
320
321
322 public final Dimension preferredLayoutSize(Container target) {
323 return checkLayoutSize(target, true);
324 }
325
326 public final void removeLayoutComponent(Component comp) {
327 relations.remove(comp);
328 newComponentAdded = true;
329 }
330
331 public void setOrientation(int orientation) {
332 fieldOrientation = orientation;
333 return;
334 }
335 public void swapOrientation(Container container) {
336 setOrientation((getOrientation() == HORIZONTAL)?VERTICAL:HORIZONTAL);
337 Component comps[] = container.getComponents();
338 for (int i = container.getComponentCount()-1; i>-1; i--) {
339 if (comps[i] instanceof DSplitterBar)
340 ((DSplitterBar)comps[i]).swapOrientation();
341 comps[i].invalidate();
342 }
343 newComponentAdded = true;
344 container.validate();
345 }
346
347 public final String toString() {
348 if (getOrientation() == VERTICAL)
349 return getClass().getName() + "[orientation=VERTICAL]";
350 else
351 return getClass().getName() + "[orientation=HORIZONTAL]";
352 }
353 }