KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > layoutdesign > support > SwingLayoutBuilder


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form.layoutdesign.support;
21
22 import java.awt.*;
23 import java.util.*;
24 import java.util.List JavaDoc;
25 import javax.swing.*;
26
27 import org.jdesktop.layout.LayoutStyle;
28 import org.jdesktop.layout.GroupLayout;
29
30 import org.netbeans.modules.form.layoutdesign.*;
31
32 /**
33  * This class constructs real layout of AWT/Swing components based on the
34  * layout model.
35  *
36  * @author Jan Stola, Tomas Pavek
37  */

38 public class SwingLayoutBuilder {
39
40     private LayoutModel layoutModel;
41
42     /**
43      * Container being layed out.
44      */

45     private Container container;
46
47     /**
48      * LayoutComponent for the container.
49      */

50     private LayoutComponent containerLC;
51
52     /**
53      * Maps from component ID to Component.
54      */

55     private Map/*<String,Component>*/ componentIDMap;
56
57     private boolean designMode;
58
59     public SwingLayoutBuilder(LayoutModel layoutModel,
60                               Container container, String JavaDoc containerId,
61                               boolean designMode)
62     {
63         componentIDMap = new HashMap/*<String,Component>*/();
64         this.layoutModel = layoutModel;
65         this.container = container;
66         this.containerLC = layoutModel.getLayoutComponent(containerId);
67         this.designMode = designMode;
68     }
69
70     /**
71      * Sets up layout of a container and adds all components to it according
72      * to the layout model. This method is used for initial construction of
73      * the layout visual representation (layout view).
74      */

75     public void setupContainerLayout(Component[] components, String JavaDoc[] compIds) {
76 // addComponentsToContainer(components, compIds);
77
for (int counter = 0; counter < components.length; counter++) {
78             componentIDMap.put(compIds[counter], components[counter]);
79         }
80         createLayout();
81     }
82
83     /**
84      * Adds new components to a container (according to the layout model).
85      * This method is used for incremental updates of the layout view.
86      */

87 // public void addComponentsToContainer(Component[] components, String[] compIds) {
88
// if (components.length != compIds.length) {
89
// throw new IllegalArgumentException("Sizes must match");
90
// }
91
// for (int counter = 0; counter < components.length; counter++) {
92
// componentIDMap.put(compIds[counter], components[counter]);
93
// }
94
// layout();
95
// }
96

97     /**
98      * Removes components from a container. This method is used for incremental
99      * updates of the layout view.
100      */

101     public void removeComponentsFromContainer(Component[] components, String JavaDoc[] compIds) {
102         if (components.length != compIds.length) {
103             throw new IllegalArgumentException JavaDoc("Sizes must match"); // NOI18N
104
}
105         for (int counter = 0; counter < components.length; counter++) {
106             componentIDMap.remove(compIds[counter]);
107         }
108         createLayout();
109     }
110
111     /**
112      * Clears given container - removes all components. This method is used
113      * for incremental updates of the layout view.
114      */

115     public void clearContainer() {
116         container.removeAll();
117         componentIDMap.clear();
118     }
119
120     public void createLayout() {
121         Throwable JavaDoc th = null;
122         boolean reset = true;
123         container.removeAll();
124         try {
125             GroupLayout layout = new GroupLayout(container);
126             container.setLayout(layout);
127             LayoutInterval horizontalInterval = containerLC.getLayoutRoot(LayoutConstants.HORIZONTAL);
128             GroupLayout.Group horizontalGroup = composeGroup(layout, horizontalInterval, true, true);
129             layout.setHorizontalGroup(horizontalGroup);
130             LayoutInterval verticalInterval = containerLC.getLayoutRoot(LayoutConstants.VERTICAL);
131             GroupLayout.Group verticalGroup = composeGroup(layout, verticalInterval, true, true);
132             layout.setVerticalGroup(verticalGroup);
133             composeLinks(layout);
134             // Try to create the layout (to be able to reset it in case of some problem)
135
layout.layoutContainer(container);
136             layout.invalidateLayout(container);
137             reset = false;
138         } finally {
139             if (reset) {
140                 container.setLayout(null);
141             }
142         }
143     }
144     
145     public void doLayout() {
146         container.doLayout();
147     }
148
149     public static boolean isRelevantContainer(Container cont) {
150         return cont.getLayout() != null
151                && cont.getLayout().getClass().getName().equals("org.jdesktop.layout.GroupLayout"); // NOI18N
152
}
153
154     // -----
155

156     private GroupLayout.Group composeGroup(GroupLayout layout, LayoutInterval interval,
157                                             boolean first, boolean last) {
158         GroupLayout.Group group = null;
159         if (interval.isGroup()) {
160             if (interval.isParallel()) {
161                 int groupAlignment = convertAlignment(interval.getGroupAlignment());
162                 boolean notResizable = interval.getMaximumSize(designMode) == LayoutConstants.USE_PREFERRED_SIZE;
163                 group = layout.createParallelGroup(groupAlignment, !notResizable);
164             } else if (interval.isSequential()) {
165                 group = layout.createSequentialGroup();
166             } else {
167                 assert false;
168             }
169             Iterator subIntervals = interval.getSubIntervals();
170             while (subIntervals.hasNext()) {
171                 LayoutInterval subInterval = (LayoutInterval)subIntervals.next();
172                 fillGroup(layout, group, subInterval,
173                           first,
174                           last && (!interval.isSequential() || !subIntervals.hasNext()));
175                 if (first && interval.isSequential()) {
176                     first = false;
177                 }
178             }
179         } else {
180             group = layout.createSequentialGroup();
181             fillGroup(layout, group, interval, true, true);
182         }
183         return group;
184     }
185     
186     private void fillGroup(GroupLayout layout, GroupLayout.Group group, LayoutInterval interval,
187                            boolean first, boolean last) {
188         int alignment = getIntervalAlignment(interval);
189         if (interval.isGroup()) {
190             if (group instanceof GroupLayout.SequentialGroup) {
191                 ((GroupLayout.SequentialGroup)group).add(composeGroup(layout, interval, first, last));
192             } else {
193                 ((GroupLayout.ParallelGroup)group).add(
194                         convertAlignment(alignment),
195                         composeGroup(layout, interval, first, last));
196             }
197         } else {
198             int minimum = interval.getMinimumSize(designMode);
199             int preferred = interval.getPreferredSize(designMode);
200             int min = convertSize(minimum, interval);
201             int pref = convertSize(preferred, interval);
202             int max = convertSize(interval.getMaximumSize(designMode), interval);
203             if (interval.isComponent()) {
204                 LayoutComponent layoutComp = interval.getComponent();
205                 Component comp = (Component)componentIDMap.get(layoutComp.getId());
206                 assert (comp != null);
207                 if (minimum == LayoutConstants.NOT_EXPLICITLY_DEFINED) {
208                     int dimension = (layoutComp.getLayoutInterval(LayoutConstants.HORIZONTAL) == interval) ? LayoutConstants.HORIZONTAL : LayoutConstants.VERTICAL;
209                     if ((dimension == LayoutConstants.HORIZONTAL) && comp.getClass().getName().equals("javax.swing.JComboBox")) { // Issue 68612 // NOI18N
210
min = 0;
211                     } else if (preferred >= 0) {
212                         Dimension minDim = comp.getMinimumSize();
213                         int compMin = (dimension == LayoutConstants.HORIZONTAL) ? minDim.width : minDim.height;
214                         if (compMin > preferred) {
215                             min = convertSize(LayoutConstants.USE_PREFERRED_SIZE, interval);
216                         }
217                     }
218                 }
219                 if (group instanceof GroupLayout.SequentialGroup) {
220                     ((GroupLayout.SequentialGroup)group).add(comp, min, pref, max);
221                 } else {
222                     GroupLayout.ParallelGroup pGroup = (GroupLayout.ParallelGroup)group;
223                     pGroup.add(convertAlignment(alignment), comp, min, pref, max);
224                 }
225             } else {
226                 assert interval.isEmptySpace();
227                 if (interval.isDefaultPadding(designMode)) {
228                     assert (group instanceof GroupLayout.SequentialGroup);
229                     GroupLayout.SequentialGroup seqGroup = (GroupLayout.SequentialGroup)group;
230                     if (first || last) {
231                         seqGroup.addContainerGap(pref, max);
232                     } else {
233                         seqGroup.addPreferredGap(LayoutStyle.RELATED, pref, max);
234                     }
235                 } else {
236                     if (min < 0) min = pref; // min == GroupLayout.PREFERRED_SIZE
237
min = Math.min(pref, min);
238                     max = Math.max(pref, max);
239                     if (group instanceof GroupLayout.SequentialGroup) {
240                         ((GroupLayout.SequentialGroup)group).add(min, pref, max);
241                     } else {
242                         ((GroupLayout.ParallelGroup)group).add(min, pref, max);
243                     }
244                 }
245             }
246         }
247     }
248
249     /**
250      * Filters out invalid use of BASELINE alignment (see issue 78035).
251      * This method is a last resort to avoid failure in building the view.
252      * See also LayoutModel.checkAndFixGroup method.
253      */

254     private static int getIntervalAlignment(LayoutInterval interval) {
255         int alignment = interval.getAlignment();
256         LayoutInterval group = interval.getParent();
257         if (group.isParallel()) {
258             int groupAlignment = group.getGroupAlignment();
259             if ((alignment == LayoutConstants.BASELINE && groupAlignment != LayoutConstants.BASELINE)
260                 || (alignment != LayoutConstants.BASELINE && groupAlignment == LayoutConstants.BASELINE))
261             { // illegal combination, follow the group alignment
262
alignment = groupAlignment;
263                 System.err.println("WARNING: Illegal use of baseline alignment, ignoring interval's alignment."); // NOI18N
264
// assert false;
265
}
266         }
267         else if (alignment != LayoutConstants.DEFAULT) {
268             System.err.println("WARNING: Ignoring non-default alignment of interval in sequential group."); // NOI18N
269
// assert false;
270
}
271
272         return alignment;
273     }
274
275     private static int convertAlignment(int alignment) {
276         int groupAlignment = 0;
277         switch (alignment) {
278             case LayoutConstants.DEFAULT: groupAlignment = GroupLayout.LEADING; break;
279             case LayoutConstants.LEADING: groupAlignment = GroupLayout.LEADING; break;
280             case LayoutConstants.TRAILING: groupAlignment = GroupLayout.TRAILING; break;
281             case LayoutConstants.CENTER: groupAlignment = GroupLayout.CENTER; break;
282             case LayoutConstants.BASELINE: groupAlignment = GroupLayout.BASELINE; break;
283             default: assert false; break;
284         }
285         return groupAlignment;
286     }
287     
288     private int convertSize(int size, LayoutInterval interval) {
289         int convertedSize;
290         switch (size) {
291             case LayoutConstants.NOT_EXPLICITLY_DEFINED: convertedSize = GroupLayout.DEFAULT_SIZE; break;
292             case LayoutConstants.USE_PREFERRED_SIZE:
293                 convertedSize = interval.isEmptySpace() ?
294                                 convertSize(interval.getPreferredSize(designMode), interval) :
295                                 GroupLayout.PREFERRED_SIZE;
296                 break;
297             default: assert (size >= 0); convertedSize = size; break;
298         }
299         return convertedSize;
300     }
301
302     private void composeLinks(GroupLayout layout) {
303         composeLinks(layout, LayoutConstants.HORIZONTAL);
304         composeLinks(layout, LayoutConstants.VERTICAL);
305     }
306     
307     private void composeLinks(GroupLayout layout, int dimension) {
308
309         Map links = SwingLayoutUtils.createLinkSizeGroups(containerLC, dimension);
310         
311         Set linksSet = links.keySet();
312         Iterator i = linksSet.iterator();
313         while (i.hasNext()) {
314             List JavaDoc group = (List JavaDoc)links.get(i.next());
315             List JavaDoc components = new ArrayList();
316             for (int j=0; j < group.size(); j++) {
317                 String JavaDoc compId = (String JavaDoc)group.get(j);
318                 LayoutComponent lc = layoutModel.getLayoutComponent(compId);
319                 if (lc != null) {
320                     Component comp = (Component)componentIDMap.get(lc.getId());
321                     if (comp == null) {
322                         return;
323                     } else {
324                         components.add(comp);
325                     }
326                 }
327             }
328             Component[] compArray = (Component[])components.toArray(new Component[components.size()]);
329             if (compArray != null) {
330                 if (dimension == LayoutConstants.HORIZONTAL) {
331                     layout.linkSize(compArray, GroupLayout.HORIZONTAL);
332                 }
333                 if (dimension == LayoutConstants.VERTICAL) {
334                     layout.linkSize(compArray, GroupLayout.VERTICAL);
335                 }
336             }
337         }
338     }
339
340 }
341
Popular Tags