Statistics
| Revision:

root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / gui / TwoColumnLayout.java @ 15280

History | View | Annotate | Download (32 KB)

1 15280 rgaitan
/*
2
 * $Id: TwoColumnLayout.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
3
 * Copyright (C) 2002 Elmar Grom
4
 *
5
 * File :               TwoColumnLayout.java
6
 * Description :        A special layout manger designed for the UserInputPanel
7
 * Author's email :     elmar@grom.net
8
 * Author's Website :   http://www.izforge.com
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public License
12
 * as published by the Free Software Foundation; either version 2
13
 * of the License, or any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
 */
24
25
package   com.izforge.izpack.gui;
26
27
import java.awt.BasicStroke;
28
import java.awt.Color;
29
import java.awt.Component;
30
import java.awt.Container;
31
import java.awt.Dimension;
32
import java.awt.Graphics2D;
33
import java.awt.LayoutManager2;
34
import java.awt.Stroke;
35
import java.util.Vector;
36
37
/**
38
 * This class implements a layout manager that generally lays out components
39
 * in two columns.
40
 * <BR><BR>
41
 * The design goal for this layout manager was to lay out forms for data
42
 * entry, where there are several rows of entry fields with associated labels.
43
 * The goal was to have the beginning off all labels line up, as well as the
44
 * left edge of all the data entry fields. This leads to a situation where all
45
 * components are essentially laid out in two columns. The columns adjust to
46
 * accommodate components of various sizes. This means that components that
47
 * are added are laid out top to bottom, either in the left column, in the
48
 * right column or straddling both columns. In addition to this general
49
 * behavior, the following additional layout capabilities are supported:<br>
50
 * <ul>
51
 * <li>Resizable margins are provided on the left and right side.
52
 * <li>A special region is provided at the top that is only affected by the
53
 *     side margins but not by any other layout behavior.
54
 * <li>It is possible to specify the vertical positioning of the cluster of
55
 *     laid out components for the case that they do not occupy the entire
56
 *     available real estate.
57
 * <li>Individual components can be indented.
58
 * </ul>
59
 *
60
 * <b>The Layout Behavior</b>
61
 * <br><br>
62
 * The left and right margin are absolute. This means that they can not be
63
 * penetrated by components. All layout happens between the limits established
64
 * by these margins. The purpose of these margins is to ensure that components
65
 * are not laid out all the way to the edge of their container, without the
66
 * need to set matching borders for each component.
67
 * <br><br>
68
 * The title margin at the top factors only into the layout behavior if there
69
 * is a component set to be laid out in that region, otherwise it is ignored.
70
 * <br><br>
71
 * The vertical space available to each row of components depends on the space
72
 * requirements of the tallest component in that row. Both components are
73
 * placed vertically centered in their row.
74
 * <br><br>
75
 * All horizontal layout is based on the position of three vertical rules,
76
 * the left rule, the right rule and the center rule.
77
 * <br><br>
78
 * <img src="doc-files/TwoColumnLayout.gif"/>
79
 * <br><br>
80
 * The actual position of each rule depends on the alignment strategy, margin
81
 * settings and component sizes. Regardless of these factors, components
82
 * placed in the left column are <i>always</i> positioned with their left edge
83
 * aligned with the left rule. Components placed in the right column are
84
 * <i>always</i> positioned with their left edge aligned with the center rule.
85
 * If a component straddles both columns, it is <i>always</i> positioned with
86
 * the left edge aligned with the left rule, but is allowed to extend all the
87
 * way to the right rule. The only exception is a component that is specified
88
 * with an indent. In this case the component is moved to the right of the
89
 * respective rule by the indent amount.
90
 * <br><br>
91
 * The location of the rules is determined based on the alignment strategy
92
 * as follows:<br>
93
 * <ul>
94
 * <li>The right rule is always located at the edge of the right margin.
95
 * <li><b>Left Alignment:</b> The left rule is located the edge of the left
96
 *     margin. The center rule is located far enough to the right to clear
97
 *     the widest component in the left column.
98
 * <li><b>Center Alignment:</b> The center rule is located at the center of
99
 *     the panel. The left rule is located far enough to the left to make
100
 *     the widest component in the left column fit.
101
 * <li><b>Right Alignment</b> The center rule is located far enough to the
102
 *     left of the right rule to make the widest component in the right
103
 *     column fit. The left rule is located far enough to the left to make
104
 *     the widest component in the left column fit.
105
 * </ul>
106
 * All components clump together vertically and are positioned right beneath
107
 * the title margin. This is of course not a very appealing presentation.
108
 * By setting how the remaining vertical space is distributed above and below
109
 * the cluster of components the cluster can be positioned more favorably
110
 * (see the shaded area in the illustration).
111
 *
112
 * @see      com.izforge.izpack.gui.TwoColumnConstraints
113
 *
114
 * @version  0.0.1 / 11/14/02
115
 * @author   Elmar Grom
116
 */
