Source code: novaworx/gui/TablePanel.java
1 /*
2 Novaworx Development Environment
3 Copyright (C) 2000-2003 Mark Soderquist
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to:
17
18 Free Software Foundation, Inc.
19 59 Temple Place, Suite 330
20 Boston, MA 02111-1307 USA
21 */
22
23 package novaworx.gui;
24
25 import java.awt.*;
26 import javax.swing.*;
27 import javax.swing.border.EmptyBorder;
28
29 // Remove following line when class is working.
30 import cosmoworx.log.*;
31
32 /**
33 <p>The <code>TablePanel</code> container that will layout components
34 in a rectangular grid similar to HTML tables.</p>
35
36 <p>For example, the following is an panel that lays out six buttons:</p>
37
38 <blockquote><pre>
39 import java.awt.*;
40
41 public class ButtonGrid extends TablePanel {
42 public TablePanel() {
43 add( new Button("1") );
44 add( new Button("2") );
45 row();
46 colspan( 2 );
47 add( new Button("3") );
48 row();
49 rowspan( 2 );
50 add( new Button("4") );
51 add( new Button("5") );
52 row();
53 add( new Button("6") );
54 done();
55 }
56 }
57 </pre></blockquote><p>
58
59 @author Mark Soderquist
60 @version 1.0
61 @see java.awt.GridBagLayout
62 */
63
64
65 public class TablePanel extends JPanel implements Scrollable {
66
67 /**
68 The GridBag for this panel.
69 */
70 private GridBagLayout moGridBag;
71
72 /**
73 The GridBagConstraints for this panel.
74 */
75 private GridBagConstraints moConstraints;
76
77 /**
78 The previous component that was added via the add() method.
79 */
80 private Component moPreviousComponent;
81
82 private int miSpacing;
83
84 private int miPadding;
85
86 private int miColspan;
87
88 private int miRowspan;
89
90 private int miPreviousColspan;
91
92 private int miPreviousRowspan;
93
94 private int miWidth;
95
96 private int miHeight;
97
98 private int miPreviousWidth;
99
100 private int miPreviousHeight;
101
102 private int miColCount;
103
104 private int miRowHeight;
105
106 private int miTotalCols;
107
108 private int miTotalRows;
109
110 /**
111 Construct a <code>TableGridLayout</code>.
112 */
113 public TablePanel() {
114 moGridBag = new GridBagLayout();
115 super.setLayout( moGridBag );
116 moConstraints = new GridBagConstraints();
117 moConstraints.fill = GridBagConstraints.HORIZONTAL;
118
119 miWidth = 1;
120 miHeight = 1;
121 miColspan = 1;
122 miRowspan = 1;
123
124 miRowHeight = 1;
125 }
126
127 /**
128 Set the border.
129 */
130 public void setBorderSize( int aiBorder ) {
131 setBorder( new EmptyBorder( aiBorder, aiBorder, aiBorder, aiBorder ) );
132 }
133
134 /**
135 Set the border.
136 */
137 public void setBorderSize( int aiTop, int aiLeft, int aiBottom, int aiRight ) {
138 setBorder( new EmptyBorder( aiTop, aiLeft, aiBottom, aiRight ) );
139 }
140
141 /**
142 Set the cell padding.
143 */
144 public void setCellPadding( int aiPadding ) {
145 miPadding = aiPadding;
146 }
147
148 /**
149 Set the cell spacing.
150 */
151 public void setCellSpacing( int aiSpacing ) {
152 miSpacing = aiSpacing;
153 }
154
155 /**
156 Set the width for the next component to be added.
157 */
158 public void width( int aiWidth ) {
159 miWidth = aiWidth;
160 }
161
162 /**
163 Set the height for the next component to be added.
164 */
165 public void height( int aiHeight ) {
166 miHeight = aiHeight;
167 }
168
169 /**
170 Set the column span for the next component added.
171 */
172 public void colspan( int aiSpan ) {
173 miColspan = aiSpan;
174 }
175
176 /**
177 Set the row span for the next component added.
178 */
179 public void rowspan( int aiSpan ) {
180 miRowspan = aiSpan;
181 }
182
183 /**
184 Finish a row in the grid and start a new one.
185 */
186 public void row() {
187 if( moPreviousComponent != null ) {
188 miPreviousColspan = GridBagConstraints.REMAINDER;
189 }
190 miTotalRows += Math.max( 1, miRowHeight );
191 miTotalCols = Math.max( miTotalCols, miColCount );
192 miRowHeight = 1;
193 miColCount = 0;
194 }
195
196 /**
197 All the components are added.
198 */
199 public void done() {
200 miPreviousColspan = GridBagConstraints.REMAINDER;
201 addPrevious();
202 miTotalRows += Math.max( 1, miRowHeight );
203 miTotalCols = Math.max( miTotalCols, miColCount );
204 //Log.write( "Table size: " + miTotalCols + "x" + miTotalRows );
205 }
206
207 /**
208 Override the add method in <code>Container</code>. The component
209 will not actually be added until the next component is added or
210 the <code>row()</code> or <code>done()</code> method is called.
211 This allows the table to be laid out correctly.
212 */
213 public Component add( Component aoComponent ) {
214 if( aoComponent == null ) {
215 throw new IllegalArgumentException( "Component cannot be null." );
216 }
217
218 addPrevious();
219
220 // Store this component.
221 moPreviousComponent = aoComponent;
222 miPreviousWidth = miWidth;
223 miPreviousHeight = miHeight;
224 miPreviousColspan = miColspan;
225 miPreviousRowspan = miRowspan;
226
227 if( moConstraints.gridwidth != GridBagConstraints.REMAINDER ) {
228 miColCount += Math.max( 1, moConstraints.gridwidth );
229 } else {
230 miColCount++;
231 }
232
233 // Reset the constraints.
234 miWidth = 1;
235 miHeight = 1;
236 miColspan = 1;
237 miRowspan = 1;
238
239 return aoComponent;
240 }
241
242 /**
243 Actually add the previous component.
244 */
245 private void addPrevious() {
246 if( moPreviousComponent == null ) return;
247 moConstraints.weightx = miPreviousWidth;
248 moConstraints.weighty = miPreviousHeight;
249 moConstraints.gridwidth = miPreviousColspan;
250 moConstraints.gridheight = miPreviousRowspan;
251 moConstraints.insets = new Insets( miSpacing, miSpacing, miSpacing, miSpacing);
252 moConstraints.ipadx = miPadding;
253 moConstraints.ipady = miPadding;
254 miRowHeight = Math.max( miRowHeight, moConstraints.gridheight );
255 moGridBag.setConstraints( moPreviousComponent, moConstraints );
256 super.add( moPreviousComponent );
257 }
258
259 /**
260 Can not change the layout of this component.
261 */
262 public void setLayout( LayoutManager aoLayout ) {
263 //
264 }
265
266 /**
267 Get the number of rows in the table.
268 */
269 public int getRowCount() {
270 return miTotalRows;
271 }
272
273 /**
274 Get the number of columns in the table.
275 */
276 public int getColumnCount() {
277 return miTotalCols;
278 }
279
280 /**
281 Part of the <code>Scrollable</code> interface.
282 */
283 public Dimension getPreferredScrollableViewportSize() {
284 return getPreferredSize();
285 }
286
287 /**
288 Part of the <code>Scrollable</code> interface.
289 */
290 public int getScrollableUnitIncrement( Rectangle aoArea, int aiOrientation, int aiDirection ) {
291 return getPreferredSize().height / miTotalRows;
292 }
293
294 /**
295 Part of the <code>Scrollable</code> interface.
296 */
297 public boolean getScrollableTracksViewportWidth() {
298 return true;
299 }
300
301 /**
302 Part of the <code>Scrollable</code> interface.
303 */
304 public boolean getScrollableTracksViewportHeight() {
305 return false;
306 }
307
308 /**
309 Part of the <code>Scrollable</code> interface.
310 */
311 public int getScrollableBlockIncrement( Rectangle aoArea, int aiOrientation, int aiDirection) {
312 return aoArea.getSize().height;
313 }
314
315 }