001: package examples.swingdemos;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005:
006: import javax.swing.*;
007: import javax.swing.table.*;
008:
009: public class TableRenderDemo extends JFrame {
010: boolean DEBUG = true;
011:
012: public TableRenderDemo() {
013: super ("TableRenderDemo");
014:
015: MyTableModel myModel = new MyTableModel();
016: JTable table = new JTable(myModel);
017: table
018: .setPreferredScrollableViewportSize(new Dimension(500,
019: 70));
020:
021: //Create the scroll pane and add the table to it.
022: JScrollPane scrollPane = new JScrollPane(table);
023:
024: //Set up column sizes.
025: initColumnSizes(table, myModel);
026:
027: //Fiddle with the Sport column's cell editors/renderers.
028: setUpSportColumn(table.getColumnModel().getColumn(2));
029:
030: //Add the scroll pane to this window.
031: getContentPane().add(scrollPane, BorderLayout.CENTER);
032:
033: addWindowListener(new WindowAdapter() {
034: public void windowClosing(WindowEvent e) {
035: System.exit(0);
036: }
037: });
038: }
039:
040: /*
041: * This method picks good column sizes.
042: * If all column heads are wider than the column's cells'
043: * contents, then you can just use column.sizeWidthToFit().
044: */
045: private void initColumnSizes(JTable table, MyTableModel model) {
046: TableColumn column = null;
047: Component comp = null;
048: int headerWidth = 0;
049: int cellWidth = 0;
050: Object[] longValues = model.longValues;
051:
052: for (int i = 0; i < 5; i++) {
053: column = table.getColumnModel().getColumn(i);
054:
055: try {
056: comp = column.getHeaderRenderer()
057: .getTableCellRendererComponent(null,
058: column.getHeaderValue(), false, false,
059: 0, 0);
060: headerWidth = comp.getPreferredSize().width;
061: } catch (NullPointerException e) {
062: System.err.println("Null pointer exception!");
063: System.err
064: .println(" getHeaderRenderer returns null in 1.3.");
065: System.err
066: .println(" The replacement is getDefaultRenderer.");
067: }
068:
069: comp = table.getDefaultRenderer(model.getColumnClass(i))
070: .getTableCellRendererComponent(table,
071: longValues[i], false, false, 0, i);
072: cellWidth = comp.getPreferredSize().width;
073:
074: if (DEBUG) {
075: System.out.println("Initializing width of column " + i
076: + ". " + "headerWidth = " + headerWidth
077: + "; cellWidth = " + cellWidth);
078: }
079:
080: //XXX: Before Swing 1.1 Beta 2, use setMinWidth instead.
081: column.setPreferredWidth(Math.max(headerWidth, cellWidth));
082: }
083: }
084:
085: public void setUpSportColumn(TableColumn sportColumn) {
086: //Set up the editor for the sport cells.
087: JComboBox comboBox = new JComboBox();
088: comboBox.addItem("Snowboarding");
089: comboBox.addItem("Rowing");
090: comboBox.addItem("Chasing toddlers");
091: comboBox.addItem("Speed reading");
092: comboBox.addItem("Teaching high school");
093: comboBox.addItem("None");
094: sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
095:
096: //Set up tool tips for the sport cells.
097: DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
098: renderer.setToolTipText("Click for combo box");
099: sportColumn.setCellRenderer(renderer);
100:
101: //Set up tool tip for the sport column header.
102: TableCellRenderer headerRenderer = sportColumn
103: .getHeaderRenderer();
104: if (headerRenderer instanceof DefaultTableCellRenderer) {
105: ((DefaultTableCellRenderer) headerRenderer)
106: .setToolTipText("Click the sport to see a list of choices");
107: }
108: }
109:
110: class MyTableModel extends AbstractTableModel {
111: final String[] columnNames = { "First Name", "Last Name",
112: "Sport", "# of Years", "Vegetarian" };
113: final Object[][] data = {
114: { "Mary", "Campione", "Snowboarding", new Integer(5),
115: new Boolean(false) },
116: { "Alison", "Huml", "Rowing", new Integer(3),
117: new Boolean(true) },
118: { "Kathy", "Walrath", "Chasing toddlers",
119: new Integer(2), new Boolean(false) },
120: { "Sharon", "Zakhour", "Speed reading",
121: new Integer(20), new Boolean(true) },
122: { "Angela", "Lih", "Teaching high school",
123: new Integer(4), new Boolean(false) } };
124: public final Object[] longValues = { "Angela", "Andrews",
125: "Teaching high school", new Integer(20), Boolean.TRUE };
126:
127: public int getColumnCount() {
128: return columnNames.length;
129: }
130:
131: public int getRowCount() {
132: return data.length;
133: }
134:
135: public String getColumnName(int col) {
136: return columnNames[col];
137: }
138:
139: public Object getValueAt(int row, int col) {
140: return data[row][col];
141: }
142:
143: /*
144: * JTable uses this method to determine the default renderer/
145: * editor for each cell. If we didn't implement this method,
146: * then the last column would contain text ("true"/"false"),
147: * rather than a check box.
148: */
149: public Class getColumnClass(int c) {
150: return getValueAt(0, c).getClass();
151: }
152:
153: /*
154: * Don't need to implement this method unless your table's
155: * editable.
156: */
157: public boolean isCellEditable(int row, int col) {
158: //Note that the data/cell address is constant,
159: //no matter where the cell appears onscreen.
160: if (col < 2) {
161: return false;
162: } else {
163: return true;
164: }
165: }
166:
167: /*
168: * Don't need to implement this method unless your table's
169: * data can change.
170: */
171: public void setValueAt(Object value, int row, int col) {
172: if (DEBUG) {
173: System.out.println("Setting value at " + row + ","
174: + col + " to " + value + " (an instance of "
175: + value.getClass() + ")");
176: }
177:
178: if (data[0][col] instanceof Integer
179: && !(value instanceof Integer)) {
180: //With JFC/Swing 1.1 and JDK 1.2, we need to create
181: //an Integer from the value; otherwise, the column
182: //switches to contain Strings. Starting with v 1.3,
183: //the table automatically converts value to an Integer,
184: //so you only need the code in the 'else' part of this
185: //'if' block.
186: try {
187: data[row][col] = new Integer(value.toString());
188: fireTableCellUpdated(row, col);
189: } catch (NumberFormatException e) {
190: JOptionPane
191: .showMessageDialog(
192: TableRenderDemo.this ,
193: "The \""
194: + getColumnName(col)
195: + "\" column accepts only integer values.");
196: }
197: } else {
198: data[row][col] = value;
199: fireTableCellUpdated(row, col);
200: }
201:
202: if (DEBUG) {
203: System.out.println("New value of data:");
204: printDebugData();
205: }
206: }
207:
208: private void printDebugData() {
209: int numRows = getRowCount();
210: int numCols = getColumnCount();
211:
212: for (int i = 0; i < numRows; i++) {
213: System.out.print(" row " + i + ":");
214: for (int j = 0; j < numCols; j++) {
215: System.out.print(" " + data[i][j]);
216: }
217: System.out.println();
218: }
219: System.out.println("--------------------------");
220: }
221: }
222:
223: public static void main(String[] args) {
224: TableRenderDemo frame = new TableRenderDemo();
225: frame.pack();
226: frame.setVisible(true);
227: }
228: }
|