117
public class TwoColumnLayout implements LayoutManager2
118
{
119
  public static final int    LEFT                = 0;
120
  public static final int    RIGHT               = 1;
121
  public static final int    CENTER              = 2;
122
123
  /** holds all the components and layout constraints. */
124
  private Vector [] components =
125
  {
126
    new Vector (),
127
    new Vector ()
128
  };
129
130
  /** holds the component to be placed in the title region, including layout
131
      constraints. */
132
  private TwoColumnConstraints title = null;
133
134
  /** the margin setting in % of the container's width */
135
  private int margin    = 0;
136
  /** the setting for the buffer area on top of hte comonent cluster in % of
137
      the left over height. */
138
  private int topBuffer = 0;
139
  /** the indent setting in % of the conteiner's width */
140
  private int indent    = 0;
141
  /** the gap between the two columns */
142
  private int gap       = 5;
143
144
  private int alignment = LEFT;
145
146
  private int leftRule;
147
  private int rightRule;
148
  private int centerRule;
149
  private int titleHeight;
150
151
 /**
152
  * Constructs a <code>TwoColumnLayout</code> layout manager. To add components
153
  * use the container's <code>add(comp, constraints)</code> method with a
154
  * TwoColumnConstraints object.
155
  *
156
  * @param     margin     the margin width to use on the left and right side
157
  *                       in % of the total container width. Values less than
158
  *                       0% and greater than 50% are not accepted.
159
  * @param     gap        the gap between the two columns.
160
  * @param     indent     the indent to use for components that have that
161
  *                       constraint set. This is a value in pixels.
162
  * @param     topBuffer  the percentage of left over vertical space to place
163
  *                       on top of the component cluster. Values between 0%
164
  *                       and 100% are accepted.
165
  * @param     alignment  how to align the overall layout. Legal values are
166
  *                       LEFT, CENTER, RIGHT.
167
  */
168
  public TwoColumnLayout (int margin,
169
                          int gap,
170
                          int indent,
171
                          int topBuffer,
172
                          int alignment)
173
  {
174
    this.indent     = indent;
175
    this.gap        = gap;
176
177
    if ((margin >= 0) && (margin <= 50))
178
    {
179
      this.margin     = margin;
180
    }
181
    if ((topBuffer >= 0) && (topBuffer <= 100))
182
    {
183
      this.topBuffer  = topBuffer;
184
    }
185
    if ((alignment == LEFT) || (alignment == CENTER) || (alignment == RIGHT))
186
    {
187
      this.alignment = alignment;
188
    }
189
  }
190
191
 /**
192
  * Sets the constraints for the specified component in this layout.
193
  * <code>null</code> is a legal value for a component, but not for a
194
  * constraints object.
195
  *
196
  * @param     comp         the component to be modified.
197
  * @param     constraints  the constraints to be applied.
198
  */
199
  public void addLayoutComponent (Component comp,
200
                                  Object    constraints)
201
  {
202
    if (constraints == null)
203
    {
204
      return;
205
    }
206
207
    TwoColumnConstraints component  = null;
208
    try
209
    {
210
      component = (TwoColumnConstraints)constraints;
211
      component = (TwoColumnConstraints)component.clone ();
212
    }
213
    catch (Throwable exception)
214
    {
215
      return;
216
    }
217
218
    component.component = comp;
219
220
    // ----------------------------------------------------
221
    // the title component is recorded in a separate
222
    // variable, displacing any component that might have
223
    // been previously recorded for that location.
224
    // ----------------------------------------------------
225
    if (component.position == TwoColumnConstraints.NORTH)
226
    {
227
      title = component;
228
      if (title.stretch)
229
      {
230
        title.align = LEFT;
231
      }
232
    }
233
234
    // ----------------------------------------------------
235
    // components that straddle both columns are a bit
236
    // tricky because these components are recorded in the
237
    // left column and the same row cannot contain a
238
    // component in the right column.
239
    //
240
    // If there are fewer components in the left column
241
    // than in the right one, a null is inserted at this
242
    // place in the right column. This allows the component
243
    // to use both columns. The component that previously
244
    // occupied this position and any that were placed
245
    // below will be pushed down by one row due to this
246
    // action.
247
    //
248
    // If there are the same number of components in both
249
    // columns or if there are fewer in the right column
250
    // then the component is added to the left column and
251
    // then the right column filled with null until both
252
    // contain the same number of components. this means
253
    // that any components that will now be placed in the
254
    // right column are positioned beneath this component.
255
    // Unoccupied spots higher in the right column become
256
    // inaccessible.
257
    // ----------------------------------------------------
258
    else if (component.position == TwoColumnConstraints.BOTH)
259
    {
260
      // first make sure that both columns have the same number of entries
261
      while (components [RIGHT].size () > components [LEFT].size ())
262
      {
263
        components [LEFT].add (null);
264
      }
265
266
      while (components [LEFT].size () > components [RIGHT].size ())
267
      {
268
        components [RIGHT].add (null);
269
      }
270
271
      components [LEFT].add (component);
272
      components [RIGHT].add (null);
273
    }
274
275
    // ----------------------------------------------------
276
    // WEST components are added to the left column
277
    // ----------------------------------------------------
278
    else if (component.position == TwoColumnConstraints.WEST)
279
    {
280
      components [LEFT].add (component);
281
    }
282
283
    // ----------------------------------------------------
284
    // WESTONLY components are added to the left column
285
    // the right column has to be kept free
286
    // ----------------------------------------------------
287
    else if (component.position == TwoColumnConstraints.WESTONLY)
288
    {
289
      components [LEFT].add (component);
290
291
      // fill right column to make sure nothing is placed there
292
      while (components [RIGHT].size () < components [LEFT].size ())
293
      {
294
        components [RIGHT].add (null);
295
      }
296
297
    }
298
299
    // ----------------------------------------------------
300
    // EAST components are added to the right column
301
    // ----------------------------------------------------
302
    else if (component.position == TwoColumnConstraints.EAST)
303
    {
304
      components [RIGHT].add (component);
305
    }
306
307
    // ----------------------------------------------------
308
    // EASTONLY components are added to the left column
309
    // the right column has to be kept free
310
    // ----------------------------------------------------
311
    else if (component.position == TwoColumnConstraints.EASTONLY)
312
    {
313
      components [RIGHT].add (component);
314
315
      // fill left column to make sure nothing is placed there
316
      while (components [LEFT].size () < components [RIGHT].size ())
317
      {
318
        components [LEFT].add (null);
319
      }
320
321
    }
322
323
    // ----------------------------------------------------
324
    // If the position did not match any of the above
325
    // criteria then the component is not added and
326
    // consequently will not be laid out.
327
    // ----------------------------------------------------
328
  }
329
330
 /**
331
  * Lays out the container in the specified panel.
332
  *
333
  * @param     parent   the component which needs to be laid out.
334
  */
335
  public void layoutContainer (Container parent)
336
  {
337
    positionRules (parent);
338
    positionTitle (parent);
339
    positionComponents (parent);
340
  }
341
342
 /**
343
  * Positions the three rules in preparation for layout. Sets the variables:<br>
344
  * <ul>
345
  * <li><code>leftRule</code>
346
  * <li><code>rightRule</code>
347
  * <li><code>centerRule</code>
348
  * </ul>
349
  *
350
  * @param     parent   the component which needs to be laid out.
351
  */
352
  private void positionRules (Container parent)
353
  {
354
    int margin = margin (parent);
355
356
    if (alignment == LEFT)
357
    {
358
      leftRule    = margin;
359
      centerRule  = leftRule + minimumColumnWidth (LEFT, parent) + gap;
360
      rightRule   = parent.getWidth () - margin;
361
    }
362
363
    else if (alignment == CENTER)
364
    {
365
      centerRule  = (int)(parent.getMinimumSize ().getWidth () / 2);
366
      leftRule    = centerRule - minimumColumnWidth (LEFT, parent) - gap;
367
      rightRule   = parent.getWidth () - margin;
368
    }
369
370
    else if (alignment == RIGHT)
371
    {
372
      rightRule   = parent.getWidth () - margin;
373
      centerRule  = rightRule - minimumColumnWidth (RIGHT, parent);
374
      leftRule    = centerRule - minimumColumnWidth (LEFT, parent) - gap;
375
    }
376
  }
377
378
 /**
379
  * Positions the title component and sets the variable <code>titleHeight</code>.
380
  * <b>Note:</b> this method depends on the fact that the rules are set to
381
  * their correct layout position.
382
  *
383
  * @param     parent   the component which needs to be laid out.
384
  */
385
  private void positionTitle (Container parent)
386
  {
387
    if (title != null)
388
    {
389
      Component component = title.component;
390
      int width   = (int)component.getMinimumSize ().getWidth ();
391
      titleHeight = (int)component.getMinimumSize ().getHeight ();
392
393
      if (component != null)
394
      {
395
        if (title.stretch)
396
        {
397
          width = rightRule - leftRule;
398
          component.setBounds (leftRule, 0, width, titleHeight);
399
        }
400
401
        else if (title.align == TwoColumnConstraints.LEFT)
402
        {
403
          component.setBounds (leftRule, 0, width, titleHeight);
404
        }
405
406
        else if (title.align == TwoColumnConstraints.CENTER)
407
        {
408
          int left = centerRule - (width / 2);
409
          component.setBounds (left, 0, width, titleHeight);
410
        }
411
412
        else if (title.align == TwoColumnConstraints.RIGHT)
413
        {
414
          int left = rightRule - width;
415
          component.setBounds (left, 0, width, titleHeight);
416
        }
417
      }
418
    }
419
  }
420
421
 /**
422
  * Positions all components in the container.
423
  *
424
  * @param     parent   the component which needs to be laid out.
425
  */
426
  private void positionComponents (Container parent)
427
  {
428
    int usedHeight  = titleHeight + minimumClusterHeight ();
429
    int topBuffer   = topBuffer (usedHeight, parent);
430
    int leftHeight  = 0;
431
    int rightHeight = 0;
432
433
    if (topBuffer < 0)
434
    {
435
      topBuffer = 0;
436
    }
437
438
    int y           = titleHeight + topBuffer;
439
440
    for (int i = 0; i < rows (); i++)
441
    {
442
      leftHeight  = height (i, LEFT);
443
      rightHeight = height (i, RIGHT);
444
445
      if (leftHeight > rightHeight)
446
      {
447
        int offset = (leftHeight - rightHeight) / 2;
448
449
        positionComponent (y, i, LEFT, parent);
450
        positionComponent ((y + offset), i, RIGHT, parent);
451
452
        y = y + leftHeight;
453
      }
454
      else if (leftHeight < rightHeight)
455
      {
456
        int offset = (rightHeight - leftHeight) / 2;
457
458
        positionComponent ((y + offset), i, LEFT, parent);
459
        positionComponent (y, i, RIGHT, parent);
460
461
        y = y + rightHeight;
462
      }
463
      else
464
      {
465
        positionComponent (y, i, LEFT,  parent);
466
        positionComponent (y, i, RIGHT, parent);
467
468
        y = y + leftHeight;
469
      }
470
    }
471
  }
472
473
 /**
474
  * Positiones one component as instructed. Constraints for each component,
475
  * such as <code>stretch</code>, <code>BOTH</code> and <code>indent</code>
476
  * are taken into account. In addition, empty comonents are handled properly.
477
  *
478
  * @param     y        the y location within the continer, where the
479
  *                     component should be positioned.
480
  * @param     row      the row of the component
481
  * @param     column   the column of the component
482
  * @param     parent   the container which needs to be laid out.
483
  */
484
  private void positionComponent (int       y,
485
                                  int       row,
486
                                  int       column,
487
                                  Container parent)
488
  {
489
    TwoColumnConstraints constraints = null;
490
491
    try
492
    {
493
      constraints = (TwoColumnConstraints)(components [column].elementAt (row));
494
    }
495
    catch (Throwable exception)
496
    {
497
      return;
498
    }
499
500
    int                  x           = 0;
501
502
    if (constraints != null)
503
    {
504
      Component component = constraints.component;
505
      int width  = (int)component.getPreferredSize ().getWidth ();
506
      int height = (int)component.getPreferredSize ().getHeight ();
507
508
      // --------------------------------------------------
509
      // set x to the appropriate rule. The only need to
510
      // modify this is for indent
511
      // --------------------------------------------------
512
      if (column == LEFT)
513
      {
514
        x = leftRule;
515
      }
516
      else
517
      {
518
        x = centerRule;
519
      }
520
521
      if (component != null)
522
      {
523
        // --------------------------------------------------
524
        // set the width for stretch based on BOTH, LEFT and
525
        // RIGHT positionsing
526
        // --------------------------------------------------
527
        if ((constraints.stretch) && (constraints.position == TwoColumnConstraints.BOTH))
528
        {
529
          width = rightRule - leftRule;
530
          x     = leftRule;
531
        }
532
        else if ((constraints.stretch) && (column == LEFT))
533
        {
534
          width = centerRule - leftRule;
535
        }
536
        else if ((constraints.stretch) && (column == RIGHT))
537
        {
538
          width = rightRule - centerRule;
539
        }
540
541
        // --------------------------------------------------
542
        // if we straddle both columns but are not stretching
543
        // use the preferred width as long as it is less then
544
        // the width of both columns combined. Also set the x
545
        // position to left, just to be sure.
546
        // --------------------------------------------------
547
        else if (constraints.position == TwoColumnConstraints.BOTH)
548
        {
549
          if (width > (rightRule - leftRule))
550
          {
551
            width = rightRule - leftRule;
552
          }
553
          x = leftRule;
554
        }
555
556
        // --------------------------------------------------
557
        // correct for indent if this option is set
558
        // --------------------------------------------------
559
        if (constraints.indent)
560
        {
561
          width   = width - indent;
562
          x       = x + indent;
563
        }
564
565
        component.setBounds (x, y, width, height);
566
      }
567
    }
568
  }
569
570
 /**
571
  * Returns the minimum width of the column requested.
572
  *
573
  * @param     column  the columns to measure (LEFT / RIGHT)
574
  * @param     parent  the component which needs to be laid out.
575
  *
576
  * @return    the minimum width required to fis the components in this column
577
  */
578
  private int minimumColumnWidth (int       column,
579
                                  Container parent)
580
  {
581
    Component             component   = null;
582
    TwoColumnConstraints  constraints = null;
583
    int                   width       = 0;
584
    int                   temp        = 0;
585
586
    for (int i = 0; i < components [column].size (); i++)
587
    {
588
      constraints = (TwoColumnConstraints)components [column].elementAt (i);
589
590
      if ((constraints          != null)            &&
591
          (constraints.position != TwoColumnConstraints.BOTH)   )
592
      {
593
        component = constraints.component;
594
        temp      = (int)component.getMinimumSize ().getWidth ();
595
596
        if (constraints.indent)
597
        {
598
          temp = temp + indent;
599
        }
600
601
        if (temp > width)
602
        {
603
          width = temp;
604
        }
605
      }
606
    }
607
608
    return (width);
609
  }
610
611
 /**
612
  * Retrunds the minimum width both columns together should have based on the
613
  * minimum widths of all the components that straddle both columns and the
614
  * minimum width of the title component.
615
  *
616
  * @param     parent  the component which needs to be laid out.
617
  *
618
  * @return    the minimum width required to fis the components in this column
619
  */
620
  private int minimumBothColumnsWidth (Container parent)
621
  {
622
    Component             component   = null;
623
    TwoColumnConstraints  constraints = null;
624
    int                   width       = 0;
625
    int                   temp        = 0;
626
627
    if (title != null)
628
    {
629
      component = title.component;
630
      width     = (int)component.getMinimumSize ().getWidth ();
631
    }
632
633
    for (int i = 0; i < components [LEFT].size (); i++)
634
    {
635
      constraints = (TwoColumnConstraints)components [LEFT].elementAt (i);
636
637
      if ((constraints          != null)            &&
638
          (constraints.position == TwoColumnConstraints.BOTH)   )
639
      {
640
        component = constraints.component;
641
        temp      = (int)component.getMinimumSize ().getWidth ();
642
643
        if (constraints.indent)
644
        {
645
          temp = temp + indent;
646
        }
647
648
        if (temp > width)
649
        {
650
          width = temp;
651
        }
652
      }
653
    }
654
655
    return (width);
656
  }
657
658
  private int minimumClusterHeight ()
659
  {
660
    int height    = 0;
661
662
    for (int i = 0; i < rows (); i++)
663
    {
664
      height = height + rowHeight (i);
665
    }
666
667
    return (height);
668
  }
669
670
 /**
671
  * Returns the number of rows that need to be laid out.
672
  */
673
  private int rows ()
674
  {
675
    int rows      = 0;
676
    int leftRows  = components [LEFT].size ();
677
    int rightRows = components [RIGHT].size ();
678
679
    if (leftRows > rightRows)
680
    {
681
      rows = leftRows;
682
    }
683
    else
684
    {
685
      rows = rightRows;
686
    }
687
688
    return (rows);
689
  }
690
691
 /**
692
  * Measures and returns the minimum height required to render the components
693
  * in the indicated row.
694
  *
695
  * @param     row  the index of the row to measure
696
  */
697
  private int rowHeight (int row)
698
  {
699
    int height  = 0;
700
    int height1 = height (row, LEFT);
701
    int height2 = height (row, RIGHT);
702
703
    // ----------------------------------------------------
704
    // take the higher one
705
    // ----------------------------------------------------
706
    if (height1 > height2)
707
    {
708
      height = height1;
709
    }
710
    else
711
    {
712
      height = height2;
713
    }
714
715
    return (height);
716
  }
717
718
 /**
719
  * Measures and returns the minimum height required to render the component
720
  * in the indicated row and column.
721
  *
722
  * @param     row      the index of the row to measure
723
  * @param     column   the column of the component to measure
724
  *                     (<code>LEFT</code> or <code>RIGHT</code>)
725
  */
726
  private int height (int row,
727
                      int column)
728
  {
729
    int                   height  = 0;
730
    int                   width   = 0;
731
    Component             component;
732
    TwoColumnConstraints  constraints;
733
734
    try
735
    {
736
      constraints = (TwoColumnConstraints)components [column].elementAt (row);
737
      if (constraints != null)
738
      {
739
        component = constraints.component;
740
        width     = (int)component.getMinimumSize ().getWidth ();
741
        height    = (int)component.getMinimumSize ().getHeight ();
742
743
        if (constraints.position == TwoColumnConstraints.WEST)
744
        {
745
          if (width > (centerRule - leftRule))
746
          {
747
            component.setBounds (0, 0, (centerRule - leftRule), height);
748
          }
749
        }
750
        else if (constraints.position == TwoColumnConstraints.EAST)
751
        {
752
          if (width > (rightRule - centerRule))
753
          {
754
            component.setBounds (0, 0, (rightRule - centerRule), height);
755
          }
756
        }
757
        else if (constraints.position == TwoColumnConstraints.BOTH)
758
        {
759
          if (width > (rightRule - leftRule))
760
          {
761
            component.setBounds (0, 0, (rightRule - leftRule), height);
762
          }
763
        }
764
765
        height    = (int)component.getMinimumSize ().getHeight ();
766
      }
767
    }
768
    // ----------------------------------------------------
769
    // we might get an exception if one of the vectors is
770
    // shorter, because we index out of bounds. If there
771
    // is nothing there then the height is 0, nothing
772
    // further to worry about!
773
    // ----------------------------------------------------
774
    catch (Throwable exception)
775
    {}
776
777
    return (height);
778
  }
779
780
 /**
781
  * Computes the margin value based on the container width and the margin setting.
782
  *
783
  * @param     parent  the component which needs to be laid out.
784
  */
785
  private int margin (Container parent)
786
  {
787
    int amount = (int)(((parent.getSize ().getWidth ()) * margin) / 100);
788
789
    return (amount);
790
  }
791
792
 /**
793
  * Computes the top buffer value based on the container width and the setting
794
  * for the top buffer
795
  *
796
  * @param     usedHeight the amount of the parent component's height that
797
  *            is already in use (height of the title and the combined height
798
  *            of all rows).
799
  * @param     parent     the component which needs to be laid out.
800
  */
801
  private int topBuffer (int       usedHeight,
802
                         Container parent)
803
  {
804
    int amount  = ((int)parent.getSize ().getHeight ()) - usedHeight;
805
    amount      = (int)(amount * topBuffer) / 100;
806
807
    return (amount);
808
  }
809
 /*--------------------------------------------------------------------------*/
810
 /**
811
  * Computes the indent value based on the container width and the indent setting.
812
  *
813
  * @param     parent  the component which needs to be laid out.
814
  */
815
 /*--------------------------------------------------------------------------*/
816
/*  private int indent (Container parent)
817
  {
818
    int amount = (int)(((parent.getMinimumSize ().getWidth ()) * indent) / 100);
819

820
    return (amount);
821
  }*/
822
 /**
823
  * Calculates the preferred size dimensions for the specified panel given
824
  * the components in the specified parent container.
825
  *
826
  * @param     parent   the component to be laid out
827
  */
828
  public Dimension preferredLayoutSize (Container parent)
829
  {
830
    return (minimumLayoutSize (parent));
831
  }
832
833
 /**
834
  * Calculates the minimum size dimensions for the specified panel given the
835
  * components in the specified parent container.
836
  *
837
  * @param     parent   the component to be laid out
838
  */
839
  public Dimension minimumLayoutSize (Container parent)
840
  {
841
    positionTitle (parent);
842
843
    int width   = minimumBothColumnsWidth (parent);
844
    int height  = minimumClusterHeight () + titleHeight;
845
846
    return (new Dimension (width, height));
847
  }
848
849
 /**
850
  * Calculates the maximum size dimensions for the specified panel given the
851
  * components in the specified parent container.
852
  *
853
  * @param     parent   the component to be laid out
854
  */
855
  public Dimension maximumLayoutSize (Container parent)
856
  {
857
    return (minimumLayoutSize (parent));
858
  }
859
860
 /**
861
  * Returns the alignment along the x axis. This specifies how the component
862
  * would like to be aligned relative to other components. The value should
863
  * be a number between 0 and 1 where 0 represents alignment along the origin,
864
  * 1 is aligned the furthest away from the origin, 0.5 is centered, etc.
865
  *
866
  * @param     parent   the component to be laid out
867
  */
868
  public float getLayoutAlignmentX (Container parent)
869
  {
870
    return (0);
871
  }
872
873
 /**
874
  * Returns the alignment along the y axis. This specifies how the component
875
  * would like to be aligned relative to other components. The value should
876
  * be a number between 0 and 1 where 0 represents alignment along the origin,
877
  * 1 is aligned the furthest away from the origin, 0.5 is centered, etc.
878
  *
879
  * @param     parent   the component to be laid out
880
  */
881
  public float getLayoutAlignmentY (Container parent)
882
  {
883
    return (0);
884
  }
885
886
 /**
887
  * Invalidates the layout, indicating that if the layout manager has cached
888
  * information it should be discarded.
889
  *
890
  * @param     parent   the component to be laid out
891
  */
892
  public void invalidateLayout (Container parent)
893
  {
894
    leftRule    = 0;
895
    rightRule   = 0;
896
    centerRule  = 0;
897
    titleHeight = 0;
898
  }
899
900
 /**
901
  * Adds the specified component with the specified name to the layout. This
902
  * version is not supported, use <code>addLayoutComponent</code> with layout
903
  * contsraints.
904
  *
905
  * @param     name   the component name
906
  * @param     comp   the component to be added
907
  */
908
  public void addLayoutComponent (String    name,
909
                                  Component comp)
910
  { }
911
912
 /**
913
  * This functionality is not supported
914
  *
915
  * @param     comp   the component to be removed
916
  */
917
  public void removeLayoutComponent (Component comp)
918
  { }
919
920
 /**
921
  * This method is provided for conveninence of debugging layout problems. It
922
  * renders the three rules and the limit of the title marign visible after
923
  * these positions have been computed. In addition, the indent locations are
924
  * shown as dashed lines. To use this functionality do the following:<br><br>
925
  * <ul>
926
  * <li>in the container using this layout manager override the
927
  *     <code>paint()</code> method.
928
  * <li>in that method, first call <code>super.paint()</code>
929
  * <li>then call this method
930
  * </ul><br>
931
  * <b>Note:</b> cast the graphics object received in the <code>paint()</code>
932
  * method to <code>Graphics2D</code> when making the call.<br><br>
933
  *
934
  * @param     graphics   the graphics context used for drawing.
935
  * @param     color      the color to use for rendering the layout grid
936
  */
937
  public void showRules (Graphics2D graphics,
938
                         Color      color)
939
  {
940
    int      height       = graphics.getClipBounds ().height;
941
942
    Stroke  currentStroke = graphics.getStroke ();
943
    Color   currentColor  = graphics.getColor ();
944
945
    Stroke stroke         = new BasicStroke (1,
946
                                             BasicStroke.CAP_BUTT,
947
                                             BasicStroke.JOIN_BEVEL,
948
                                             1.5f,
949
                                             new float [] {10, 5},
950
                                             5);
951
    graphics.setColor (color);
952
953
    graphics.drawLine (leftRule,    0,            leftRule,     height);
954
    graphics.drawLine (centerRule,  titleHeight,  centerRule,   height);
955
    graphics.drawLine (rightRule,   0,            rightRule,    height);
956
    graphics.drawLine (leftRule,    titleHeight,  rightRule,    titleHeight);
957
958
    graphics.setStroke (stroke);
959
    graphics.drawLine  ((leftRule + indent),   titleHeight, (leftRule + indent), height);
960
    graphics.drawLine  ((centerRule + indent), titleHeight, (centerRule + indent), height);
961
962
    graphics.setStroke (currentStroke);
963
    graphics.setColor (currentColor);
964
  }
965
}
966
/*---------------------------------------------------------------------------*/