KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > layoutdesign > LayoutRegion


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;
21
22 import java.awt.Rectangle JavaDoc;
23
24 /**
25  * Defines a rectangular area in the layout. For each dimension it holds the
26  * starting, ending, and center positions. For vertical dimension also the
27  * "baseline" position.
28  */

29
30 class LayoutRegion implements LayoutConstants {
31
32     // number of tracked points for each dimension
33
static final int[] POINT_COUNT = new int[] { 3, 4 };
34
35     // all points - used as param where no particular but all points should be used
36
static final int ALL_POINTS = Integer.MAX_VALUE;
37
38     // no point - used as param where no point should be processed
39
static final int NO_POINT = Integer.MIN_VALUE;
40
41     // unknown point position value
42
static final int UNKNOWN = Integer.MIN_VALUE;
43
44     // array of tracked positions - for each tracked point within each dimension
45
// - for HORIZONTAL dimension there are LEADING, TRAILING, CENTER points
46
// - for VERTICAL dimension there are LEADING, TRAILING, CENTER, BASELINE points
47
// (the constants can be used as indexes to the array)
48
int positions[][];
49
50     LayoutRegion() {
51         positions = new int[DIM_COUNT][];
52         positions[HORIZONTAL] = new int[] { UNKNOWN, UNKNOWN, UNKNOWN };
53         positions[VERTICAL] = new int[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN }; // including BASELINE
54
}
55
56     LayoutRegion(LayoutRegion reg) {
57         this();
58         set(reg);
59     }
60
61     boolean isSet() {
62         return isSet(HORIZONTAL) && isSet(VERTICAL);
63     }
64
65     boolean isSet(int dimension) {
66         return positions[dimension][LEADING] != UNKNOWN
67                && positions[dimension][TRAILING] != UNKNOWN;
68     }
69
70     int size(int dimension) {
71         int trail = positions[dimension][TRAILING];
72         int lead = positions[dimension][LEADING];
73         return trail != UNKNOWN && lead != UNKNOWN ? trail - lead : UNKNOWN;
74     }
75
76     /**
77      * Sets up the region based on given bounds rectangle and baseline position.
78      */

79     void set(Rectangle JavaDoc bounds, int baselinePos) {
80         int[] horiz = positions[HORIZONTAL];
81         horiz[LEADING] = bounds.x;
82         horiz[TRAILING] = bounds.x + bounds.width;
83         horiz[CENTER] = bounds.x + bounds.width / 2;
84
85         int[] vert = positions[VERTICAL];
86         vert[LEADING] = bounds.y;
87         vert[TRAILING] = bounds.y + bounds.height;
88         vert[CENTER] = bounds.y + bounds.height / 2;
89         vert[BASELINE] = baselinePos;
90     }
91
92     /**
93      * Converts the region to a rectangle.
94      * @param bounds rectangle to be set (output)
95      * @return Rectangle updated with actual position values (same instance as
96      * passed in as parameter)
97      */

98     Rectangle JavaDoc toRectangle(Rectangle JavaDoc bounds) {
99         int[] horiz = positions[HORIZONTAL];
100         bounds.x = horiz[LEADING];
101         bounds.width = horiz[TRAILING] - bounds.x;
102         int[] vert = positions[VERTICAL];
103         bounds.y = vert[LEADING];
104         bounds.height = vert[TRAILING] - bounds.y;
105         return bounds;
106     }
107
108     /**
109      * Copies all position values from another region.
110      */

111     void set(LayoutRegion reg) {
112         for (int i=0; i < DIM_COUNT; i++) {
113             set(i, reg);
114         }
115     }
116
117     /**
118      * Copies position values of given dimension from another region.
119      */

120     void set(int dimension, LayoutRegion reg) {
121         int[] pos = positions[dimension];
122         int[] setPos = reg.positions[dimension];
123         for (int j=0; j < pos.length; j++) {
124             pos[j] = setPos[j];
125         }
126     }
127
128     void set(int dimension, int leading, int trailing) {
129         int[] pos = positions[dimension];
130         if (pos[LEADING] != leading || pos[TRAILING] != trailing) {
131             pos[LEADING] = leading;
132             pos[TRAILING] = trailing;
133             pos[CENTER] = leading != UNKNOWN && trailing != UNKNOWN ?
134                           (leading + trailing) / 2 : UNKNOWN;
135             if (dimension == VERTICAL) {
136                 pos[BASELINE] = UNKNOWN; // undefined after change
137
}
138         }
139     }
140
141     /**
142      * Reverts the region to unset state - like it was just after the creation.
143      */

144     void reset() {
145         for (int i=0; i < DIM_COUNT; i++) {
146             int[] pos = positions[i];
147             for (int j=0; j < pos.length; j++)
148                 pos[j] = UNKNOWN;
149         }
150     }
151
152     /**
153      * @param points array of alignment constants (LEADING or TRAILING) defining
154      * for each dimension which point should be moved (can be null to
155      * move everything)
156      */

157     void reshape(int[] points, int[] moves) {
158         for (int i=0; i < DIM_COUNT; i++) {
159             reshape(i, (points != null ? points[i] : ALL_POINTS), moves[i]);
160         }
161     }
162
163     void reshape(int dimension, int align, int move) {
164         int[] pos = positions[dimension];
165         if (align == ALL_POINTS) { // move everything
166
for (int j=0; j < pos.length; j++) {
167                 if (pos[j] != UNKNOWN)
168                     pos[j] += move;
169             }
170         }
171         else if (align != NO_POINT) { // move only the desired point
172
assert align == LEADING || align == TRAILING;
173             if (pos[align] != UNKNOWN) {
174                 pos[align] += move;
175                 if (pos[LEADING] != UNKNOWN && pos[TRAILING] != UNKNOWN) {
176                     if (pos[LEADING] > pos[TRAILING]) { // don't allow negative size
177
pos[align] = pos[align^1];
178                     }
179                     pos[CENTER] = (pos[LEADING] + pos[TRAILING]) / 2;
180                 }
181                 if (dimension == VERTICAL && move != 0) {
182                     pos[BASELINE] = UNKNOWN; // undefined after resizing
183
}
184             }
185         }
186     }
187
188     /**
189      * Grows to bounds of given region.
190      */

191     void expand(LayoutRegion reg) {
192         for (int i=0; i < DIM_COUNT; i++) {
193             expand(reg, i);
194         }
195     }
196
197     void expand(LayoutRegion reg, int dimension) {
198         int[] pos = positions[dimension];
199         int[] exPos = reg.positions[dimension];
200         if (exPos[LEADING] != UNKNOWN
201             && (pos[LEADING] == UNKNOWN || exPos[LEADING] < pos[LEADING]))
202         {
203             pos[LEADING] = exPos[LEADING];
204         }
205         if (exPos[TRAILING] != UNKNOWN
206             && (pos[TRAILING] == UNKNOWN || exPos[TRAILING] > pos[TRAILING]))
207         {
208             pos[TRAILING] = exPos[TRAILING];
209         }
210         if (pos[LEADING] != UNKNOWN && pos[TRAILING] != UNKNOWN) {
211             pos[CENTER] = (pos[LEADING] + pos[TRAILING]) / 2;
212         }
213     }
214
215     /**
216      * @param sp1 base LayoutSpace
217      * @param sp2 compared LayoutSpace
218      * @param points array of alignment constants defining what points should
219      * be compared in each dimension (can be null if it does not matter)
220      * @param diffs output array with the position difference for each dimension
221      */

222 /* static void positionDiff(LayoutSpace sp1, LayoutSpace sp2,
223                              int[] points, int[] diffs)
224     {
225         for (int i=0; i < DIM_COUNT; i++) {
226             int[] pos1 = sp1.positions[i];
227             int[] pos2 = sp2.positions[i];
228             int align = points != null ? points[i] : LEADING;
229             if (align != NO_POINT) {
230                 if (align == ALL_POINTS) {
231                     align = LEADING;
232                 }
233                 diffs[i] = pos1[align] != UNKNOWN && pos2[align] != UNKNOWN ?
234                            pos2[align] - pos1[align] : UNKNOWN;
235             }
236         }
237     } */

238
239     static boolean isValidCoordinate(int pos) {
240         return pos > Short.MIN_VALUE && pos < Short.MAX_VALUE;
241     }
242
243     /**
244      * @param r1 base LayoutRegion
245      * @param r2 compared LayoutRegion
246      * @param dimension HORIZONTAL or VERTICAL (dimension index)
247      * @param align1 alignment constant of a point in base LayoutRegion
248      * @param align2 alignment constant of a point in compared LayoutRegion
249      * @return distance sp2 - sp1 in given dimension between given points
250      */

251     static int distance(LayoutRegion r1, LayoutRegion r2,
252                         int dimension,
253                         int align1, int align2)
254     {
255         int pos1 = r1.positions[dimension][align1];
256         int pos2 = r2.positions[dimension][align2];
257         return pos1 != UNKNOWN && pos2 != UNKNOWN ? pos2 - pos1 : UNKNOWN;
258     }
259
260     /**
261      * Goes through all points of given two regions in given dimension and finds
262      * the smallest distance (abs) between the regions. Positive value is
263      * returned if r2 has higher position.
264      * @return the smallest distance between the corresponding points of given
265      * regions in given dimension
266      */

267     static int minDistance(LayoutRegion r1, LayoutRegion r2, int dimension) {
268         int[] pos1 = r1.positions[dimension];
269         int[] pos2 = r2.positions[dimension];
270         int min = UNKNOWN;
271         int sign = 1;
272         for (int i=0; i < pos1.length; i++) {
273             if (pos1[i] != UNKNOWN && pos2[i] != UNKNOWN) {
274                 int dst = pos2[i] - pos1[i];
275                 int s;
276                 if (dst < 0) {
277                     dst = -dst;
278                     s = -1;
279                 }
280                 else s = 1;
281                 if (min == UNKNOWN || dst < min) {
282                     min = dst;
283                     sign = s;
284                 }
285             }
286         }
287         return min * sign;
288     }
289
290     /**
291      * Computes distance between two regions supposing they do not overlap.
292      * The distance is between LEADING point of one region and TRAILING of the
293      * other (or vice versa, depending on their relative position). Positive
294      * value is returned if r2 has higher position.
295      * @return the distance between two regions if they don't overlap, or 0 if
296      * they overlap
297      */

298     static int nonOverlapDistance(LayoutRegion r1, LayoutRegion r2, int dimension) {
299         int[] pos1 = r1.positions[dimension];
300         int[] pos2 = r2.positions[dimension];
301         int dst = pos2[LEADING] - pos1[TRAILING];
302         if (dst >= 0) {
303             return dst;
304         }
305         dst = pos2[TRAILING] - pos1[LEADING];
306         if (dst <= 0) {
307             return dst;
308         }
309         return 0;
310     }
311
312     /**
313      * Checks whether a point of 'contained' region (described by 'alignment')
314      * is inside the 'container' region's area in given 'dimension'.
315      * @return whether a point of a region is inside the other region
316      */

317     static boolean pointInside(LayoutRegion contained, int alignment, LayoutRegion container, int dimension) {
318         int[] pos = container.positions[dimension];
319         int point = contained.positions[dimension][alignment];
320         assert point != UNKNOWN && pos[LEADING] != UNKNOWN && pos[TRAILING] != UNKNOWN;
321         if (alignment == LEADING) {
322             return point >= pos[LEADING] && point < pos[TRAILING];
323         }
324 // if (alignment == TRAILING) {
325
return point > pos[LEADING] && point <= pos[TRAILING];
326 // }
327
}
328
329     /**
330      * @return whether the given regions overlap in given dimension
331      */

332     static boolean overlap(LayoutRegion r1, LayoutRegion r2, int dimension,
333                            int margin)
334     {
335         int[] pos1 = r1.positions[dimension];
336         int[] pos2 = r2.positions[dimension];
337         assert pos1[LEADING] != UNKNOWN && pos1[TRAILING] != UNKNOWN
338                && pos2[LEADING] != UNKNOWN && pos2[TRAILING] != UNKNOWN;
339         return pos1[TRAILING] + margin > pos2[LEADING]
340                && pos1[LEADING] - margin < pos2[TRAILING];
341     }
342
343     /**
344      * @return whether given regions occupy the same space
345      */

346     static boolean sameSpace(LayoutRegion r1, LayoutRegion r2) {
347         return sameSpace(r1, r2, HORIZONTAL) && sameSpace(r1, r2, VERTICAL);
348     }
349
350     /**
351      * @return whether given regions occupy the same space in given dimension
352      */

353     static boolean sameSpace(LayoutRegion r1, LayoutRegion r2, int dimension) {
354         return r1.positions[dimension][LEADING] == r2.positions[dimension][LEADING]
355             && r1.positions[dimension][TRAILING] == r2.positions[dimension][TRAILING];
356     }
357 }
358
Popular Tags