1 /*
2  * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.tools.jconsole;
27 
28 import java.awt.*;
29 
30 import javax.swing.*;
31 
32 @SuppressWarnings("serial")
33 public class VariableGridLayout extends GridLayout {
34 
35     private boolean fillRows, fillColumns;
36 
VariableGridLayout(int rows, int cols, int hgap, int vgap, boolean fillRows, boolean fillColumns)37     public VariableGridLayout(int rows, int cols,
38                               int hgap, int vgap,
39                               boolean fillRows, boolean fillColumns) {
40         super(rows, cols, hgap, vgap);
41 
42         this.fillRows    = fillRows;
43         this.fillColumns = fillColumns;
44     }
45 
setFillRow(JComponent c, boolean b)46     public void setFillRow(JComponent c, boolean b) {
47         c.putClientProperty("VariableGridLayout.fillRow", b);
48     }
49 
setFillColumn(JComponent c, boolean b)50     public void setFillColumn(JComponent c, boolean b) {
51         c.putClientProperty("VariableGridLayout.fillColumn", b);
52     }
53 
getFillRow(JComponent c)54     public boolean getFillRow(JComponent c) {
55         Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillRow");
56         return (b != null) ? b : fillRows;
57     }
58 
getFillColumn(JComponent c)59     public boolean getFillColumn(JComponent c) {
60         Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillColumn");
61         return (b != null) ? b : fillColumns;
62     }
63 
layoutContainer(Container parent)64     public void layoutContainer(Container parent) {
65         Insets insets = parent.getInsets();
66         int ncomponents = parent.getComponentCount();
67         int nrows = getRows();
68         int ncols = getColumns();
69         int hgap =  getHgap();
70         int vgap =  getVgap();
71 
72         if (nrows > 0) {
73             ncols = (ncomponents + nrows - 1) / nrows;
74         } else {
75             nrows = (ncomponents + ncols - 1) / ncols;
76         }
77 
78         // Set heights
79         int x;
80         int y;
81         int nFills = 0;
82         boolean[] fills = new boolean[nrows];
83         int lastFillRow = -1;
84         int nComps = parent.getComponentCount();
85 
86         y = insets.top;
87         for (int row = 0; row < nrows; row++) {
88             // Find largest minimum height for this row
89             int h = 0;
90             for (int col = 0; col < ncols; col++) {
91                 if (row * ncols + col < nComps) {
92                     Component c = parent.getComponent(row * ncols + col);
93                     h = Math.max(h, c.getMinimumSize().height);
94                 }
95             }
96             // Set heights for this row
97             x = insets.left;
98             for (int col = 0; col < ncols; col++) {
99                 if (row * ncols + col < nComps) {
100                     JComponent c = (JComponent)parent.getComponent(row * ncols + col);
101                     int w = c.getWidth();
102                     c.setBounds(x, y, w, h);
103                     x += w + hgap;
104                     if (col == 0 && getFillRow(c)) {
105                         fills[row] = true;
106                     }
107                 }
108             }
109             y += h + vgap;
110             if (fills[row]) {
111                 nFills++;
112                 lastFillRow = row;
113             }
114         }
115 
116         // Fill heights
117         if (nFills > 0 && y < parent.getHeight()) {
118             // How much height to add
119             int hAdd = (parent.getHeight() - y) / nFills;
120             int hAdded = 0;
121             for (int row = 0; row < nrows; row++) {
122                 if (fills[row]) {
123                     if (row == lastFillRow) {
124                         // Compensate for rounding error
125                         hAdd = parent.getHeight() - (y+hAdded);
126                     }
127                     for (int col = 0; col < ncols; col++) {
128                         if (row * ncols + col < nComps) {
129                             Component c = parent.getComponent(row * ncols + col);
130                             Rectangle b = c.getBounds();
131                             c.setBounds(b.x, b.y + hAdded, b.width, b.height + hAdd);
132                         }
133                     }
134                     hAdded += hAdd;
135                 }
136             }
137         }
138 
139         // Set widths
140         nFills = 0;
141         fills = new boolean[ncols];
142         int lastFillCol = -1;
143 
144         x = insets.left;
145         for (int col = 0; col < ncols; col++) {
146             // Find largest minimum width for this column
147             int w = 0;
148             for (int row = 0; row < nrows; row++) {
149                 if (row * ncols + col < nComps) {
150                     Component c = parent.getComponent(row * ncols + col);
151                     w = Math.max(w, c.getMinimumSize().width);
152                 }
153             }
154             // Set widths for this column
155             y = insets.top;
156             for (int row = 0; row < nrows; row++) {
157                 if (row * ncols + col < nComps) {
158                     JComponent c = (JComponent)parent.getComponent(row * ncols + col);
159                     int h = c.getHeight();
160                     c.setBounds(x, y, w, h);
161                     y += h + vgap;
162                     if (row == 0 && getFillColumn(c)) {
163                         fills[col] = true;
164                     }
165                 }
166             }
167             x += w + hgap;
168             if (fills[col]) {
169                 nFills++;
170                 lastFillCol = col;
171             }
172         }
173 
174         // Fill widths
175         if (nFills > 0 && x < parent.getWidth()) {
176             // How much width to add
177             int wAdd = (parent.getWidth() - x) / nFills;
178             int wAdded = 0;
179             for (int col = 0; col < ncols; col++) {
180                 if (fills[col]) {
181                     if (col == lastFillCol) {
182                         wAdd = parent.getWidth() - (x+wAdded);
183                     }
184                     for (int row = 0; row < nrows; row++) {
185                         if (row * ncols + col < nComps) {
186                             Component c = parent.getComponent(row * ncols + col);
187                             Rectangle b = c.getBounds();
188                             c.setBounds(b.x + wAdded, b.y, b.width + wAdd, b.height);
189                         }
190                     }
191                     wAdded += wAdd;
192                 }
193             }
194         }
195     }
196 
preferredLayoutSize(Container parent)197     public Dimension preferredLayoutSize(Container parent) {
198         Insets insets = parent.getInsets();
199         int ncomponents = parent.getComponentCount();
200         int nrows = getRows();
201         int ncols = getColumns();
202         int hgap =  getHgap();
203         int vgap =  getVgap();
204 
205         if (nrows > 0) {
206             ncols = (ncomponents + nrows - 1) / nrows;
207         } else {
208             nrows = (ncomponents + ncols - 1) / ncols;
209         }
210 
211         int nComps = parent.getComponentCount();
212 
213         int y = insets.top;
214         for (int row = 0; row < nrows; row++) {
215             int h = 0;
216             for (int col = 0; col < ncols; col++) {
217                 if (row * ncols + col < nComps) {
218                     Component c = parent.getComponent(row * ncols + col);
219                     h = Math.max(h, c.getMinimumSize().height);
220                 }
221             }
222             y += h + vgap;
223         }
224 
225         int x = insets.left;
226         for (int col = 0; col < ncols; col++) {
227             int w = 0;
228             for (int row = 0; row < nrows; row++) {
229                 if (row * ncols + col < nComps) {
230                     Component c = parent.getComponent(row * ncols + col);
231                     w = Math.max(w, c.getMinimumSize().width);
232                 }
233             }
234             x += w + hgap;
235         }
236         return new Dimension(x, y);
237     }
238 }
239