KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > layout > LayoutGenerator


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.layout;
12 import org.eclipse.jface.util.Geometry;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.events.ModifyListener;
15 import org.eclipse.swt.graphics.Point;
16 import org.eclipse.swt.layout.GridData;
17 import org.eclipse.swt.layout.GridLayout;
18 import org.eclipse.swt.widgets.Button;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Layout;
22 import org.eclipse.swt.widgets.Scrollable;
23
24 /* package */class LayoutGenerator {
25
26     /**
27      * Default size for controls with varying contents
28      */

29     private static final Point defaultSize = new Point(150, 150);
30
31     /**
32      * Default wrapping size for wrapped labels
33      */

34     private static final int wrapSize = 350;
35
36     private static final GridDataFactory nonWrappingLabelData = GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).grab(false, false);
37
38     private static boolean hasStyle(Control c, int style) {
39         return (c.getStyle() & style) != 0;
40     }
41
42     /**
43      * Generates a GridLayout for the given composite by examining its child
44      * controls and attaching layout data to any immediate children that do not
45      * already have layout data.
46      *
47      * @param toGenerate
48      * composite to generate a layout for
49      */

50     public static void generateLayout(Composite toGenerate) {
51         Control[] children = toGenerate.getChildren();
52
53         for (int i = 0; i < children.length; i++) {
54             Control control = children[i];
55
56             // Skip any children that already have layout data
57
if (control.getLayoutData() != null) {
58                 continue;
59             }
60
61             applyLayoutDataTo(control);
62         }
63     }
64
65     private static void applyLayoutDataTo(Control control) {
66         defaultsFor(control).applyTo(control);
67     }
68     
69     /**
70      * Creates default factory for this control types:
71      * <ul>
72      * <li>{@link Button} with {@link SWT#CHECK}</li>
73      * <li>{@link Button}</li>
74      * <li>{@link Composite}</li>
75      * </ul>
76      * @param control the control the factory is search for
77      * @return a default factory for the control
78      */

79     public static GridDataFactory defaultsFor(Control control) {
80         if (control instanceof Button) {
81             Button button = (Button) control;
82
83             if (hasStyle(button, SWT.CHECK)) {
84                 return nonWrappingLabelData.copy();
85             } else {
86                 return GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).hint(Geometry.max(button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true), LayoutConstants.getMinButtonSize()));
87             }
88         }
89
90         if (control instanceof Scrollable) {
91             Scrollable scrollable = (Scrollable) control;
92
93             if (scrollable instanceof Composite) {
94                 Composite composite = (Composite) control;
95
96                 Layout theLayout = composite.getLayout();
97                 if (theLayout instanceof GridLayout) {
98                     boolean growsHorizontally = false;
99                     boolean growsVertically = false;
100
101                     Control[] children = composite.getChildren();
102                     for (int i = 0; i < children.length; i++) {
103                         Control child = children[i];
104
105                         GridData data = (GridData) child.getLayoutData();
106
107                         if (data != null) {
108                             if (data.grabExcessHorizontalSpace) {
109                                 growsHorizontally = true;
110                             }
111                             if (data.grabExcessVerticalSpace) {
112                                 growsVertically = true;
113                             }
114                         }
115                     }
116
117                     return GridDataFactory.fillDefaults().grab(growsHorizontally, growsVertically);
118                 }
119             }
120         }
121
122         boolean wrapping = hasStyle(control, SWT.WRAP);
123
124         // Assume any control with the H_SCROLL or V_SCROLL flags are
125
// horizontally or vertically
126
// scrollable, respectively.
127
boolean hScroll = hasStyle(control, SWT.H_SCROLL);
128         boolean vScroll = hasStyle(control, SWT.V_SCROLL);
129
130         boolean containsText = hasMethod(control, "setText", new Class JavaDoc[] { String JavaDoc.class }); //$NON-NLS-1$
131

132         // If the control has a setText method, an addModifyListener method, and
133
// does not have
134
// the SWT.READ_ONLY flag, assume it contains user-editable text.
135
boolean userEditable = !hasStyle(control, SWT.READ_ONLY) && containsText && hasMethod(control, "addModifyListener", new Class JavaDoc[] { ModifyListener.class }); //$NON-NLS-1$
136

137         // For controls containing user-editable text...
138
if (userEditable) {
139             if (hasStyle(control, SWT.MULTI)) {
140                 vScroll = true;
141             }
142
143             if (!wrapping) {
144                 hScroll = true;
145             }
146         }
147
148         // Compute the horizontal hint
149
int hHint = SWT.DEFAULT;
150         boolean grabHorizontal = hScroll;
151
152         // For horizontally-scrollable controls, override their horizontal
153
// preferred size
154
// with a constant
155
if (hScroll) {
156             hHint = defaultSize.x;
157         } else {
158             // For wrapping controls, there are two cases.
159
// 1. For controls that contain text (like wrapping labels,
160
// read-only text boxes,
161
// etc.) override their preferred size with the preferred wrapping
162
// point and
163
// make them grab horizontal space.
164
// 2. For non-text controls (like wrapping toolbars), assume that
165
// their non-wrapped
166
// size is best.
167

168             if (wrapping) {
169                 if (containsText) {
170                     hHint = wrapSize;
171                     grabHorizontal = true;
172                 }
173             }
174         }
175
176         int vAlign = SWT.FILL;
177
178         // Heuristic for labels: Controls that contain non-wrapping read-only
179
// text should be
180
// center-aligned rather than fill-aligned
181
if (!vScroll && !wrapping && !userEditable && containsText) {
182             vAlign = SWT.CENTER;
183         }
184
185         return GridDataFactory.fillDefaults().grab(grabHorizontal, vScroll).align(SWT.FILL, vAlign).hint(hHint, vScroll ? defaultSize.y : SWT.DEFAULT);
186     }
187
188     private static boolean hasMethod(Control control, String JavaDoc name, Class JavaDoc[] parameterTypes) {
189         Class JavaDoc c = control.getClass();
190         try {
191             return c.getMethod(name, parameterTypes) != null;
192         } catch (SecurityException JavaDoc e) {
193             return false;
194         } catch (NoSuchMethodException JavaDoc e) {
195             return false;
196         }
197     }
198 }
199
Popular Tags