1:
42:
43: package ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51: import ;
52: import ;
53: import ;
54:
55:
58: public class FlowArrangement implements Arrangement, Serializable {
59:
60:
61: private static final long serialVersionUID = 4543632485478613800L;
62:
63:
64: private HorizontalAlignment horizontalAlignment;
65:
66:
67: private VerticalAlignment verticalAlignment;
68:
69:
70: private double horizontalGap;
71:
72:
73: private double verticalGap;
74:
75:
78: public FlowArrangement() {
79: this(HorizontalAlignment.CENTER, VerticalAlignment.CENTER, 2.0, 2.0);
80: }
81:
82:
90: public FlowArrangement(HorizontalAlignment hAlign, VerticalAlignment vAlign,
91: double hGap, double vGap) {
92: this.horizontalAlignment = hAlign;
93: this.verticalAlignment = vAlign;
94: this.horizontalGap = hGap;
95: this.verticalGap = vGap;
96: }
97:
98:
106: public void add(Block block, Object key) {
107:
108:
109: }
110:
111:
123: public Size2D arrange(BlockContainer container, Graphics2D g2,
124: RectangleConstraint constraint) {
125:
126: LengthConstraintType w = constraint.getWidthConstraintType();
127: LengthConstraintType h = constraint.getHeightConstraintType();
128: if (w == LengthConstraintType.NONE) {
129: if (h == LengthConstraintType.NONE) {
130: return arrangeNN(container, g2);
131: }
132: else if (h == LengthConstraintType.FIXED) {
133: return arrangeNF(container, g2, constraint);
134: }
135: else if (h == LengthConstraintType.RANGE) {
136: throw new RuntimeException("Not implemented.");
137: }
138: }
139: else if (w == LengthConstraintType.FIXED) {
140: if (h == LengthConstraintType.NONE) {
141: return arrangeFN(container, g2, constraint);
142: }
143: else if (h == LengthConstraintType.FIXED) {
144: return arrangeFF(container, g2, constraint);
145: }
146: else if (h == LengthConstraintType.RANGE) {
147: return arrangeFR(container, g2, constraint);
148: }
149: }
150: else if (w == LengthConstraintType.RANGE) {
151: if (h == LengthConstraintType.NONE) {
152: return arrangeRN(container, g2, constraint);
153: }
154: else if (h == LengthConstraintType.FIXED) {
155: return arrangeRF(container, g2, constraint);
156: }
157: else if (h == LengthConstraintType.RANGE) {
158: return arrangeRR(container, g2, constraint);
159: }
160: }
161: throw new RuntimeException("Unrecognised constraint type.");
162:
163: }
164:
165:
175: protected Size2D arrangeFN(BlockContainer container, Graphics2D g2,
176: RectangleConstraint constraint) {
177:
178: List blocks = container.getBlocks();
179: double width = constraint.getWidth();
180:
181: double x = 0.0;
182: double y = 0.0;
183: double maxHeight = 0.0;
184: List itemsInRow = new ArrayList();
185: for (int i = 0; i < blocks.size(); i++) {
186: Block block = (Block) blocks.get(i);
187: Size2D size = block.arrange(g2, RectangleConstraint.NONE);
188: if (x + size.width <= width) {
189: itemsInRow.add(block);
190: block.setBounds(
191: new Rectangle2D.Double(x, y, size.width, size.height)
192: );
193: x = x + size.width + this.horizontalGap;
194: maxHeight = Math.max(maxHeight, size.height);
195: }
196: else {
197: if (itemsInRow.isEmpty()) {
198:
199: block.setBounds(
200: new Rectangle2D.Double(
201: x, y, Math.min(size.width, width - x), size.height
202: )
203: );
204: x = 0.0;
205: y = y + size.height + this.verticalGap;
206: }
207: else {
208:
209: itemsInRow.clear();
210: x = 0.0;
211: y = y + maxHeight + this.verticalGap;
212: maxHeight = size.height;
213: block.setBounds(
214: new Rectangle2D.Double(
215: x, y, Math.min(size.width, width), size.height
216: )
217: );
218: x = size.width + this.horizontalGap;
219: itemsInRow.add(block);
220: }
221: }
222: }
223: return new Size2D(constraint.getWidth(), y + maxHeight);
224: }
225:
226:
236: protected Size2D arrangeFR(BlockContainer container, Graphics2D g2,
237: RectangleConstraint constraint) {
238:
239: Size2D s = arrangeFN(container, g2, constraint);
240: if (constraint.getHeightRange().contains(s.height)) {
241: return s;
242: }
243: else {
244: RectangleConstraint c = constraint.toFixedHeight(
245: constraint.getHeightRange().constrain(s.getHeight())
246: );
247: return arrangeFF(container, g2, c);
248: }
249: }
250:
251:
261: protected Size2D arrangeFF(BlockContainer container, Graphics2D g2,
262: RectangleConstraint constraint) {
263:
264:
265: return arrangeFN(container, g2, constraint);
266: }
267:
268:
278: protected Size2D arrangeRR(BlockContainer container, Graphics2D g2,
279: RectangleConstraint constraint) {
280:
281:
282:
283: Size2D s1 = arrangeNN(container, g2);
284: if (constraint.getWidthRange().contains(s1.width)) {
285: return s1;
286: }
287: else {
288: RectangleConstraint c = constraint.toFixedWidth(
289: constraint.getWidthRange().getUpperBound()
290: );
291: return arrangeFR(container, g2, c);
292: }
293: }
294:
295:
305: protected Size2D arrangeRF(BlockContainer container, Graphics2D g2,
306: RectangleConstraint constraint) {
307:
308: Size2D s = arrangeNF(container, g2, constraint);
309: if (constraint.getWidthRange().contains(s.width)) {
310: return s;
311: }
312: else {
313: RectangleConstraint c = constraint.toFixedWidth(
314: constraint.getWidthRange().constrain(s.getWidth())
315: );
316: return arrangeFF(container, g2, c);
317: }
318: }
319:
320:
330: protected Size2D arrangeRN(BlockContainer container, Graphics2D g2,
331: RectangleConstraint constraint) {
332:
333:
334: Size2D s1 = arrangeNN(container, g2);
335: if (constraint.getWidthRange().contains(s1.width)) {
336: return s1;
337: }
338: else {
339: RectangleConstraint c = constraint.toFixedWidth(
340: constraint.getWidthRange().getUpperBound()
341: );
342: return arrangeFN(container, g2, c);
343: }
344: }
345:
346:
355: protected Size2D arrangeNN(BlockContainer container, Graphics2D g2) {
356: double x = 0.0;
357: double width = 0.0;
358: double maxHeight = 0.0;
359: List blocks = container.getBlocks();
360: int blockCount = blocks.size();
361: if (blockCount > 0) {
362: Size2D[] sizes = new Size2D[blocks.size()];
363: for (int i = 0; i < blocks.size(); i++) {
364: Block block = (Block) blocks.get(i);
365: sizes[i] = block.arrange(g2, RectangleConstraint.NONE);
366: width = width + sizes[i].getWidth();
367: maxHeight = Math.max(sizes[i].height, maxHeight);
368: block.setBounds(
369: new Rectangle2D.Double(
370: x, 0.0, sizes[i].width, sizes[i].height
371: )
372: );
373: x = x + sizes[i].width + this.horizontalGap;
374: }
375: if (blockCount > 1) {
376: width = width + this.horizontalGap * (blockCount - 1);
377: }
378: if (this.verticalAlignment != VerticalAlignment.TOP) {
379: for (int i = 0; i < blocks.size(); i++) {
380:
381: if (this.verticalAlignment == VerticalAlignment.CENTER) {
382:
383: }
384: else if (this.verticalAlignment
385: == VerticalAlignment.BOTTOM) {
386:
387: }
388: }
389: }
390: }
391: return new Size2D(width, maxHeight);
392: }
393:
394:
404: protected Size2D arrangeNF(BlockContainer container, Graphics2D g2,
405: RectangleConstraint constraint) {
406:
407: return arrangeNN(container, g2);
408: }
409:
410:
413: public void clear() {
414:
415: }
416:
417:
424: public boolean equals(Object obj) {
425: if (obj == this) {
426: return true;
427: }
428: if (!(obj instanceof FlowArrangement)) {
429: return false;
430: }
431: FlowArrangement that = (FlowArrangement) obj;
432: if (this.horizontalAlignment != that.horizontalAlignment) {
433: return false;
434: }
435: if (this.verticalAlignment != that.verticalAlignment) {
436: return false;
437: }
438: if (this.horizontalGap != that.horizontalGap) {
439: return false;
440: }
441: if (this.verticalGap != that.verticalGap) {
442: return false;
443: }
444: return true;
445: }
446:
447: }