001: package examples.swingdemos;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005:
006: import javax.swing.*;
007: import javax.swing.border.*;
008: import javax.swing.table.*;
009:
010: /**
011: * This is like TableEditDemo, except that it substitutes a
012: * Favorite Color column for the Last Name column and specifies
013: * a custom cell renderer and editor for the color data.
014: */
015: public class TableDialogEditDemo extends JFrame {
016: boolean DEBUG = false;
017:
018: public TableDialogEditDemo() {
019: super ("TableDialogEditDemo");
020:
021: MyTableModel myModel = new MyTableModel();
022: JTable table = new JTable(myModel);
023: table
024: .setPreferredScrollableViewportSize(new Dimension(500,
025: 70));
026:
027: //Create the scroll pane and add the table to it.
028: JScrollPane scrollPane = new JScrollPane(table);
029:
030: //Set up renderer and editor for the Favorite Color column.
031: setUpColorRenderer(table);
032: setUpColorEditor(table);
033:
034: //Set up real input validation for integer data.
035: setUpIntegerEditor(table);
036:
037: //Add the scroll pane to this window.
038: getContentPane().add(scrollPane, BorderLayout.CENTER);
039:
040: addWindowListener(new WindowAdapter() {
041: public void windowClosing(WindowEvent e) {
042: System.exit(0);
043: }
044: });
045: }
046:
047: class ColorRenderer extends JLabel implements TableCellRenderer {
048: Border unselectedBorder = null;
049: Border selectedBorder = null;
050: boolean isBordered = true;
051:
052: public ColorRenderer(boolean bordered) {
053: super ();
054: this .isBordered = bordered;
055: setOpaque(true); //MUST do this for background to show up.
056: }
057:
058: public Component getTableCellRendererComponent(JTable table,
059: Object color, boolean isSelected, boolean hasFocus,
060: int row, int column) {
061: setBackground((Color) color);
062: if (isBordered) {
063: if (isSelected) {
064: if (selectedBorder == null) {
065: selectedBorder = BorderFactory
066: .createMatteBorder(2, 5, 2, 5, table
067: .getSelectionBackground());
068: }
069: setBorder(selectedBorder);
070: } else {
071: if (unselectedBorder == null) {
072: unselectedBorder = BorderFactory
073: .createMatteBorder(2, 5, 2, 5, table
074: .getBackground());
075: }
076: setBorder(unselectedBorder);
077: }
078: }
079: return this ;
080: }
081: }
082:
083: private void setUpColorRenderer(JTable table) {
084: table.setDefaultRenderer(Color.class, new ColorRenderer(true));
085: }
086:
087: //Set up the editor for the Color cells.
088: private void setUpColorEditor(JTable table) {
089: //First, set up the button that brings up the dialog.
090: final JButton button = new JButton("") {
091: public void setText(String s) {
092: //Button never shows text -- only color.
093: }
094: };
095: button.setBackground(Color.white);
096: button.setBorderPainted(false);
097: button.setMargin(new Insets(0, 0, 0, 0));
098:
099: //Now create an editor to encapsulate the button, and
100: //set it up as the editor for all Color cells.
101: final ColorEditor colorEditor = new ColorEditor(button);
102: table.setDefaultEditor(Color.class, colorEditor);
103:
104: //Set up the dialog that the button brings up.
105: final JColorChooser colorChooser = new JColorChooser();
106: ActionListener okListener = new ActionListener() {
107: public void actionPerformed(ActionEvent e) {
108: colorEditor.currentColor = colorChooser.getColor();
109: }
110: };
111: final JDialog dialog = JColorChooser.createDialog(button,
112: "Pick a Color", true, colorChooser, okListener, null); //XXXDoublecheck this is OK
113:
114: //Here's the code that brings up the dialog.
115: button.addActionListener(new ActionListener() {
116: public void actionPerformed(ActionEvent e) {
117: button.setBackground(colorEditor.currentColor);
118: colorChooser.setColor(colorEditor.currentColor);
119: //Without the following line, the dialog comes up
120: //in the middle of the screen.
121: //dialog.setLocationRelativeTo(button);
122: dialog.show();
123: }
124: });
125: }
126:
127: /*
128: * The editor button that brings up the dialog.
129: * We extend DefaultCellEditor for convenience,
130: * even though it mean we have to create a dummy
131: * check box. Another approach would be to copy
132: * the implementation of TableCellEditor methods
133: * from the source code for DefaultCellEditor.
134: */
135: class ColorEditor extends DefaultCellEditor {
136: Color currentColor = null;
137:
138: public ColorEditor(JButton b) {
139: super (new JCheckBox()); //Unfortunately, the constructor
140: //expects a check box, combo box,
141: //or text field.
142: editorComponent = b;
143: setClickCountToStart(1); //This is usually 1 or 2.
144:
145: //Must do this so that editing stops when appropriate.
146: b.addActionListener(new ActionListener() {
147: public void actionPerformed(ActionEvent e) {
148: fireEditingStopped();
149: }
150: });
151: }
152:
153: protected void fireEditingStopped() {
154: super .fireEditingStopped();
155: }
156:
157: public Object getCellEditorValue() {
158: return currentColor;
159: }
160:
161: public Component getTableCellEditorComponent(JTable table,
162: Object value, boolean isSelected, int row, int column) {
163: ((JButton) editorComponent).setText(value.toString());
164: currentColor = (Color) value;
165: return editorComponent;
166: }
167: }
168:
169: private void setUpIntegerEditor(JTable table) {
170: //Set up the editor for the integer cells.
171: final WholeNumberField integerField = new WholeNumberField(0, 5);
172: integerField.setHorizontalAlignment(SwingConstants.RIGHT);
173:
174: DefaultCellEditor integerEditor = new DefaultCellEditor(
175: integerField) {
176: //Override DefaultCellEditor's getCellEditorValue method
177: //to return an Integer, not a String:
178: public Object getCellEditorValue() {
179: return new Integer(integerField.getValue());
180: }
181: };
182: table.setDefaultEditor(Integer.class, integerEditor);
183: }
184:
185: class MyTableModel extends AbstractTableModel {
186: final String[] columnNames = { "First Name", "Favorite Color",
187: "Sport", "# of Years", "Vegetarian" };
188: final Object[][] data = {
189: { "Mary", new Color(153, 0, 153), "Snowboarding",
190: new Integer(5), new Boolean(false) },
191: { "Alison", new Color(51, 51, 153), "Rowing",
192: new Integer(3), new Boolean(true) },
193: { "Kathy", new Color(51, 102, 51), "Chasing toddlers",
194: new Integer(2), new Boolean(false) },
195: { "Mark", Color.blue, "Speed reading", new Integer(20),
196: new Boolean(true) },
197: { "Philip", Color.pink, "Pool", new Integer(7),
198: new Boolean(false) } };
199:
200: public int getColumnCount() {
201: return columnNames.length;
202: }
203:
204: public int getRowCount() {
205: return data.length;
206: }
207:
208: public String getColumnName(int col) {
209: return columnNames[col];
210: }
211:
212: public Object getValueAt(int row, int col) {
213: return data[row][col];
214: }
215:
216: /*
217: * JTable uses this method to determine the default renderer/
218: * editor for each cell. If we didn't implement this method,
219: * then the last column would contain text ("true"/"false"),
220: * rather than a check box.
221: */
222: public Class getColumnClass(int c) {
223: return getValueAt(0, c).getClass();
224: }
225:
226: /*
227: * Don't need to implement this method unless your table's
228: * editable.
229: */
230: public boolean isCellEditable(int row, int col) {
231: //Note that the data/cell address is constant,
232: //no matter where the cell appears onscreen.
233: if (col < 1) {
234: return false;
235: } else {
236: return true;
237: }
238: }
239:
240: public void setValueAt(Object value, int row, int col) {
241: if (DEBUG) {
242: System.out.println("Setting value at " + row + ","
243: + col + " to " + value + " (an instance of "
244: + value.getClass() + ")");
245: }
246:
247: data[row][col] = value;
248: fireTableCellUpdated(row, col);
249:
250: if (DEBUG) {
251: System.out.println("New value of data:");
252: printDebugData();
253: }
254: }
255:
256: private void printDebugData() {
257: int numRows = getRowCount();
258: int numCols = getColumnCount();
259:
260: for (int i = 0; i < numRows; i++) {
261: System.out.print(" row " + i + ":");
262: for (int j = 0; j < numCols; j++) {
263: System.out.print(" " + data[i][j]);
264: }
265: System.out.println();
266: }
267: System.out.println("--------------------------");
268: }
269: }
270:
271: public static void main(String[] args) {
272: TableDialogEditDemo frame = new TableDialogEditDemo();
273: frame.pack();
274: frame.setVisible(true);
275: }
276: }
|