KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > minigrid > MiniTable


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.minigrid;
15
16 import java.awt.event.*;
17 import javax.swing.*;
18 import javax.swing.table.*;
19 import javax.swing.event.*;
20 import java.awt.*;
21 import java.sql.*;
22 import java.math.*;
23 import java.util.*;
24
25 import org.compiere.swing.*;
26 import org.compiere.util.*;
27 import org.compiere.grid.ed.*;
28 import java.beans.*;
29
30 import org.compiere.model.*;
31
32 /**
33  * Mini Table.
34  * Default Read Only Table for Boolean, String, Number, Timestamp values
35  * <p>
36  * After initializing the Table Model, you need to call setColumnClass,
37  * add columns via addColumn or in one go prepare the table.
38  * <code>
39  * Minitable mt = new MiniTable();
40  * String sql = mt.prepareTable(..); // table defined
41  * while() {
42  * // add where to the sql statement
43  * ResultSet rs = ..
44  * mt.loadTable(rs);
45  * rs.close();
46  * }
47  * </code>
48  * @author Jorg Janke
49  * @version $Id: MiniTable.java,v 1.15 2003/10/27 15:22:03 jjanke Exp $
50  */

51 public class MiniTable extends CTable
52 {
53     /**
54      * Default Constructor
55      */

56     public MiniTable()
57     {
58         super();
59     // Log.trace(Log.l4_Data, "MiniTable");
60
setCellSelectionEnabled(false);
61         setRowSelectionAllowed(false);
62         // Default Editor
63
this.setCellEditor(new ROCellEditor());
64     } // MiniTable
65

66     /** List of R/W columns */
67     private ArrayList m_readWriteColumn = new ArrayList();
68     /** List of Column Width */
69     private ArrayList m_minWidth = new ArrayList();
70
71     /** Color Column Index of Model */
72     private int m_colorColumnIndex = -1;
73     /** Color Column compare data */
74     private Object JavaDoc m_colorDataCompare = Env.ZERO;
75
76     /** Multi Selection mode (default false) */
77     private boolean m_multiSelection = false;
78
79     /** Lauout set in prepareTable and used in loadTable */
80     private ColumnInfo[] m_layout = null;
81
82     /**
83      * Size Columns.
84      * Uses Mimimum Column Size
85      */

86     public void autoSize()
87     {
88         Log.trace(Log.l4_Data, "MiniTable.autoSize");
89         //
90
final int SLACK = 8; // making sure it fits in a column
91
final int MAXSIZE = 300; // max size of a column
92
//
93
TableModel model = this.getModel();
94         int size = model.getColumnCount();
95         // for all columns
96
for (int col = 0; col < size; col++)
97         {
98             // Column & minimum width
99
TableColumn tc = this.getColumnModel().getColumn(col);
100             int width = 0;
101             if (m_minWidth.size() > col)
102                 width = ((Integer JavaDoc)m_minWidth.get(col)).intValue();
103         // Log.trace(Log.l4_Data, "Column=" + col + " " + column.getHeaderValue());
104

105             // Header
106
TableCellRenderer renderer = tc.getHeaderRenderer();
107             if (renderer == null)
108                 renderer = new DefaultTableCellRenderer();
109             Component comp = renderer.getTableCellRendererComponent
110                 (this, tc.getHeaderValue(), false, false, 0, 0);
111         // Log.trace(Log.l5_DData, "Hdr - preferred=" + comp.getPreferredSize().width + ", width=" + comp.getWidth());
112
width = Math.max(width, comp.getPreferredSize().width + SLACK);
113
114             // Cells
115
int maxRow = Math.min(30, getRowCount()); // first 30 rows
116
for (int row = 0; row < maxRow; row++)
117             {
118                 renderer = getCellRenderer(row, col);
119                 comp = renderer.getTableCellRendererComponent
120                     (this, getValueAt(row, col), false, false, row, col);
121                 int rowWidth = comp.getPreferredSize().width + SLACK;
122                 width = Math.max(width, rowWidth);
123             }
124             // Width not greater ..
125
width = Math.min(MAXSIZE, width);
126             tc.setPreferredWidth(width);
127         // Log.trace(Log.l5_DData, "width=" + width);
128
} // for all columns
129
} // autoSize
130

131
132     /**
133      * Is Cell Editable
134      * @param row row
135      * @param column column
136      * @return true if editable
137      */

138     public boolean isCellEditable(int row, int column)
139     {
140         // if the first column is a boolean and it is false, it is not editable
141
if (column != 0
142                 && getValueAt(row, 0) instanceof Boolean JavaDoc
143                 && !((Boolean JavaDoc)getValueAt(row, 0)).booleanValue())
144             return false;
145
146         // is the column RW?
147
if (m_readWriteColumn.contains(new Integer JavaDoc(column)))
148             return true;
149         return false;
150     } // isCellEditable
151

152     /**
153      * Set Column to ReadOnly
154      * @param column column
155      * @param readOnly read only
156      */

157     public void setColumnReadOnly (int column, boolean readOnly)
158     {
159         // Column is ReadWrite
160
if (m_readWriteColumn.contains(new Integer JavaDoc(column)))
161         {
162             // Remove from list
163
if (readOnly)
164             {
165                 int size = m_readWriteColumn.size();
166                 for (int i = 0; i < size; i++)
167                 {
168                     if (((Integer JavaDoc)m_readWriteColumn.get(i)).intValue() == column)
169                     {
170                         m_readWriteColumn.remove(i);
171                         break;
172                     }
173                 }
174             } // ReadOnly
175
}
176         // current column is R/O - ReadWrite - add to list
177
else if (!readOnly)
178             m_readWriteColumn.add(new Integer JavaDoc(column));
179     } // setColumnReadOnly
180

181     /*************************************************************************/
182
183     /**
184      * Prepare Table and return SQL
185      *
186      * @param layout array of column info
187      * @param from SQL FROM content
188      * @param where SQL WHERE content
189      * @param multiSelection multiple selections
190      * @return SQL
191      */

192     public String JavaDoc prepareTable(ColumnInfo[] layout,
193         String JavaDoc from, String JavaDoc where, boolean multiSelection, String JavaDoc tableName)
194     {
195         m_layout = layout;
196         m_multiSelection = multiSelection;
197         //
198
StringBuffer JavaDoc sql = new StringBuffer JavaDoc ("SELECT ");
199         // add columns & sql
200
for (int i = 0; i < layout.length; i++)
201         {
202             // create sql
203
if (i > 0)
204                 sql.append(", ");
205             sql.append(layout[i].getColSQL());
206             // adding ID column
207
if (layout[i].isKeyPairCol())
208                 sql.append(",").append(layout[i].getKeyPairColSQL());
209
210             // add to model
211
addColumn(layout[i].getColHeader());
212             if (layout[i].isColorColumn())
213                 setColorColumn(i);
214             if (layout[i].getColClass() == IDColumn.class)
215                 p_keyColumnIndex = i;
216         }
217         // set editors (two steps)
218
for (int i = 0; i < layout.length; i++)
219             setColumnClass(i, layout[i].getColClass(), layout[i].isReadOnly(), layout[i].getColHeader());
220
221         sql.append( " FROM ").append(from);
222         sql.append(" WHERE ").append(where);
223
224         // Table Selection
225
setRowSelectionAllowed(true);
226         //
227
return MRole.getDefault().addAccessSQL(sql.toString(),
228             tableName, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
229     } // prepareTable
230

231     /**
232      * Add Table Column.
233      * after adding a column, you need to set the column classes again
234      * (DefaultTableModel fires TableStructureChanged, which calls
235      * JTable.tableChanged .. createDefaultColumnsFromModel
236      * @param header header
237      */

238     public void addColumn (String JavaDoc header)
239     {
240     // Log.trace(Log.l4_Data, "MiniTable.addColumn", header);
241
int index = getColumnCount();
242         if (getModel() instanceof DefaultTableModel)
243         {
244             DefaultTableModel model = (DefaultTableModel)getModel();
245             model.addColumn(header);
246         }
247         else
248             throw new IllegalArgumentException JavaDoc("Model must be instance of DefaultTableModel");
249     } // addColumn
250

251     /**
252      * Set Column Editor & Renderer to Class.
253      * (after all columns were added)
254      * @param index column index
255      * @param c class of column - determines renderere
256      * @param readOnly read only flag
257      */

258     public void setColumnClass (int index, Class JavaDoc c, boolean readOnly)
259     {
260         setColumnClass(index, c, readOnly, null);
261     } // setColumnClass
262

263     /**
264      * Set Column Editor & Renderer to Class
265      * (after all columns were added)
266      * Lauout of IDColumn depemds on multiSelection
267      * @param index column index
268      * @param c class of column - determines renderere/editors supported:
269      * IDColumn, Boolean, Double (Quantity), BigDecimal (Amount), Integer, Timestamp, String (default)
270      * @param readOnly read only flag
271      * @param header optional header value
272      */

273     public void setColumnClass (int index, Class JavaDoc c, boolean readOnly, String JavaDoc header)
274     {
275     // Log.trace(Log.l4_Data, "MiniTable.setColumnClass - " + index, c.getName() + ", r/o=" + readOnly);
276
TableColumn tc = getColumnModel().getColumn(index);
277         if (tc == null)
278             return;
279         // Set R/O
280
setColumnReadOnly(index, readOnly);
281
282         // Header
283
if (header != null && header.length() > 0)
284             tc.setHeaderValue(header);
285
286         // ID Column & Selection
287
if (c == IDColumn.class)
288         {
289             tc.setCellRenderer(new IDColumnRenderer(m_multiSelection));
290             if (m_multiSelection)
291                 tc.setCellEditor(new IDColumnEditor());
292             else
293                 tc.setCellEditor(new ROCellEditor());
294             m_minWidth.add(new Integer JavaDoc(10));
295             tc.setMaxWidth(20);
296             tc.setPreferredWidth(20);
297             tc.setResizable(false);
298         }
299         // Boolean
300
else if (c == Boolean JavaDoc.class)
301         {
302             tc.setCellRenderer(new CheckRenderer());
303             if (readOnly)
304                 tc.setCellEditor(new ROCellEditor());
305             else
306             {
307                 CCheckBox check = new CCheckBox();
308                 check.setMargin(new Insets(0,0,0,0));
309                 check.setHorizontalAlignment(JLabel.CENTER);
310                 tc.setCellEditor(new DefaultCellEditor(check));
311             }
312             m_minWidth.add(new Integer JavaDoc(30));
313         }
314         // Date
315
else if (c == Timestamp.class)
316         {
317             tc.setCellRenderer(new VCellRenderer(DisplayType.Date));
318             if (readOnly)
319                 tc.setCellEditor(new ROCellEditor());
320             else
321                 tc.setCellEditor(new MiniCellEditor(c));
322             m_minWidth.add(new Integer JavaDoc(30));
323         }
324         // Amount
325
else if (c == BigDecimal.class)
326         {
327             tc.setCellRenderer(new VCellRenderer(DisplayType.Amount));
328             if (readOnly)
329             {
330                 tc.setCellEditor(new ROCellEditor());
331                 m_minWidth.add(new Integer JavaDoc(70));
332             }
333             else
334             {
335                 tc.setCellEditor(new MiniCellEditor(c));
336                 m_minWidth.add(new Integer JavaDoc(80));
337             }
338         }
339         // Number
340
else if (c == Double JavaDoc.class)
341         {
342             tc.setCellRenderer(new VCellRenderer(DisplayType.Number));
343             if (readOnly)
344             {
345                 tc.setCellEditor(new ROCellEditor());
346                 m_minWidth.add(new Integer JavaDoc(70));
347             }
348             else
349             {
350                 tc.setCellEditor(new MiniCellEditor(c));
351                 m_minWidth.add(new Integer JavaDoc(80));
352             }
353         }
354         // Integer
355
else if (c == Integer JavaDoc.class)
356         {
357             tc.setCellRenderer(new VCellRenderer(DisplayType.Integer));
358             if (readOnly)
359                 tc.setCellEditor(new ROCellEditor());
360             else
361                 tc.setCellEditor(new MiniCellEditor(c));
362             m_minWidth.add(new Integer JavaDoc(30));
363         }
364         // String
365
else
366         {
367             tc.setCellRenderer(new VCellRenderer(DisplayType.String));
368             if (readOnly)
369                 tc.setCellEditor(new ROCellEditor());
370             else
371                 tc.setCellEditor(new MiniCellEditor(String JavaDoc.class));
372             m_minWidth.add(new Integer JavaDoc(30));
373         }
374     // Log.trace(Log.l5_DData, "Renderer=" + tc.getCellRenderer().toString() + ", Editor=" + tc.getCellEditor().toString());
375
} // setColumnClass
376

377     /**
378      * Clear Table Content
379      * @param no number of rows
380      */

381     public void setRowCount (int no)
382     {
383         if (getModel() instanceof DefaultTableModel)
384         {
385             DefaultTableModel model = (DefaultTableModel)getModel();
386             model.setRowCount(no);
387         // Log.trace(Log.l4_Data, "MiniTable.setRowCount", "rows=" + getRowCount() + ", cols=" + getColumnCount());
388
}
389         else
390             throw new IllegalArgumentException JavaDoc("Model must be instance of DefaultTableModel");
391     } // setRowCount
392

393     /*************************************************************************/
394
395     /**
396      * Load Table from ResultSet - The ResultSet is not closed
397      *
398      * @param rs ResultSet with the column layout defined in prepareTable
399      */

400     public void loadTable(ResultSet rs)
401     {
402         Log.trace(Log.l3_Util, "MiniTable.loadTable");
403         if (m_layout == null)
404             throw new UnsupportedOperationException JavaDoc("MiniTable.loadTable - layout not defined");
405
406         // Clear Table
407
setRowCount(0);
408         //
409
try
410         {
411             while (rs.next())
412             {
413                 int row = getRowCount();
414                 setRowCount(row+1);
415                 int colOffset = 1; // columns start with 1
416
for (int col = 0; col < m_layout.length; col++)
417                 {
418                     Object JavaDoc data = null;
419                     Class JavaDoc c = m_layout[col].getColClass();
420                     int colIndex = col + colOffset;
421                     if (c == IDColumn.class)
422                         data = new IDColumn(rs.getInt(colIndex));
423                     else if (c == Boolean JavaDoc.class)
424                         data = new Boolean JavaDoc(rs.getString(colIndex).equals("Y"));
425                     else if (c == Timestamp.class)
426                         data = rs.getTimestamp(colIndex);
427                     else if (c == BigDecimal.class)
428                         data = rs.getBigDecimal(colIndex);
429                     else if (c == Double JavaDoc.class)
430                         data = new Double JavaDoc(rs.getDouble(colIndex));
431                     else if (c == Integer JavaDoc.class)
432                         data = new Integer JavaDoc(rs.getInt(colIndex));
433                     else if (c == KeyNamePair.class)
434                     {
435                         String JavaDoc display = rs.getString(colIndex);
436                         int key = rs.getInt(colIndex+1);
437                         data = new KeyNamePair(key, display);
438                         colOffset++;
439                     }
440                     else
441                     {
442                         String JavaDoc s = rs.getString(colIndex);
443                         if (s != null)
444                             data = s.trim(); // problems with NCHAR
445
}
446                     // store
447
setValueAt(data, row, col);
448             // Log.trace(Log.l6_Database, "r=" + row + ", c=" + col + " " + m_layout[col].getColHeader(),
449
// "data=" + data.toString() + " " + data.getClass().getName() + " * " + m_table.getCellRenderer(row, col));
450
}
451             }
452         }
453         catch (SQLException e)
454         {
455             Log.error("MiniTable.loadTable", e);
456         }
457         autoSize();
458     } // executeQuery
459

460     /**
461      * Get the key of currently selected row based on layout defined in prepareTable
462      * @return ID if key
463      */

464     public Integer JavaDoc getSelectedRowKey()
465     {
466         if (m_layout == null)
467             throw new UnsupportedOperationException JavaDoc("MiniTable.getSelectedRowKey - layout not defined");
468
469         int row = getSelectedRow();
470         if (row != -1 && p_keyColumnIndex != -1)
471         {
472             Object JavaDoc data = getModel().getValueAt(row, p_keyColumnIndex);
473             if (data instanceof IDColumn)
474                 data = ((IDColumn)data).getRecord_ID();
475             if (data instanceof Integer JavaDoc)
476                 return (Integer JavaDoc)data;
477         }
478         return null;
479     } // getSelectedRowKey
480

481     /*************************************************************************/
482
483     /**
484      * Get Layout
485      * @return Array of ColumnInfo
486      */

487     public ColumnInfo[] getLayoutInfo()
488     {
489         return m_layout;
490     } // getLayout
491

492     /**
493      * Set Single Selection
494      * @param multiSelection multiple selections
495      */

496     public void setMultiSelection (boolean multiSelection)
497     {
498         m_multiSelection = multiSelection;
499     } // setMultiSelection
500

501     /**
502      * Single Selection Table
503      * @return true if multiple rows can be selected
504      */

505     public boolean isMultiSelection()
506     {
507         return m_multiSelection;
508     } // isMultiSelection
509

510     /**
511      * Set the Column to determine the color of the row (based on model index)
512      * @param modelIndex model index
513      */

514     public void setColorColumn (int modelIndex)
515     {
516         m_colorColumnIndex = modelIndex;
517     } // setColorColumn
518

519     /**
520      * Set ColorColumn comparison criteria
521      * @param dataCompare data
522      */

523     public void setColorCompare (Object JavaDoc dataCompare)
524     {
525         m_colorDataCompare = dataCompare;
526     } //
527

528     /**
529      * Get ColorCode for Row.
530      * <pre>
531      * If numerical value in compare column is
532      * negative = -1,
533      * positive = 1,
534      * otherwise = 0
535      * If Timestamp
536      * </pre>
537      * @param row row
538      * @return color code
539      */

540     public int getColorCode (int row)
541     {
542         if (m_colorColumnIndex == -1)
543             return 0;
544
545         Object JavaDoc data = getModel().getValueAt(row, m_colorColumnIndex);
546         int cmp = 0;
547
548         // We need to have a Number
549
if (data == null)
550             return 0;
551         try
552         {
553             if (data instanceof Timestamp)
554             {
555                 if (m_colorDataCompare == null || !(m_colorDataCompare instanceof Timestamp))
556                     m_colorDataCompare = new Timestamp(System.currentTimeMillis());
557                 cmp = ((Timestamp)m_colorDataCompare).compareTo(data);
558             }
559             else
560             {
561                 if (m_colorDataCompare == null || !(m_colorDataCompare instanceof BigDecimal))
562                     m_colorDataCompare = Env.ZERO;
563                 if (!(data instanceof BigDecimal))
564                     data = new BigDecimal(data.toString());
565                 cmp = ((BigDecimal)m_colorDataCompare).compareTo(data);
566             }
567         }
568         catch (Exception JavaDoc e)
569         {
570             return 0;
571         }
572         if (cmp > 0)
573             return -1;
574         if (cmp < 0)
575             return 1;
576         return 0;
577     } // getColorCode
578

579 } // MiniTable
580
Popular Tags