/Users/lyon/j4p/src/gui/layouts/PreferredSizeGridLayout.java

1    package gui.layouts; 
2     
3    import java.awt.*; 
4     
5     
6    public class PreferredSizeGridLayout 
7            extends GridLayout { 
8     
9        private BoundableInterface boundableInterface = 
10               new PreferredBoundable(); 
11    
12       public PreferredSizeGridLayout() { 
13           this(1, 0, 0, 0); 
14       } 
15    
16       /** 
17        * Creates a grid layout with the specified number of rows and 
18        * columns. All components in the layout are given equal size. 
19        * <p> 
20        * One, but not both, of <code>rows</code> and <code>cols</code> can 
21        * be zero, which means that any number of objects can be placed in a 
22        * row or in a column. 
23        * @param     rows   the rows, with the value zero meaning 
24        *                   any number of rows. 
25        * @param     cols   the columns, with the value zero meaning 
26        *                   any number of columns. 
27        */ 
28       public PreferredSizeGridLayout(int rows, int cols) { 
29           this(rows, cols, 0, 0); 
30       } 
31    
32       /** 
33        * Creates a grid layout with the specified number of rows and 
34        * columns. All components in the layout are given equal size. 
35        * <p> 
36        * In addition, the horizontal and vertical gaps are set to the 
37        * specified values. Horizontal gaps are placed at the left and 
38        * right edges, and between each of the columns. Vertical gaps are 
39        * placed at the top and bottom edges, and between each of the rows. 
40        * <p> 
41        * One, but not both, of <code>rows</code> and <code>cols</code> can 
42        * be zero, which means that any number of objects can be placed in a 
43        * row or in a column. 
44        * @param     rows   the rows, with the value zero meaning 
45        *                   any number of rows. 
46        * @param     cols   the columns, with the value zero meaning 
47        *                   any number of columns. 
48        * @param     hgap   the horizontal gap. 
49        * @param     vgap   the vertical gap. 
50        * @exception   IllegalArgumentException  if the of <code>rows</code> 
51        *                   or <code>cols</code> is invalid. 
52        */ 
53       public PreferredSizeGridLayout(int rows, int cols, int hgap, int vgap) { 
54           super(rows, cols, hgap, vgap); 
55       } 
56    
57       public Dimension preferredLayoutSize(Container parent) { 
58           synchronized (parent.getTreeLock()) { 
59               Insets insets = parent.getInsets(); 
60               int ncomponents = parent.getComponentCount(); 
61               int nrows = getRows(); 
62               int ncols = getColumns(); 
63    
64               if (nrows > 0) { 
65                   ncols = (ncomponents + nrows - 1) / nrows; 
66               } else { 
67                   nrows = (ncomponents + ncols - 1) / ncols; 
68               } 
69               int w = 0; 
70               int h = 0; 
71               for (int i = 0; i < ncomponents; i++) { 
72                   Component comp = parent.getComponent(i); 
73                   Dimension d = comp.getPreferredSize(); 
74                   if (w < d.width) { 
75                       w = d.width; 
76                   } 
77                   if (h < d.height) { 
78                       h = d.height; 
79                   } 
80               } 
81               return new Dimension( 
82                       insets.left + 
83                       insets.right + 
84                       ncols * w + 
85                       (ncols - 1) * getHgap(), 
86                       insets.top + 
87                       insets.bottom + 
88                       nrows * h + 
89                       (nrows - 1) * getVgap()); 
90           } 
91       } 
92    
93    
94       /** 
95        * Lays out the specified container using this layout. 
96        * <p> 
97        * This method reshapes the components in the specified target 
98        * container in order to satisfy the constraints of the 
99        * <code>PreferredSizeGridLayout</code> object. 
100       * <p> 
101       * The grid layout manager determines the size of individual 
102       * components by dividing the free space in the container into 
103       * equal-sized portions according to the number of rows and columns 
104       * in the layout. The container's free space equals the container's 
105       * size minus any insets and any specified horizontal or vertical 
106       * gap. All components in a grid layout are given the 
107       * Minimum of the same size or the preferred size. 
108       * 
109       * @see        java.awt.Container 
110       * @see        java.awt.Container#doLayout 
111       */ 
112      public void layoutContainer(Container parent) { 
113          synchronized (parent.getTreeLock()) { 
114              Insets insets = parent.getInsets(); 
115              int ncomponents = parent.getComponentCount(); 
116              int nrows = getRows(); 
117              int ncols = getColumns(); 
118   
119              if (ncomponents == 0) { 
120                  return; 
121              } 
122              if (nrows > 0) { 
123                  ncols = (ncomponents + nrows - 1) / nrows; 
124              } else { 
125                  nrows = (ncomponents + ncols - 1) / ncols; 
126              } 
127              int w = parent.getWidth() - (insets.left + insets.right); 
128              int h = parent.getHeight() - (insets.top + insets.bottom); 
129              w = (w - (ncols - 1) * getHgap()) / ncols; 
130              h = (h - (nrows - 1) * getVgap()) / nrows; 
131   
132              for (int c = 0, x = insets.left; c < ncols; c++, x += w + getHgap()) { 
133                  for (int r = 0, y = insets.top; r < nrows; r++, y += h + getVgap()) { 
134                      int i = r * ncols + c; 
135                      if (i < ncomponents) { 
136                          boundableInterface.setBounds(parent.getComponent(i), x, y, w, h); 
137                      } 
138                  } 
139              } 
140          } 
141      } 
142   
143      public BoundableInterface getBoundableInterface() { 
144          return boundableInterface; 
145      } 
146   
147      public void setBoundableInterface(BoundableInterface boundableInterface) { 
148          this.boundableInterface = boundableInterface; 
149      } 
150   
151   
152  } 
153