001: /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the Hypersonic SQL Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: *
030: * This software consists of voluntary contributions made by many individuals
031: * on behalf of the Hypersonic SQL Group.
032: *
033: *
034: * For work added by the HSQL Development Group:
035: *
036: * Copyright (c) 2001-2005, The HSQL Development Group
037: * All rights reserved.
038: *
039: * Redistribution and use in source and binary forms, with or without
040: * modification, are permitted provided that the following conditions are met:
041: *
042: * Redistributions of source code must retain the above copyright notice, this
043: * list of conditions and the following disclaimer.
044: *
045: * Redistributions in binary form must reproduce the above copyright notice,
046: * this list of conditions and the following disclaimer in the documentation
047: * and/or other materials provided with the distribution.
048: *
049: * Neither the name of the HSQL Development Group nor the names of its
050: * contributors may be used to endorse or promote products derived from this
051: * software without specific prior written permission.
052: *
053: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
054: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
055: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
056: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
057: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
058: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
059: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
060: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
061: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
062: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
063: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
064: */
065:
066: package org.hsqldb.util;
067:
068: import java.util.Vector;
069: import java.awt.Component;
070:
071: import javax.swing.JTable;
072: import javax.swing.event.TableModelEvent;
073: import javax.swing.table.AbstractTableModel;
074: import javax.swing.table.TableCellRenderer;
075: import javax.swing.table.TableColumn;
076: import javax.swing.table.TableModel;
077:
078: // sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
079: // deccles@users 20040412 - patch 933671 - various bug fixes
080:
081: /** Simple table model to represent a grid of tuples.
082: *
083: * New class based on Hypersonic SQL original
084: *
085: * @author dmarshall@users
086: * @version 1.7.2
087: * @since 1.7.0
088: */
089: class GridSwing extends AbstractTableModel {
090:
091: JTable jtable = null;
092: Object[] headers;
093: Vector rows;
094:
095: /**
096: * Default constructor.
097: */
098: public GridSwing() {
099:
100: super ();
101:
102: headers = new Object[0]; // initially empty
103: rows = new Vector(); // initially empty
104: }
105:
106: /**
107: * Get the name for the specified column.
108: */
109: public String getColumnName(int i) {
110: return headers[i].toString();
111: }
112:
113: public Class getColumnClass(int i) {
114:
115: if (rows.size() > 0) {
116: Object o = getValueAt(0, i);
117:
118: if (o != null) {
119: if ((o instanceof java.sql.Timestamp)
120: || (o instanceof java.sql.Time)) {
121: // This is a workaround for JTable's lack of a default
122: // renderer that displays times.
123: // Without this workaround, Timestamps (and similar
124: // classes) will be displayed as dates without times,
125: // since JTable will match these classes to their
126: // java.util.Date superclass.
127: return Object.class; // renderer will draw .toString().
128: }
129: return o.getClass();
130: }
131: }
132:
133: return super .getColumnClass(i);
134: }
135:
136: /**
137: * Get the number of columns.
138: */
139: public int getColumnCount() {
140: return headers.length;
141: }
142:
143: /**
144: * Get the number of rows currently in the table.
145: */
146: public int getRowCount() {
147: return rows.size();
148: }
149:
150: /**
151: * Get the current column headings.
152: */
153: public Object[] getHead() {
154: return headers;
155: }
156:
157: /**
158: * Get the current table data.
159: * Each row is represented as a <code>String[]</code>
160: * with a single non-null value in the 0-relative
161: * column position.
162: * <p>The first row is at offset 0, the nth row at offset n etc.
163: */
164: public Vector getData() {
165: return rows;
166: }
167:
168: /**
169: * Get the object at the specified cell location.
170: */
171: public Object getValueAt(int row, int col) {
172:
173: if (row >= rows.size()) {
174: return null;
175: }
176:
177: Object[] colArray = (Object[]) rows.elementAt(row);
178:
179: if (col >= colArray.length) {
180: return null;
181: }
182:
183: return colArray[col];
184: }
185:
186: /**
187: * Set the name of the column headings.
188: */
189: public void setHead(Object[] h) {
190:
191: headers = new Object[h.length];
192:
193: // System.arraycopy(h, 0, headers, 0, h.length);
194: for (int i = 0; i < h.length; i++) {
195: headers[i] = h[i];
196: }
197: }
198:
199: /**
200: * Append a tuple to the end of the table.
201: */
202: public void addRow(Object[] r) {
203:
204: Object[] row = new Object[r.length];
205:
206: // System.arraycopy(r, 0, row, 0, r.length);
207: for (int i = 0; i < r.length; i++) {
208: row[i] = r[i];
209:
210: if (row[i] == null) {
211:
212: // row[i] = "(null)";
213: }
214: }
215:
216: rows.addElement(row);
217: }
218:
219: /**
220: * Remove data from all cells in the table (without
221: * affecting the current headings).
222: */
223: public void clear() {
224: rows.removeAllElements();
225: }
226:
227: public void setJTable(JTable table) {
228: jtable = table;
229: }
230:
231: public void fireTableChanged(TableModelEvent e) {
232: super .fireTableChanged(e);
233: autoSizeTableColumns(jtable);
234: }
235:
236: public static void autoSizeTableColumns(JTable table) {
237:
238: TableModel model = table.getModel();
239: TableColumn column = null;
240: Component comp = null;
241: int headerWidth = 0;
242: int maxCellWidth = Integer.MIN_VALUE;
243: int cellWidth = 0;
244: TableCellRenderer headerRenderer = table.getTableHeader()
245: .getDefaultRenderer();
246:
247: for (int i = 0; i < table.getColumnCount(); i++) {
248: column = table.getColumnModel().getColumn(i);
249: comp = headerRenderer.getTableCellRendererComponent(table,
250: column.getHeaderValue(), false, false, 0, 0);
251: headerWidth = comp.getPreferredSize().width + 10;
252: maxCellWidth = Integer.MIN_VALUE;
253:
254: for (int j = 0; j < Math.min(model.getRowCount(), 30); j++) {
255: TableCellRenderer r = table.getCellRenderer(j, i);
256:
257: comp = r.getTableCellRendererComponent(table, model
258: .getValueAt(j, i), false, false, j, i);
259: cellWidth = comp.getPreferredSize().width;
260:
261: if (cellWidth >= maxCellWidth) {
262: maxCellWidth = cellWidth;
263: }
264: }
265:
266: column.setPreferredWidth(Math
267: .max(headerWidth, maxCellWidth) + 10);
268: }
269: }
270: }
|