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