Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / javax / swing / JTable.java
blob69a865df9c0751923f0aba4c4dc06bd719a68664
1 /* JTable.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Cursor;
44 import java.awt.Dimension;
45 import java.awt.Font;
46 import java.awt.FontMetrics;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ActionListener;
51 import java.awt.event.FocusListener;
52 import java.beans.PropertyChangeEvent;
53 import java.beans.PropertyChangeListener;
54 import java.text.DateFormat;
55 import java.text.NumberFormat;
56 import java.util.Date;
57 import java.util.EventObject;
58 import java.util.Hashtable;
59 import java.util.Locale;
60 import java.util.Vector;
62 import javax.accessibility.Accessible;
63 import javax.accessibility.AccessibleComponent;
64 import javax.accessibility.AccessibleContext;
65 import javax.accessibility.AccessibleExtendedTable;
66 import javax.accessibility.AccessibleRole;
67 import javax.accessibility.AccessibleSelection;
68 import javax.accessibility.AccessibleStateSet;
69 import javax.accessibility.AccessibleTable;
70 import javax.accessibility.AccessibleTableModelChange;
71 import javax.swing.event.CellEditorListener;
72 import javax.swing.event.ChangeEvent;
73 import javax.swing.event.ListSelectionEvent;
74 import javax.swing.event.ListSelectionListener;
75 import javax.swing.event.TableColumnModelEvent;
76 import javax.swing.event.TableColumnModelListener;
77 import javax.swing.event.TableModelEvent;
78 import javax.swing.event.TableModelListener;
79 import javax.swing.plaf.TableUI;
80 import javax.swing.table.DefaultTableCellRenderer;
81 import javax.swing.table.DefaultTableColumnModel;
82 import javax.swing.table.DefaultTableModel;
83 import javax.swing.table.JTableHeader;
84 import javax.swing.table.TableCellEditor;
85 import javax.swing.table.TableCellRenderer;
86 import javax.swing.table.TableColumn;
87 import javax.swing.table.TableColumnModel;
88 import javax.swing.table.TableModel;
89 import javax.swing.text.Caret;
91 public class JTable
92 extends JComponent
93 implements TableModelListener, Scrollable, TableColumnModelListener,
94 ListSelectionListener, CellEditorListener, Accessible
96 /**
97 * Provides accessibility support for <code>JTable</code>.
99 * @author Roman Kennke (kennke@aicas.com)
101 protected class AccessibleJTable
102 extends AccessibleJComponent
103 implements AccessibleSelection, ListSelectionListener, TableModelListener,
104 TableColumnModelListener, CellEditorListener, PropertyChangeListener,
105 AccessibleExtendedTable
109 * Provides accessibility support for table cells.
111 * @author Roman Kennke (kennke@aicas.com)
113 protected class AccessibleJTableCell
114 extends AccessibleContext
115 implements Accessible, AccessibleComponent
119 * The table of this cell.
121 private JTable table;
124 * The row index of this cell.
126 private int row;
129 * The column index of this cell.
131 private int column;
134 * The index of this cell inside the AccessibleJTable parent.
136 private int index;
139 * Creates a new <code>AccessibleJTableCell</code>.
141 * @param t the table
142 * @param r the row
143 * @param c the column
144 * @param i the index of this cell inside the accessible table parent
146 public AccessibleJTableCell(JTable t, int r, int c, int i)
148 table = t;
149 row = r;
150 column = c;
151 index = i;
155 * Returns the accessible row for the table cell.
157 * @return the accessible row for the table cell
159 public AccessibleRole getAccessibleRole()
161 // TODO: What is the role of the table cell?
162 return AccessibleRole.UNKNOWN;
166 * Returns the accessible state set of this accessible table cell.
168 * @return the accessible state set of this accessible table cell
170 public AccessibleStateSet getAccessibleStateSet()
172 // TODO: What state shoiuld be returned here?
173 return new AccessibleStateSet();
177 * Returns the index of this cell in the parent object.
179 * @return the index of this cell in the parent object
181 public int getAccessibleIndexInParent()
183 return index;
187 * Returns the number of children of this object. Table cells cannot have
188 * children, so we return <code>0</code> here.
190 * @return <code>0</code>
192 public int getAccessibleChildrenCount()
194 return 0;
198 * Returns the accessible child at index <code>i</code>. Table cells
199 * don't have children, so we return <code>null</code> here.
201 * @return <code>null</code>
203 public Accessible getAccessibleChild(int i)
205 return null;
209 * Returns the locale setting for this accessible table cell.
211 * @return the locale setting for this accessible table cell
213 public Locale getLocale()
215 // TODO: For now, we return english here. This must be fixed as soon
216 // as we have a localized Swing.
217 return Locale.ENGLISH;
221 * Returns the accessible context of this table cell. Since accessible
222 * table cells are their own accessible context, we return
223 * <code>this</code>.
225 * @return the accessible context of this table cell
227 public AccessibleContext getAccessibleContext()
229 return this;
233 * Returns the background color of this cell.
235 * @return the background color of this cell
237 public Color getBackground()
239 return table.getBackground();
243 * Sets the background of the cell. Since table cells cannot have
244 * individual background colors, this method does nothing. Set the
245 * background directly on the table instead.
247 * @param color not used
249 public void setBackground(Color color)
251 // This method does nothing. See API comments.
255 * Returns the foreground color of the table cell.
257 * @return the foreground color of the table cell
259 public Color getForeground()
261 return table.getForeground();
265 * Sets the foreground of the cell. Since table cells cannot have
266 * individual foreground colors, this method does nothing. Set the
267 * foreground directly on the table instead.
269 * @param color not used
271 public void setForeground(Color color)
273 // This method does nothing. See API comments.
277 * Returns the cursor for this table cell.
279 * @return the cursor for this table cell
281 public Cursor getCursor()
283 return table.getCursor();
287 * Sets the cursor of the cell. Since table cells cannot have
288 * individual cursors, this method does nothing. Set the
289 * cursor directly on the table instead.
291 * @param cursor not used
293 public void setCursor(Cursor cursor)
295 // This method does nothing. See API comments.
299 * Returns the font of the table cell.
301 * @return the font of the table cell
303 public Font getFont()
305 return table.getFont();
309 * Sets the font of the cell. Since table cells cannot have
310 * individual fonts, this method does nothing. Set the
311 * font directly on the table instead.
313 * @param font not used
315 public void setFont(Font font)
317 // This method does nothing. See API comments.
321 * Returns the font metrics for a specified font.
323 * @param font the font for which we return the metrics
325 * @return the font metrics for a specified font
327 public FontMetrics getFontMetrics(Font font)
329 return table.getFontMetrics(font);
333 * Returns <code>true</code> if this table cell is enabled,
334 * <code>false</code> otherwise.
336 * @return <code>true</code> if this table cell is enabled,
337 * <code>false</code> otherwise
339 public boolean isEnabled()
341 return table.isEnabled();
345 * Table cells cannot be disabled or enabled individually, so this method
346 * does nothing. Set the enabled flag on the table itself.
348 * @param b not used here
350 public void setEnabled(boolean b)
352 // This method does nothing. See API comments.
356 * Returns <code>true</code> if this cell is visible, <code>false</code>
357 * otherwise.
359 * @return <code>true</code> if this cell is visible, <code>false</code>
360 * otherwise
362 public boolean isVisible()
364 return table.isVisible();
368 * The visibility cannot be set on individual table cells, so this method
369 * does nothing. Set the visibility on the table itself.
371 * @param b not used
373 public void setVisible(boolean b)
375 // This method does nothing. See API comments.
379 * Returns <code>true</code> if this table cell is currently showing on
380 * screen.
382 * @return <code>true</code> if this table cell is currently showing on
383 * screen
385 public boolean isShowing()
387 return table.isShowing();
391 * Returns <code>true</code> if this table cell contains the location
392 * at <code>point</code>, <code>false</code> otherwise.
393 * <code>point</code> is interpreted as relative to the coordinate system
394 * of the table cell.
396 * @return <code>true</code> if this table cell contains the location
397 * at <code>point</code>, <code>false</code> otherwise
399 public boolean contains(Point point)
401 Rectangle cellRect = table.getCellRect(row, column, true);
402 cellRect.x = 0;
403 cellRect.y = 0;
404 return cellRect.contains(point);
408 * Returns the screen location of the table cell.
410 * @return the screen location of the table cell
412 public Point getLocationOnScreen()
414 Point tableLoc = table.getLocationOnScreen();
415 Rectangle cellRect = table.getCellRect(row, column, true);
416 tableLoc.x += cellRect.x;
417 tableLoc.y += cellRect.y;
418 return tableLoc;
422 * Returns the location of this cell relative to the table's bounds.
424 * @return the location of this cell relative to the table's bounds
426 public Point getLocation()
428 Rectangle cellRect = table.getCellRect(row, column, true);
429 return new Point(cellRect.x, cellRect.y);
433 * The location of the table cells cannot be manipulated directly, so
434 * this method does nothing.
436 * @param point not used
438 public void setLocation(Point point)
440 // This method does nothing. See API comments.
444 * Returns the bounds of the cell relative to its table.
446 * @return the bounds of the cell relative to its table
448 public Rectangle getBounds()
450 return table.getCellRect(row, column, true);
454 * The bounds of the table cells cannot be manipulated directly, so
455 * this method does nothing.
457 * @param rectangle not used
459 public void setBounds(Rectangle rectangle)
461 // This method does nothing. See API comments.
465 * Returns the size of the table cell.
467 * @return the size of the table cell
469 public Dimension getSize()
471 Rectangle cellRect = table.getCellRect(row, column, true);
472 return new Dimension(cellRect.width, cellRect.height);
476 * The size cannot be set on table cells directly, so this method does
477 * nothing.
479 * @param dimension not used
481 public void setSize(Dimension dimension)
483 // This method does nothing. See API comments.
487 * Table cells have no children, so we return <code>null</code> here.
489 * @return <code>null</code>
491 public Accessible getAccessibleAt(Point point)
493 return null;
497 * Returns <code>true</code> if this table cell is focus traversable,
498 * <code>false</code> otherwise.
500 * @return <code>true</code> if this table cell is focus traversable,
501 * <code>false</code> otherwise
503 public boolean isFocusTraversable()
505 return table.isFocusable();
509 * Requests that this table cell gets the keyboard focus.
511 public void requestFocus()
513 // We first set the selection models' lead selection to this cell.
514 table.getColumnModel().getSelectionModel()
515 .setLeadSelectionIndex(column);
516 table.getSelectionModel().setLeadSelectionIndex(row);
517 // Now we request that the table receives focus.
518 table.requestFocus();
522 * Adds a focus listener to this cell. The focus listener is really
523 * added to the table, so there is no way to find out when an individual
524 * cell changes the focus.
526 * @param listener the focus listener to add
528 public void addFocusListener(FocusListener listener)
530 table.addFocusListener(listener);
534 * Removes a focus listener from the cell. The focus listener is really
535 * removed from the table.
537 * @param listener the listener to remove
539 public void removeFocusListener(FocusListener listener)
541 table.removeFocusListener(listener);
546 protected class AccessibleJTableModelChange
547 implements AccessibleTableModelChange
549 protected int type;
550 protected int firstRow;
551 protected int lastRow;
552 protected int firstColumn;
553 protected int lastColumn;
555 protected AccessibleJTableModelChange(int type, int firstRow,
556 int lastRow, int firstColumn,
557 int lastColumn)
559 this.type = type;
560 this.firstRow = firstRow;
561 this.lastRow = lastRow;
562 this.firstColumn = firstColumn;
563 this.lastColumn = lastColumn;
566 public int getType()
568 return type;
571 public int getFirstRow()
573 return firstRow;
576 public int getLastRow()
578 return lastRow;
581 public int getFirstColumn()
583 return firstColumn;
586 public int getLastColumn()
588 return lastColumn;
593 * Creates a new <code>AccessibleJTable</code>.
595 * @since JDK1.5
597 protected AccessibleJTable()
599 getModel().addTableModelListener(this);
600 getSelectionModel().addListSelectionListener(this);
601 getColumnModel().addColumnModelListener(this);
602 getCellEditor().addCellEditorListener(this);
606 * Returns the number of selected items in this table.
608 public int getAccessibleSelectionCount()
610 return getSelectedColumnCount();
613 public Accessible getAccessibleSelection(int i)
615 // TODO Auto-generated method stub
616 return null;
619 public boolean isAccessibleChildSelected(int i)
621 // TODO Auto-generated method stub
622 return false;
625 public void addAccessibleSelection(int i)
627 // TODO Auto-generated method stub
631 public void removeAccessibleSelection(int i)
633 // TODO Auto-generated method stub
637 public void clearAccessibleSelection()
639 // TODO Auto-generated method stub
643 public void selectAllAccessibleSelection()
645 // TODO Auto-generated method stub
649 public void valueChanged(ListSelectionEvent event)
651 // TODO Auto-generated method stub
656 * Receives notification when the table model changes. Depending on the
657 * type of change, this method calls {@link #tableRowsInserted} or
658 * {@link #tableRowsDeleted}.
660 * @param event the table model event
662 public void tableChanged(TableModelEvent event)
664 switch (event.getType())
666 case TableModelEvent.INSERT:
667 tableRowsInserted(event);
668 break;
669 case TableModelEvent.DELETE:
670 tableRowsDeleted(event);
671 break;
676 * Receives notification when one or more rows have been inserted into the
677 * table.
679 * @param event the table model event
681 public void tableRowsInserted(TableModelEvent event)
683 // TODO: What to do here, if anything? This might be a hook method for
684 // subclasses...
688 * Receives notification when one or more rows have been deleted from the
689 * table.
691 * @param event the table model event
693 public void tableRowsDeleted(TableModelEvent event)
695 // TODO: What to do here, if anything? This might be a hook method for
696 // subclasses...
699 public void columnAdded(TableColumnModelEvent event)
701 // TODO Auto-generated method stub
705 public void columnMarginChanged(ChangeEvent event)
707 // TODO Auto-generated method stub
711 public void columnMoved(TableColumnModelEvent event)
713 // TODO Auto-generated method stub
717 public void columnRemoved(TableColumnModelEvent event)
719 // TODO Auto-generated method stub
723 public void columnSelectionChanged(ListSelectionEvent event)
725 // TODO Auto-generated method stub
729 public void editingCanceled(ChangeEvent event)
731 // TODO Auto-generated method stub
735 public void editingStopped(ChangeEvent event)
737 // TODO Auto-generated method stub
742 * Receives notification when any of the JTable's properties changes. This
743 * is used to replace the listeners on the table's model, selection model,
744 * column model and cell editor.
746 * @param e the property change event
748 public void propertyChange(PropertyChangeEvent e)
750 String propName = e.getPropertyName();
751 if (propName.equals("tableModel"))
753 TableModel oldModel = (TableModel) e.getOldValue();
754 oldModel.removeTableModelListener(this);
755 TableModel newModel = (TableModel) e.getNewValue();
756 newModel.addTableModelListener(this);
758 else if (propName.equals("columnModel"))
760 TableColumnModel oldModel = (TableColumnModel) e.getOldValue();
761 oldModel.removeColumnModelListener(this);
762 TableColumnModel newModel = (TableColumnModel) e.getNewValue();
763 newModel.addColumnModelListener(this);
765 else if (propName.equals("selectionModel"))
767 ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
768 oldModel.removeListSelectionListener(this);
769 ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
770 newModel.addListSelectionListener(this);
772 else if (propName.equals("cellEditor"))
774 CellEditor oldEd = (CellEditor) e.getOldValue();
775 oldEd.removeCellEditorListener(this);
776 CellEditor newEd = (CellEditor) e.getNewValue();
777 newEd.addCellEditorListener(this);
781 public int getAccessibleRow(int index)
783 // TODO Auto-generated method stub
784 return 0;
787 public int getAccessibleColumn(int index)
789 // TODO Auto-generated method stub
790 return 0;
793 public int getAccessibleIndex(int r, int c)
795 // TODO Auto-generated method stub
796 return 0;
799 public Accessible getAccessibleCaption()
801 // TODO Auto-generated method stub
802 return null;
805 public void setAccessibleCaption(Accessible caption)
807 // TODO Auto-generated method stub
811 public Accessible getAccessibleSummary()
813 // TODO Auto-generated method stub
814 return null;
817 public void setAccessibleSummary(Accessible summary)
819 // TODO Auto-generated method stub
823 public int getAccessibleRowCount()
825 // TODO Auto-generated method stub
826 return 0;
829 public int getAccessibleColumnCount()
831 // TODO Auto-generated method stub
832 return 0;
835 public Accessible getAccessibleAt(int r, int c)
837 // TODO Auto-generated method stub
838 return null;
841 public int getAccessibleRowExtentAt(int r, int c)
843 // TODO Auto-generated method stub
844 return 0;
847 public int getAccessibleColumnExtentAt(int r, int c)
849 // TODO Auto-generated method stub
850 return 0;
853 public AccessibleTable getAccessibleRowHeader()
855 // TODO Auto-generated method stub
856 return null;
859 public void setAccessibleRowHeader(AccessibleTable header)
861 // TODO Auto-generated method stub
865 public AccessibleTable getAccessibleColumnHeader()
867 // TODO Auto-generated method stub
868 return null;
871 public void setAccessibleColumnHeader(AccessibleTable header)
873 // TODO Auto-generated method stub
877 public Accessible getAccessibleRowDescription(int r)
879 // TODO Auto-generated method stub
880 return null;
883 public void setAccessibleRowDescription(int r, Accessible description)
885 // TODO Auto-generated method stub
889 public Accessible getAccessibleColumnDescription(int c)
891 // TODO Auto-generated method stub
892 return null;
895 public void setAccessibleColumnDescription(int c, Accessible description)
897 // TODO Auto-generated method stub
901 public boolean isAccessibleSelected(int r, int c)
903 // TODO Auto-generated method stub
904 return false;
907 public boolean isAccessibleRowSelected(int r)
909 // TODO Auto-generated method stub
910 return false;
913 public boolean isAccessibleColumnSelected(int c)
915 // TODO Auto-generated method stub
916 return false;
919 public int[] getSelectedAccessibleRows()
921 // TODO Auto-generated method stub
922 return null;
925 public int[] getSelectedAccessibleColumns()
927 // TODO Auto-generated method stub
928 return null;
933 * Handles property changes from the <code>TableColumn</code>s of this
934 * <code>JTable</code>.
936 * More specifically, this triggers a {@link #revalidate()} call if the
937 * preferredWidth of one of the observed columns changes.
939 class TableColumnPropertyChangeHandler implements PropertyChangeListener
942 * Receives notification that a property of the observed TableColumns
943 * has changed.
945 * @param ev the property change event
947 public void propertyChange(PropertyChangeEvent ev)
949 if (ev.getPropertyName().equals("preferredWidth"))
951 JTableHeader header = getTableHeader();
952 TableColumn col = (TableColumn) ev.getSource();
953 header.setResizingColumn(col);
954 doLayout();
955 header.setResizingColumn(null);
961 * A cell renderer for boolean values.
963 private class BooleanCellRenderer
964 extends DefaultTableCellRenderer
968 * The CheckBox that is used for rendering.
970 private JCheckBox checkBox = new JCheckBox();
973 * Returns the component that is used for rendering the value.
975 * @param table the JTable
976 * @param value the value of the object
977 * @param isSelected is the cell selected?
978 * @param hasFocus has the cell the focus?
979 * @param row the row to render
980 * @param column the cell to render
982 * @return this component (the default table cell renderer)
984 public Component getTableCellRendererComponent(JTable table, Object value,
985 boolean isSelected,
986 boolean hasFocus, int row,
987 int column)
989 Boolean boolValue = (Boolean) value;
990 checkBox.setSelected(boolValue.booleanValue());
991 return checkBox;
996 * A cell renderer for Date values.
998 private class DateCellRenderer
999 extends DefaultTableCellRenderer
1002 * Returns the component that is used for rendering the value.
1004 * @param table the JTable
1005 * @param value the value of the object
1006 * @param isSelected is the cell selected?
1007 * @param hasFocus has the cell the focus?
1008 * @param row the row to render
1009 * @param column the cell to render
1011 * @return this component (the default table cell renderer)
1013 public Component getTableCellRendererComponent(JTable table, Object value,
1014 boolean isSelected,
1015 boolean hasFocus, int row,
1016 int column)
1018 super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
1019 row, column);
1020 if (value instanceof Date)
1022 Date dateValue = (Date) value;
1023 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
1024 setText(df.format(dateValue));
1026 return this;
1031 * A cell renderer for Double values.
1033 private class DoubleCellRenderer
1034 extends DefaultTableCellRenderer
1037 * Creates a new instance of NumberCellRenderer.
1039 public DoubleCellRenderer()
1041 setHorizontalAlignment(JLabel.RIGHT);
1045 * Returns the component that is used for rendering the value.
1047 * @param table the JTable
1048 * @param value the value of the object
1049 * @param isSelected is the cell selected?
1050 * @param hasFocus has the cell the focus?
1051 * @param row the row to render
1052 * @param column the cell to render
1054 * @return this component (the default table cell renderer)
1056 public Component getTableCellRendererComponent(JTable table, Object value,
1057 boolean isSelected,
1058 boolean hasFocus, int row,
1059 int column)
1061 super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
1062 row, column);
1063 if (value instanceof Double)
1065 Double doubleValue = (Double) value;
1066 NumberFormat nf = NumberFormat.getInstance();
1067 setText(nf.format(doubleValue.doubleValue()));
1069 return this;
1074 * A cell renderer for Float values.
1076 private class FloatCellRenderer
1077 extends DefaultTableCellRenderer
1080 * Creates a new instance of NumberCellRenderer.
1082 public FloatCellRenderer()
1084 setHorizontalAlignment(JLabel.RIGHT);
1088 * Returns the component that is used for rendering the value.
1090 * @param table the JTable
1091 * @param value the value of the object
1092 * @param isSelected is the cell selected?
1093 * @param hasFocus has the cell the focus?
1094 * @param row the row to render
1095 * @param column the cell to render
1097 * @return this component (the default table cell renderer)
1099 public Component getTableCellRendererComponent(JTable table, Object value,
1100 boolean isSelected,
1101 boolean hasFocus, int row,
1102 int column)
1104 super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
1105 row, column);
1106 if (value instanceof Float)
1108 Float floatValue = (Float) value;
1109 NumberFormat nf = NumberFormat.getInstance();
1110 setText(nf.format(floatValue.floatValue()));
1112 return this;
1117 * A cell renderer for Number values.
1119 private class NumberCellRenderer
1120 extends DefaultTableCellRenderer
1123 * Creates a new instance of NumberCellRenderer.
1125 public NumberCellRenderer()
1127 setHorizontalAlignment(JLabel.RIGHT);
1132 * A cell renderer for Icon values.
1134 private class IconCellRenderer
1135 extends DefaultTableCellRenderer
1138 * Returns the component that is used for rendering the value.
1140 * @param table the JTable
1141 * @param value the value of the object
1142 * @param isSelected is the cell selected?
1143 * @param hasFocus has the cell the focus?
1144 * @param row the row to render
1145 * @param column the cell to render
1147 * @return this component (the default table cell renderer)
1149 public Component getTableCellRendererComponent(JTable table, Object value,
1150 boolean isSelected,
1151 boolean hasFocus, int row,
1152 int column)
1154 super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
1155 row, column);
1156 if (value instanceof Icon)
1158 Icon iconValue = (Icon) value;
1159 setIcon(iconValue);
1161 return this;
1165 private static final long serialVersionUID = 3876025080382781659L;
1169 * When resizing columns, do not automatically change any columns. In this
1170 * case the table should be enclosed in a {@link JScrollPane} in order to
1171 * accomodate cases in which the table size exceeds its visible area.
1173 public static final int AUTO_RESIZE_OFF = 0;
1176 * When resizing column <code>i</code>, automatically change only the
1177 * single column <code>i+1</code> to provide or absorb excess space
1178 * requirements.
1180 public static final int AUTO_RESIZE_NEXT_COLUMN = 1;
1183 * When resizing column <code>i</code> in a table of <code>n</code>
1184 * columns, automatically change all columns in the range <code>[i+1,
1185 * n)</code>, uniformly, to provide or absorb excess space requirements.
1187 public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
1190 * When resizing column <code>i</code> in a table of <code>n</code>
1191 * columns, automatically change all columns in the range <code>[0,
1192 * n)</code> (with the exception of column i) uniformly, to provide or
1193 * absorb excess space requirements.
1195 public static final int AUTO_RESIZE_ALL_COLUMNS = 4;
1198 * When resizing column <code>i</code> in a table of <code>n</code>
1199 * columns, automatically change column <code>n-1</code> (the last column
1200 * in the table) to provide or absorb excess space requirements.
1202 public static final int AUTO_RESIZE_LAST_COLUMN = 3;
1206 * A table mapping {@link java.lang.Class} objects to
1207 * {@link TableCellEditor} objects. This table is consulted by the
1208 * FIXME
1210 protected Hashtable defaultEditorsByColumnClass;
1213 * A table mapping {@link java.lang.Class} objects to
1214 * {@link TableCellEditor} objects. This table is consulted by the
1215 * FIXME
1217 protected Hashtable defaultRenderersByColumnClass;
1220 * The column that is edited, -1 if the table is not edited currently.
1222 protected int editingColumn;
1225 * The row that is edited, -1 if the table is not edited currently.
1227 protected int editingRow;
1230 * The component that is used for editing.
1231 * <code>null</code> if the table is not editing currently.
1234 protected transient Component editorComp;
1238 * Whether or not the table should automatically compute a matching
1239 * {@link TableColumnModel} and assign it to the {@link #columnModel}
1240 * property when the {@link #dataModel} property is changed.
1242 * @see #setModel(TableModel)
1243 * @see #createDefaultColumnsFromModel()
1244 * @see #setColumnModel(TableColumnModel)
1245 * @see #setAutoCreateColumnsFromModel(boolean)
1246 * @see #getAutoCreateColumnsFromModel()
1248 protected boolean autoCreateColumnsFromModel;
1251 * A numeric code specifying the resizing behavior of the table. Must be
1252 * one of {@link #AUTO_RESIZE_ALL_COLUMNS} (the default), {@link
1253 * #AUTO_RESIZE_LAST_COLUMN}, {@link #AUTO_RESIZE_NEXT_COLUMN}, {@link
1254 * #AUTO_RESIZE_SUBSEQUENT_COLUMNS}, or {@link #AUTO_RESIZE_OFF}.
1256 * @see #doLayout()
1257 * @see #setAutoResizeMode(int)
1258 * @see #getAutoResizeMode()
1260 protected int autoResizeMode;
1263 * The height in pixels of any row of the table. All rows in a table are
1264 * of uniform height. This differs from column width, which varies on a
1265 * per-column basis, and is stored in the individual columns of the
1266 * {@link #columnModel}.
1268 * @see #getRowHeight()
1269 * @see #setRowHeight(int)
1270 * @see TableColumn#getWidth()
1271 * @see TableColumn#setWidth(int)
1273 protected int rowHeight;
1276 * The height in pixels of the gap left between any two rows of the table.
1278 * @see #setRowMargin(int)
1279 * @see #getRowHeight()
1280 * @see #getIntercellSpacing()
1281 * @see #setIntercellSpacing(Dimension)
1282 * @see TableColumnModel#getColumnMargin()
1283 * @see TableColumnModel#setColumnMargin(int)
1285 protected int rowMargin;
1288 * Whether or not the table should allow row selection. If the table
1289 * allows both row <em>and</em> column selection, it is said to allow
1290 * "cell selection". Previous versions of the JDK supported cell
1291 * selection as an independent concept, but it is now represented solely
1292 * in terms of simultaneous row and column selection.
1294 * @see TableColumnModel#getColumnSelectionAllowed()
1295 * @see #setRowSelectionAllowed(boolean)
1296 * @see #getRowSelectionAllowed()
1297 * @see #getCellSelectionEnabled()
1298 * @see #setCellSelectionEnabled(boolean)
1300 protected boolean rowSelectionAllowed;
1303 * @deprecated Use {@link #rowSelectionAllowed}, {@link
1304 * #getColumnSelectionAllowed}, or the combined methods {@link
1305 * #getCellSelectionEnabled} and {@link #setCellSelectionEnabled(boolean)}.
1307 protected boolean cellSelectionEnabled;
1310 * The model for data stored in the table. Confusingly, the published API
1311 * requires that this field be called <code>dataModel</code>, despite its
1312 * property name. The table listens to its model as a {@link
1313 * TableModelListener}.
1315 * @see #tableChanged(TableModelEvent)
1316 * @see TableModel#addTableModelListener(TableModelListener)
1318 protected TableModel dataModel;
1321 * <p>A model of various aspects of the columns of the table, <em>not
1322 * including</em> the data stored in them. The {@link TableColumnModel}
1323 * is principally concerned with holding a set of {@link TableColumn}
1324 * objects, each of which describes the display parameters of a column
1325 * and the numeric index of the column from the data model which the
1326 * column is presenting.</p>
1328 * <p>The TableColumnModel also contains a {@link ListSelectionModel} which
1329 * indicates which columns are currently selected. This selection model
1330 * works in combination with the {@link #selectionModel} of the table
1331 * itself to specify a <em>table selection</em>: a combination of row and
1332 * column selections.</p>
1334 * <p>Most application programmers do not need to work with this property
1335 * at all: setting {@link #autoCreateColumnsFromModel} will construct the
1336 * columnModel automatically, and the table acts as a facade for most of
1337 * the interesting properties of the columnModel anyways.</p>
1339 * @see #setColumnModel(TableColumnModel)
1340 * @see #getColumnModel()
1342 protected TableColumnModel columnModel;
1345 * A model of the rows of this table which are currently selected. This
1346 * model is used in combination with the column selection model held as a
1347 * member of the {@link #columnModel} property, to represent the rows and
1348 * columns (or both: cells) of the table which are currently selected.
1350 * @see #rowSelectionAllowed
1351 * @see #setSelectionModel(ListSelectionModel)
1352 * @see #getSelectionModel()
1353 * @see TableColumnModel#getSelectionModel()
1354 * @see ListSelectionModel#addListSelectionListener(ListSelectionListener)
1356 protected ListSelectionModel selectionModel;
1359 * The current cell editor.
1361 protected TableCellEditor cellEditor;
1364 * Whether or not drag-and-drop is enabled on this table.
1366 * @see #setDragEnabled(boolean)
1367 * @see #getDragEnabled()
1369 private boolean dragEnabled;
1372 * The color to paint the grid lines of the table, when either {@link
1373 * #showHorizontalLines} or {@link #showVerticalLines} is set.
1375 * @see #setGridColor(Color)
1376 * @see #getGridColor()
1378 protected Color gridColor;
1381 * The size this table would prefer its viewport assume, if it is
1382 * contained in a {@link JScrollPane}.
1384 * @see #setPreferredScrollableViewportSize(Dimension)
1385 * @see #getPreferredScrollableViewportSize()
1387 protected Dimension preferredViewportSize;
1390 * The color to paint the background of selected cells. Fires a property
1391 * change event with name {@link #SELECTION_BACKGROUND_CHANGED_PROPERTY}
1392 * when its value changes.
1394 * @see #setSelectionBackground(Color)
1395 * @see #getSelectionBackground()
1397 protected Color selectionBackground;
1400 * The name carried in property change events when the {@link
1401 * #selectionBackground} property changes.
1403 private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY = "selectionBackground";
1406 * The color to paint the foreground of selected cells. Fires a property
1407 * change event with name {@link #SELECTION_FOREGROUND_CHANGED_PROPERTY}
1408 * when its value changes.
1410 * @see #setSelectionForeground(Color)
1411 * @see #getSelectionForeground()
1413 protected Color selectionForeground;
1416 * The name carried in property change events when the
1417 * {@link #selectionForeground} property changes.
1419 private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground";
1422 * The showHorizontalLines property.
1424 protected boolean showHorizontalLines;
1427 * The showVerticalLines property.
1429 protected boolean showVerticalLines;
1432 * The tableHeader property.
1434 protected JTableHeader tableHeader;
1437 * The row of the cell being edited.
1439 int rowBeingEdited = -1;
1442 * The column of the cell being edited.
1444 int columnBeingEdited = -1;
1447 * The action listener for the editor's Timer.
1449 Timer editorTimer = new EditorUpdateTimer();
1452 * Stores the old value of a cell before it was edited, in case
1453 * editing is cancelled
1455 Object oldCellValue;
1458 * The property handler for this table's columns.
1460 TableColumnPropertyChangeHandler tableColumnPropertyChangeHandler =
1461 new TableColumnPropertyChangeHandler();
1464 * Creates a new <code>JTable</code> instance.
1466 public JTable ()
1468 this(null, null, null);
1472 * Creates a new <code>JTable</code> instance.
1474 * @param numRows an <code>int</code> value
1475 * @param numColumns an <code>int</code> value
1477 public JTable (int numRows, int numColumns)
1479 this(new DefaultTableModel(numRows, numColumns));
1483 * Creates a new <code>JTable</code> instance.
1485 * @param data an <code>Object[][]</code> value
1486 * @param columnNames an <code>Object[]</code> value
1488 public JTable(Object[][] data, Object[] columnNames)
1490 this(new DefaultTableModel(data, columnNames));
1494 * Creates a new <code>JTable</code> instance.
1496 * @param dm a <code>TableModel</code> value
1498 public JTable (TableModel dm)
1500 this(dm, null, null);
1504 * Creates a new <code>JTable</code> instance.
1506 * @param dm a <code>TableModel</code> value
1507 * @param cm a <code>TableColumnModel</code> value
1509 public JTable (TableModel dm, TableColumnModel cm)
1511 this(dm, cm, null);
1515 * Creates a new <code>JTable</code> instance.
1517 * @param dm a <code>TableModel</code> value
1518 * @param cm a <code>TableColumnModel</code> value
1519 * @param sm a <code>ListSelectionModel</code> value
1521 public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm)
1523 boolean autoCreate = false;
1524 if (cm != null)
1525 setColumnModel(cm);
1526 else
1528 setColumnModel(createDefaultColumnModel());
1529 autoCreate = true;
1531 setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
1532 setModel(dm == null ? createDefaultDataModel() : dm);
1533 setAutoCreateColumnsFromModel(autoCreate);
1534 initializeLocalVars();
1535 // The following four lines properly set the lead selection indices.
1536 // After this, the UI will handle the lead selection indices.
1537 // FIXME: this should probably not be necessary, if the UI is installed
1538 // before the TableModel is set then the UI will handle things on its
1539 // own, but certain variables need to be set before the UI can be installed
1540 // so we must get the correct order for all the method calls in this
1541 // constructor.
1542 selectionModel.setAnchorSelectionIndex(0);
1543 selectionModel.setLeadSelectionIndex(0);
1544 columnModel.getSelectionModel().setAnchorSelectionIndex(0);
1545 columnModel.getSelectionModel().setLeadSelectionIndex(0);
1546 updateUI();
1549 protected void initializeLocalVars()
1551 setTableHeader(createDefaultTableHeader());
1552 if (autoCreateColumnsFromModel)
1553 createDefaultColumnsFromModel();
1554 this.columnModel.addColumnModelListener(this);
1556 this.defaultRenderersByColumnClass = new Hashtable();
1557 createDefaultRenderers();
1559 this.defaultEditorsByColumnClass = new Hashtable();
1560 createDefaultEditors();
1562 this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
1563 this.rowHeight = 16;
1564 this.rowMargin = 1;
1565 this.rowSelectionAllowed = true;
1566 // this.accessibleContext = new AccessibleJTable();
1567 this.cellEditor = null;
1568 // COMPAT: Both Sun and IBM have drag enabled
1569 this.dragEnabled = true;
1570 this.preferredViewportSize = new Dimension(450,400);
1571 this.showHorizontalLines = true;
1572 this.showVerticalLines = true;
1573 this.editingColumn = -1;
1574 this.editingRow = -1;
1575 setIntercellSpacing(new Dimension(1,1));
1579 * Creates a new <code>JTable</code> instance.
1581 * @param data a <code>Vector</code> value
1582 * @param columnNames a <code>Vector</code> value
1584 public JTable(Vector data, Vector columnNames)
1586 this(new DefaultTableModel(data, columnNames));
1590 * The timer that updates the editor component.
1592 private class EditorUpdateTimer
1593 extends Timer
1594 implements ActionListener
1597 * Creates a new EditorUpdateTimer object with a default delay of 0.5 seconds.
1599 public EditorUpdateTimer()
1601 super(500, null);
1602 addActionListener(this);
1606 * Lets the caret blink and repaints the table.
1608 public void actionPerformed(ActionEvent ev)
1610 Caret c = ((JTextField)JTable.this.editorComp).getCaret();
1611 if (c != null)
1612 c.setVisible(!c.isVisible());
1613 JTable.this.repaint();
1617 * Updates the blink delay according to the current caret.
1619 public void update()
1621 stop();
1622 Caret c = ((JTextField)JTable.this.editorComp).getCaret();
1623 if (c != null)
1625 setDelay(c.getBlinkRate());
1626 if (((JTextField)JTable.this.editorComp).isEditable())
1627 start();
1628 else
1629 c.setVisible(false);
1634 public void addColumn(TableColumn column)
1636 if (column.getHeaderValue() == null)
1638 String name = dataModel.getColumnName(column.getModelIndex());
1639 column.setHeaderValue(name);
1642 columnModel.addColumn(column);
1643 column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
1646 protected void createDefaultEditors()
1648 //FIXME: Create the editor object.
1651 protected void createDefaultRenderers()
1653 setDefaultRenderer(Boolean.class, new BooleanCellRenderer());
1654 setDefaultRenderer(Number.class, new NumberCellRenderer());
1655 setDefaultRenderer(Double.class, new DoubleCellRenderer());
1656 setDefaultRenderer(Double.class, new FloatCellRenderer());
1657 setDefaultRenderer(Date.class, new DateCellRenderer());
1658 setDefaultRenderer(Icon.class, new IconCellRenderer());
1662 * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code>
1664 public static JScrollPane createScrollPaneForTable(JTable table)
1666 return new JScrollPane(table);
1669 protected TableColumnModel createDefaultColumnModel()
1671 return new DefaultTableColumnModel();
1674 protected TableModel createDefaultDataModel()
1676 return new DefaultTableModel();
1679 protected ListSelectionModel createDefaultSelectionModel()
1681 return new DefaultListSelectionModel();
1684 protected JTableHeader createDefaultTableHeader()
1686 return new JTableHeader(columnModel);
1689 // listener support
1691 public void columnAdded (TableColumnModelEvent event)
1693 revalidate();
1694 repaint();
1697 public void columnMarginChanged (ChangeEvent event)
1699 revalidate();
1700 repaint();
1703 public void columnMoved (TableColumnModelEvent event)
1705 revalidate();
1706 repaint();
1709 public void columnRemoved (TableColumnModelEvent event)
1711 revalidate();
1712 repaint();
1715 public void columnSelectionChanged (ListSelectionEvent event)
1717 repaint();
1720 public void editingCanceled (ChangeEvent event)
1722 if (rowBeingEdited > -1 && columnBeingEdited > -1)
1724 if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField)
1726 remove ((Component)getValueAt(rowBeingEdited, columnBeingEdited));
1727 setValueAt(oldCellValue, rowBeingEdited, columnBeingEdited);
1729 rowBeingEdited = -1;
1730 columnBeingEdited = -1;
1732 editorTimer.stop();
1733 editorComp = null;
1734 cellEditor = null;
1735 requestFocusInWindow(false);
1736 repaint();
1739 public void editingStopped (ChangeEvent event)
1741 if (rowBeingEdited > -1 && columnBeingEdited > -1)
1743 if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField)
1745 remove((Component)getValueAt(rowBeingEdited, columnBeingEdited));
1746 setValueAt(((JTextField)editorComp).getText(),
1747 rowBeingEdited, columnBeingEdited);
1749 rowBeingEdited = -1;
1750 columnBeingEdited = -1;
1752 editorTimer.stop();
1753 editorComp = null;
1754 cellEditor = null;
1755 requestFocusInWindow(false);
1756 repaint();
1759 public void tableChanged (TableModelEvent event)
1761 // update the column model from the table model if the structure has
1762 // changed and the flag autoCreateColumnsFromModel is set
1763 if ((event.getFirstRow() ==TableModelEvent.HEADER_ROW)
1764 && autoCreateColumnsFromModel)
1766 createDefaultColumnsFromModel();
1768 // If the structure changes, we need to revalidate, since that might
1769 // affect the size parameters of the JTable. Otherwise we only need
1770 // to perform a repaint to update the view.
1771 if (event.getType() == TableModelEvent.INSERT)
1772 revalidate();
1773 else if (event.getType() == TableModelEvent.DELETE)
1775 if (dataModel.getRowCount() == 0)
1776 clearSelection();
1777 revalidate();
1779 repaint();
1782 public void valueChanged (ListSelectionEvent event)
1784 repaint();
1788 * Returns index of the column that contains specified point
1789 * or -1 if this table doesn't contain this point.
1791 * @param point point to identify the column
1792 * @return index of the column that contains specified point or
1793 * -1 if this table doesn't contain this point.
1795 public int columnAtPoint(Point point)
1797 if (point != null)
1799 int x0 = getLocation().x;
1800 int ncols = getColumnCount();
1801 Dimension gap = getIntercellSpacing();
1802 TableColumnModel cols = getColumnModel();
1803 int x = point.x;
1805 for (int i = 0; i < ncols; ++i)
1807 int width = cols.getColumn(i).getWidth()
1808 + (gap == null ? 0 : gap.width);
1809 if (0 <= x && x < width)
1810 return i;
1811 x -= width;
1814 return -1;
1818 * Returns index of the row that contains specified point or
1819 * -1 if this table doesn't contain this point.
1821 * @param point point to identify the row
1822 * @return index of the row that contains specified point or
1823 * -1 if this table doesn't contain this point.
1825 public int rowAtPoint(Point point)
1827 if (point != null)
1829 int y0 = getLocation().y;
1830 int nrows = getRowCount();
1831 int height = getRowHeight();
1832 int y = point.y;
1834 for (int i = 0; i < nrows; ++i)
1836 if (0 <= y && y < height)
1837 return i;
1838 y -= height;
1841 return -1;
1844 /**
1845 * Calculate the visible rectangle for a particular row and column. The
1846 * row and column are specified in visual terms; the column may not match
1847 * the {@link #dataModel} column.
1849 * @param row the visible row to get the cell rectangle of
1851 * @param column the visible column to get the cell rectangle of, which may
1852 * differ from the {@link #dataModel} column
1854 * @param includeSpacing whether or not to include the cell margins in the
1855 * resulting cell. If <code>false</code>, the result will only contain the
1856 * inner area of the target cell, not including its margins.
1858 * @return a rectangle enclosing the specified cell
1860 public Rectangle getCellRect(int row,
1861 int column,
1862 boolean includeSpacing)
1864 int height = getRowHeight(row);
1865 int width = columnModel.getColumn(column).getWidth();
1866 int x_gap = columnModel.getColumnMargin();
1867 int y_gap = rowMargin;
1869 column = Math.max(0, Math.min(column, getColumnCount() - 1));
1870 row = Math.max(0, Math.min(row, getRowCount() - 1));
1872 int x = 0;
1873 int y = (height + y_gap) * row;
1875 for (int i = 0; i < column; ++i)
1876 x += columnModel.getColumn(i).getWidth();
1878 if (includeSpacing)
1879 return new Rectangle(x, y, width, height);
1880 else
1881 return new Rectangle(x, y, width - x_gap, height - y_gap);
1884 public void clearSelection()
1886 selectionModel.clearSelection();
1887 getColumnModel().getSelectionModel().clearSelection();
1891 * Get the value of the selectedRow property by delegation to
1892 * the {@link ListSelectionModel#getMinSelectionIndex} method of the
1893 * {@link #selectionModel} field.
1895 * @return The current value of the selectedRow property
1897 public int getSelectedRow ()
1899 return selectionModel.getMinSelectionIndex();
1903 * Get the value of the {@link #selectionModel} property.
1905 * @return The current value of the property
1907 public ListSelectionModel getSelectionModel()
1909 //Neither Sun nor IBM returns null if rowSelection not allowed
1910 return selectionModel;
1913 public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
1915 if (orientation == SwingConstants.VERTICAL)
1916 return visibleRect.height * direction;
1917 else
1918 return visibleRect.width * direction;
1922 * Get the value of the <code>scrollableTracksViewportHeight</code> property.
1924 * @return The constant value <code>false</code>
1926 public boolean getScrollableTracksViewportHeight()
1928 return false;
1932 * Get the value of the <code>scrollableTracksViewportWidth</code> property.
1934 * @return <code>true</code> unless the {@link #autoResizeMode} property is
1935 * <code>AUTO_RESIZE_OFF</code>
1937 public boolean getScrollableTracksViewportWidth()
1939 if (autoResizeMode == AUTO_RESIZE_OFF)
1940 return false;
1941 else
1942 return true;
1945 public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
1947 // FIXME: I don't exactly know what sun does here. in both cases they
1948 // pick values which do *not* simply expose the next cell in a given
1949 // scroll direction.
1951 if (orientation == SwingConstants.VERTICAL)
1952 return direction * rowHeight;
1953 else
1955 int sum = 0;
1956 for (int i = 0; i < getColumnCount(); ++i)
1957 sum += columnModel.getColumn(0).getWidth();
1958 int inc = getColumnCount() == 0 ? 10 : sum / getColumnCount();
1959 return direction * inc;
1964 public TableCellEditor getCellEditor(int row, int column)
1966 TableCellEditor editor = columnModel.getColumn(column).getCellEditor();
1968 if (editor == null)
1969 editor = getDefaultEditor(dataModel.getColumnClass(column));
1971 return editor;
1974 public TableCellEditor getDefaultEditor(Class columnClass)
1976 if (defaultEditorsByColumnClass.containsKey(columnClass))
1977 return (TableCellEditor) defaultEditorsByColumnClass.get(columnClass);
1978 else
1980 // FIXME: We have at least an editor for Object.class in our defaults.
1981 TableCellEditor r = new DefaultCellEditor(new JTextField());
1982 defaultEditorsByColumnClass.put(columnClass, r);
1983 return r;
1989 public TableCellRenderer getCellRenderer(int row, int column)
1991 TableCellRenderer renderer =
1992 columnModel.getColumn(column).getCellRenderer();
1994 if (renderer == null)
1995 renderer = getDefaultRenderer(dataModel.getColumnClass(column));
1997 return renderer;
2000 public void setDefaultRenderer(Class columnClass, TableCellRenderer rend)
2002 defaultRenderersByColumnClass.put(columnClass, rend);
2005 public TableCellRenderer getDefaultRenderer(Class columnClass)
2007 if (defaultRenderersByColumnClass.containsKey(columnClass))
2008 return (TableCellRenderer) defaultRenderersByColumnClass.get(columnClass);
2009 else
2011 TableCellRenderer r = new DefaultTableCellRenderer();
2012 defaultRenderersByColumnClass.put(columnClass, r);
2013 return r;
2017 public int convertColumnIndexToModel(int vc)
2019 if (vc < 0)
2020 return vc;
2021 else
2022 return columnModel.getColumn(vc).getModelIndex();
2025 public int convertColumnIndexToView(int mc)
2027 if (mc < 0)
2028 return mc;
2029 int ncols = getColumnCount();
2030 for (int vc = 0; vc < ncols; ++vc)
2032 if (columnModel.getColumn(vc).getModelIndex() == mc)
2033 return vc;
2035 return -1;
2038 public Component prepareRenderer(TableCellRenderer renderer,
2039 int row,
2040 int column)
2042 boolean rsa = getRowSelectionAllowed();
2043 boolean csa = getColumnSelectionAllowed();
2044 boolean rs = rsa ? getSelectionModel().isSelectedIndex(row) : false;
2045 boolean cs = csa ? columnModel.getSelectionModel().isSelectedIndex(column) : false;
2046 boolean isSelected = ((rsa && csa && rs && cs)
2047 || (rsa && !csa && rs)
2048 || (!rsa && csa && cs));
2050 return renderer.getTableCellRendererComponent(this,
2051 dataModel.getValueAt(row,
2052 convertColumnIndexToModel(column)),
2053 isSelected,
2054 false, // hasFocus
2055 row, column);
2060 * Get the value of the {@link #autoCreateColumnsFromModel} property.
2062 * @return The current value of the property
2064 public boolean getAutoCreateColumnsFromModel()
2066 return autoCreateColumnsFromModel;
2070 * Get the value of the {@link #autoResizeMode} property.
2072 * @return The current value of the property
2074 public int getAutoResizeMode()
2076 return autoResizeMode;
2080 * Get the value of the {@link #rowHeight} property.
2082 * @return The current value of the property
2084 public int getRowHeight()
2086 return rowHeight;
2090 * Get the height of the specified row.
2092 * @param row the row whose height to return
2094 public int getRowHeight(int row)
2096 // FIXME: return the height of the specified row
2097 // which may be different from the general rowHeight
2098 return rowHeight;
2103 * Get the value of the {@link #rowMargin} property.
2105 * @return The current value of the property
2107 public int getRowMargin()
2109 return rowMargin;
2113 * Get the value of the {@link #rowSelectionAllowed} property.
2115 * @return The current value of the property
2117 public boolean getRowSelectionAllowed()
2119 return rowSelectionAllowed;
2123 * Get the value of the {@link #cellSelectionEnabled} property.
2125 * @return The current value of the property
2127 public boolean getCellSelectionEnabled()
2129 return getColumnSelectionAllowed() && getRowSelectionAllowed();
2133 * Get the value of the {@link #dataModel} property.
2135 * @return The current value of the property
2137 public TableModel getModel()
2139 return dataModel;
2143 * Get the value of the <code>columnCount</code> property by
2144 * delegation to the @{link #columnModel} field.
2146 * @return The current value of the columnCount property
2148 public int getColumnCount()
2150 return columnModel.getColumnCount();
2154 * Get the value of the <code>rowCount</code> property by
2155 * delegation to the @{link #dataModel} field.
2157 * @return The current value of the rowCount property
2159 public int getRowCount()
2161 return dataModel.getRowCount();
2165 * Get the value of the {@link #columnModel} property.
2167 * @return The current value of the property
2169 public TableColumnModel getColumnModel()
2171 return columnModel;
2175 * Get the value of the <code>selectedColumn</code> property by
2176 * delegation to the @{link #columnModel} field.
2178 * @return The current value of the selectedColumn property
2180 public int getSelectedColumn()
2182 return columnModel.getSelectionModel().getMinSelectionIndex();
2185 private static int countSelections(ListSelectionModel lsm)
2187 int lo = lsm.getMinSelectionIndex();
2188 int hi = lsm.getMaxSelectionIndex();
2189 int sum = 0;
2190 if (lo != -1 && hi != -1)
2192 switch (lsm.getSelectionMode())
2194 case ListSelectionModel.SINGLE_SELECTION:
2195 sum = 1;
2196 break;
2198 case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
2199 sum = hi - lo + 1;
2200 break;
2202 case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:
2203 for (int i = lo; i <= hi; ++i)
2204 if (lsm.isSelectedIndex(i))
2205 ++sum;
2206 break;
2209 return sum;
2212 private static int[] getSelections(ListSelectionModel lsm)
2214 int sz = countSelections(lsm);
2215 int [] ret = new int[sz];
2217 int lo = lsm.getMinSelectionIndex();
2218 int hi = lsm.getMaxSelectionIndex();
2219 int j = 0;
2220 java.util.ArrayList ls = new java.util.ArrayList();
2221 if (lo != -1 && hi != -1)
2223 switch (lsm.getSelectionMode())
2225 case ListSelectionModel.SINGLE_SELECTION:
2226 ret[0] = lo;
2227 break;
2229 case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
2230 for (int i = lo; i <= hi; ++i)
2231 ret[j++] = i;
2232 break;
2234 case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:
2235 for (int i = lo; i <= hi; ++i)
2236 if (lsm.isSelectedIndex(i))
2237 ret[j++] = i;
2238 break;
2241 return ret;
2245 * Get the value of the <code>selectedColumnCount</code> property by
2246 * delegation to the @{link #columnModel} field.
2248 * @return The current value of the selectedColumnCount property
2250 public int getSelectedColumnCount()
2252 return countSelections(columnModel.getSelectionModel());
2256 * Get the value of the <code>selectedColumns</code> property by
2257 * delegation to the @{link #columnModel} field.
2259 * @return The current value of the selectedColumns property
2261 public int[] getSelectedColumns()
2263 return getSelections(columnModel.getSelectionModel());
2267 * Get the value of the <code>columnSelectionAllowed</code> property.
2269 * @return The current value of the columnSelectionAllowed property
2271 public boolean getColumnSelectionAllowed()
2273 return getColumnModel().getColumnSelectionAllowed();
2277 * Get the value of the <code>selectedRowCount</code> property by
2278 * delegation to the @{link #selectionModel} field.
2280 * @return The current value of the selectedRowCount property
2282 public int getSelectedRowCount()
2284 return countSelections(selectionModel);
2288 * Get the value of the <code>selectedRows</code> property by
2289 * delegation to the @{link #selectionModel} field.
2291 * @return The current value of the selectedRows property
2293 public int[] getSelectedRows()
2295 return getSelections(selectionModel);
2299 * Get the value of the {@link #accessibleContext} property.
2301 * @return The current value of the property
2303 public AccessibleContext getAccessibleContext()
2305 return accessibleContext;
2309 * Get the value of the {@link #cellEditor} property.
2311 * @return The current value of the property
2313 public TableCellEditor getCellEditor()
2315 return cellEditor;
2319 * Get the value of the {@link #dragEnabled} property.
2321 * @return The current value of the property
2323 public boolean getDragEnabled()
2325 return dragEnabled;
2329 * Get the value of the {@link #gridColor} property.
2331 * @return The current value of the property
2333 public Color getGridColor()
2335 return gridColor;
2339 * Get the value of the <code>intercellSpacing</code> property.
2341 * @return The current value of the property
2343 public Dimension getIntercellSpacing()
2345 return new Dimension(columnModel.getColumnMargin(), rowMargin);
2349 * Get the value of the {@link #preferredViewportSize} property.
2351 * @return The current value of the property
2353 public Dimension getPreferredScrollableViewportSize()
2355 return preferredViewportSize;
2359 * Get the value of the {@link #selectionBackground} property.
2361 * @return The current value of the property
2363 public Color getSelectionBackground()
2365 return selectionBackground;
2369 * Get the value of the {@link #selectionForeground} property.
2371 * @return The current value of the property
2373 public Color getSelectionForeground()
2375 return selectionForeground;
2379 * Get the value of the {@link #showHorizontalLines} property.
2381 * @return The current value of the property
2383 public boolean getShowHorizontalLines()
2385 return showHorizontalLines;
2389 * Get the value of the {@link #showVerticalLines} property.
2391 * @return The current value of the property
2393 public boolean getShowVerticalLines()
2395 return showVerticalLines;
2399 * Get the value of the {@link #tableHeader} property.
2401 * @return The current value of the property
2403 public JTableHeader getTableHeader()
2405 return tableHeader;
2409 * Removes specified column from displayable columns of this table.
2411 * @param column column to removed
2413 public void removeColumn(TableColumn column)
2415 columnModel.removeColumn(column);
2419 * Moves column at the specified index to new given location.
2421 * @param column index of the column to move
2422 * @param targetColumn index specifying new location of the column
2424 public void moveColumn(int column,int targetColumn)
2426 columnModel.moveColumn(column, targetColumn);
2430 * Set the value of the {@link #autoCreateColumnsFromModel} flag. If the
2431 * flag changes from <code>false</code> to <code>true</code>, the
2432 * {@link #createDefaultColumnsFromModel()} method is called.
2434 * @param autoCreate the new value of the flag.
2436 public void setAutoCreateColumnsFromModel(boolean autoCreate)
2438 if (autoCreateColumnsFromModel != autoCreate)
2440 autoCreateColumnsFromModel = autoCreate;
2441 if (autoCreate)
2442 createDefaultColumnsFromModel();
2447 * Set the value of the {@link #autoResizeMode} property.
2449 * @param a The new value of the autoResizeMode property
2451 public void setAutoResizeMode(int a)
2453 autoResizeMode = a;
2454 revalidate();
2455 repaint();
2459 * Set the value of the {@link #rowHeight} property.
2461 * @param r The new value of the rowHeight property
2463 public void setRowHeight(int r)
2465 if (r < 1)
2466 throw new IllegalArgumentException();
2468 rowHeight = r;
2469 revalidate();
2470 repaint();
2474 * Sets the value of the rowHeight property for the specified
2475 * row.
2477 * @param rh is the new rowHeight
2478 * @param row is the row to change the rowHeight of
2480 public void setRowHeight(int row, int rh)
2482 setRowHeight(rh);
2483 // FIXME: not implemented
2487 * Set the value of the {@link #rowMargin} property.
2489 * @param r The new value of the rowMargin property
2491 public void setRowMargin(int r)
2493 rowMargin = r;
2494 revalidate();
2495 repaint();
2499 * Set the value of the {@link #rowSelectionAllowed} property.
2501 * @param r The new value of the rowSelectionAllowed property
2503 public void setRowSelectionAllowed(boolean r)
2505 rowSelectionAllowed = r;
2506 repaint();
2510 * Set the value of the {@link #cellSelectionEnabled} property.
2512 * @param c The new value of the cellSelectionEnabled property
2514 public void setCellSelectionEnabled(boolean c)
2516 setColumnSelectionAllowed(c);
2517 setRowSelectionAllowed(c);
2518 // for backward-compatibility sake:
2519 cellSelectionEnabled = true;
2523 * <p>Set the value of the {@link #dataModel} property.</p>
2525 * <p>Unregister <code>this</code> as a {@link TableModelListener} from
2526 * previous {@link #dataModel} and register it with new parameter
2527 * <code>m</code>.</p>
2529 * @param m The new value of the model property
2531 public void setModel(TableModel m)
2533 // Throw exception is m is null.
2534 if (m == null)
2535 throw new IllegalArgumentException();
2537 // Don't do anything if setting the current model again.
2538 if (dataModel == m)
2539 return;
2541 TableModel oldModel = dataModel;
2543 // Remove table as TableModelListener from old model.
2544 if (dataModel != null)
2545 dataModel.removeTableModelListener(this);
2547 if (m != null)
2549 // Set property.
2550 dataModel = m;
2552 // Add table as TableModelListener to new model.
2553 dataModel.addTableModelListener(this);
2555 // Automatically create columns.
2556 if (autoCreateColumnsFromModel)
2557 createDefaultColumnsFromModel();
2560 // This property is bound, so we fire a property change event.
2561 firePropertyChange("model", oldModel, dataModel);
2563 // Repaint table.
2564 revalidate();
2565 repaint();
2569 * <p>Set the value of the {@link #columnModel} property.</p>
2571 * <p>Unregister <code>this</code> as a {@link TableColumnModelListener}
2572 * from previous {@link #columnModel} and register it with new parameter
2573 * <code>c</code>.</p>
2575 * @param c The new value of the columnModel property
2577 public void setColumnModel(TableColumnModel c)
2579 if (c == null)
2580 throw new IllegalArgumentException();
2581 TableColumnModel tmp = columnModel;
2582 if (tmp != null)
2583 tmp.removeColumnModelListener(this);
2584 if (c != null)
2585 c.addColumnModelListener(this);
2586 columnModel = c;
2587 if (dataModel != null && columnModel != null)
2589 int ncols = getColumnCount();
2590 for (int i = 0; i < ncols; ++i)
2591 columnModel.getColumn(i).setHeaderValue(dataModel.getColumnName(i));
2594 // according to Sun's spec we also have to set the tableHeader's
2595 // column model here
2596 if (tableHeader != null)
2597 tableHeader.setColumnModel(c);
2599 revalidate();
2600 repaint();
2604 * Set the value of the <code>columnSelectionAllowed</code> property.
2606 * @param c The new value of the property
2608 public void setColumnSelectionAllowed(boolean c)
2610 getColumnModel().setColumnSelectionAllowed(c);
2611 repaint();
2615 * <p>Set the value of the {@link #selectionModel} property.</p>
2617 * <p>Unregister <code>this</code> as a {@link ListSelectionListener}
2618 * from previous {@link #selectionModel} and register it with new
2619 * parameter <code>s</code>.</p>
2621 * @param s The new value of the selectionModel property
2623 public void setSelectionModel(ListSelectionModel s)
2625 if (s == null)
2626 throw new IllegalArgumentException();
2627 ListSelectionModel tmp = selectionModel;
2628 if (tmp != null)
2629 tmp.removeListSelectionListener(this);
2630 if (s != null)
2631 s.addListSelectionListener(this);
2632 selectionModel = s;
2636 * Set the value of the <code>selectionMode</code> property by
2637 * delegation to the {@link #selectionModel} field. The same selection
2638 * mode is set for row and column selection models.
2640 * @param s The new value of the property
2642 public void setSelectionMode(int s)
2644 selectionModel.setSelectionMode(s);
2645 columnModel.getSelectionModel().setSelectionMode(s);
2647 repaint();
2651 * <p>Set the value of the {@link #cellEditor} property.</p>
2653 * <p>Unregister <code>this</code> as a {@link CellEditorListener} from
2654 * previous {@link #cellEditor} and register it with new parameter
2655 * <code>c</code>.</p>
2657 * @param c The new value of the cellEditor property
2659 public void setCellEditor(TableCellEditor c)
2661 TableCellEditor tmp = cellEditor;
2662 if (tmp != null)
2663 tmp.removeCellEditorListener(this);
2664 if (c != null)
2665 c.addCellEditorListener(this);
2666 cellEditor = c;
2670 * Set the value of the {@link #dragEnabled} property.
2672 * @param d The new value of the dragEnabled property
2674 public void setDragEnabled(boolean d)
2676 dragEnabled = d;
2680 * Set the value of the {@link #gridColor} property.
2682 * @param g The new value of the gridColor property
2684 public void setGridColor(Color g)
2686 gridColor = g;
2687 repaint();
2691 * Set the value of the <code>intercellSpacing</code> property.
2693 * @param i The new value of the intercellSpacing property
2695 public void setIntercellSpacing(Dimension i)
2697 rowMargin = i.height;
2698 columnModel.setColumnMargin(i.width);
2699 repaint();
2703 * Set the value of the {@link #preferredViewportSize} property.
2705 * @param p The new value of the preferredViewportSize property
2707 public void setPreferredScrollableViewportSize(Dimension p)
2709 preferredViewportSize = p;
2710 revalidate();
2711 repaint();
2715 * <p>Set the value of the {@link #selectionBackground} property.</p>
2717 * <p>Fire a PropertyChangeEvent with name {@link
2718 * #SELECTION_BACKGROUND_CHANGED_PROPERTY} to registered listeners, if
2719 * selectionBackground changed.</p>
2721 * @param s The new value of the selectionBackground property
2723 public void setSelectionBackground(Color s)
2725 Color tmp = selectionBackground;
2726 selectionBackground = s;
2727 if (((tmp == null && s != null)
2728 || (s == null && tmp != null)
2729 || (tmp != null && s != null && !tmp.equals(s))))
2730 firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY, tmp, s);
2731 repaint();
2735 * <p>Set the value of the {@link #selectionForeground} property.</p>
2737 * <p>Fire a PropertyChangeEvent with name {@link
2738 * #SELECTION_FOREGROUND_CHANGED_PROPERTY} to registered listeners, if
2739 * selectionForeground changed.</p>
2741 * @param s The new value of the selectionForeground property
2743 public void setSelectionForeground(Color s)
2745 Color tmp = selectionForeground;
2746 selectionForeground = s;
2747 if (((tmp == null && s != null)
2748 || (s == null && tmp != null)
2749 || (tmp != null && s != null && !tmp.equals(s))))
2750 firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY, tmp, s);
2751 repaint();
2755 * Set the value of the <code>showGrid</code> property.
2757 * @param s The new value of the showGrid property
2759 public void setShowGrid(boolean s)
2761 setShowVerticalLines(s);
2762 setShowHorizontalLines(s);
2766 * Set the value of the {@link #showHorizontalLines} property.
2768 * @param s The new value of the showHorizontalLines property
2770 public void setShowHorizontalLines(boolean s)
2772 showHorizontalLines = s;
2773 repaint();
2777 * Set the value of the {@link #showVerticalLines} property.
2779 * @param s The new value of the showVerticalLines property
2781 public void setShowVerticalLines(boolean s)
2783 showVerticalLines = s;
2784 repaint();
2788 * Set the value of the {@link #tableHeader} property.
2790 * @param t The new value of the tableHeader property
2792 public void setTableHeader(JTableHeader t)
2794 if (tableHeader != null)
2795 tableHeader.setTable(null);
2796 tableHeader = t;
2797 if (tableHeader != null)
2798 tableHeader.setTable(this);
2799 revalidate();
2800 repaint();
2803 protected void configureEnclosingScrollPane()
2805 JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
2806 if (jsp != null && tableHeader != null)
2808 jsp.setColumnHeaderView(tableHeader);
2812 protected void unconfigureEnclosingScrollPane()
2814 JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
2815 if (jsp != null)
2817 jsp.setColumnHeaderView(null);
2822 public void addNotify()
2824 super.addNotify();
2825 configureEnclosingScrollPane();
2828 public void removeNotify()
2830 super.addNotify();
2831 unconfigureEnclosingScrollPane();
2836 * This distributes the superfluous width in a table evenly on its columns.
2838 * The implementation used here is different to that one described in
2839 * the JavaDocs. It is much simpler, and seems to work very well.
2841 * TODO: correctly implement the algorithm described in the JavaDoc
2843 private void distributeSpill(TableColumn[] cols, int spill)
2845 int average = spill / cols.length;
2846 for (int i = 0; i < cols.length; i++)
2848 if (cols[i] != null)
2849 cols[i].setWidth(cols[i].getWidth() + average);
2853 public void doLayout()
2855 TableColumn resizingColumn = null;
2857 int ncols = getColumnCount();
2858 if (ncols < 1)
2859 return;
2861 int[] pref = new int[ncols];
2862 int prefSum = 0;
2863 int rCol = -1;
2865 if (tableHeader != null)
2866 resizingColumn = tableHeader.getResizingColumn();
2868 for (int i = 0; i < ncols; ++i)
2870 TableColumn col = columnModel.getColumn(i);
2871 int p = col.getWidth();
2872 pref[i] = p;
2873 prefSum += p;
2874 if (resizingColumn == col)
2875 rCol = i;
2878 int spill = getWidth() - prefSum;
2880 if (resizingColumn != null)
2882 TableColumn col;
2883 TableColumn [] cols;
2885 switch (getAutoResizeMode())
2887 case AUTO_RESIZE_LAST_COLUMN:
2888 col = columnModel.getColumn(ncols-1);
2889 col.setWidth(col.getPreferredWidth() + spill);
2890 break;
2892 case AUTO_RESIZE_NEXT_COLUMN:
2893 col = columnModel.getColumn(ncols-1);
2894 col.setWidth(col.getPreferredWidth() + spill);
2895 break;
2897 case AUTO_RESIZE_ALL_COLUMNS:
2898 cols = new TableColumn[ncols];
2899 for (int i = 0; i < ncols; ++i)
2900 cols[i] = columnModel.getColumn(i);
2901 distributeSpill(cols, spill);
2902 break;
2904 case AUTO_RESIZE_SUBSEQUENT_COLUMNS:
2905 cols = new TableColumn[ncols];
2906 for (int i = rCol; i < ncols; ++i)
2907 cols[i] = columnModel.getColumn(i);
2908 distributeSpill(cols, spill);
2909 break;
2911 case AUTO_RESIZE_OFF:
2912 default:
2913 int prefWidth = resizingColumn.getPreferredWidth();
2914 resizingColumn.setWidth(prefWidth);
2917 else
2919 TableColumn [] cols = new TableColumn[ncols];
2920 for (int i = 0; i < ncols; ++i)
2921 cols[i] = columnModel.getColumn(i);
2922 distributeSpill(cols, spill);
2927 * @deprecated Replaced by <code>doLayout()</code>
2929 public void sizeColumnsToFit(boolean lastColumnOnly)
2931 doLayout();
2935 * Obsolete since JDK 1.4. Please use <code>doLayout()</code>.
2937 public void sizeColumnsToFit(int resizingColumn)
2939 doLayout();
2942 public String getUIClassID()
2944 return "TableUI";
2948 * This method returns the table's UI delegate.
2950 * @return The table's UI delegate.
2952 public TableUI getUI()
2954 return (TableUI) ui;
2958 * This method sets the table's UI delegate.
2960 * @param ui The table's UI delegate.
2962 public void setUI(TableUI ui)
2964 super.setUI(ui);
2967 public void updateUI()
2969 setUI((TableUI) UIManager.getUI(this));
2970 revalidate();
2971 repaint();
2974 public Class getColumnClass(int column)
2976 return dataModel.getColumnClass(column);
2979 public String getColumnName(int column)
2981 int modelColumn = columnModel.getColumn(column).getModelIndex();
2982 return dataModel.getColumnName(modelColumn);
2985 public int getEditingColumn()
2987 return editingColumn;
2990 public void setEditingColumn(int column)
2992 editingColumn = column;
2995 public int getEditingRow()
2997 return editingRow;
3000 public void setEditingRow(int column)
3002 editingRow = column;
3005 public Component getEditorComponent()
3007 return editorComp;
3010 public boolean isEditing()
3012 return editorComp != null;
3015 public void setDefaultEditor(Class columnClass, TableCellEditor editor)
3017 if (editor != null)
3018 defaultEditorsByColumnClass.put(columnClass, editor);
3019 else
3020 defaultEditorsByColumnClass.remove(columnClass);
3023 public void addColumnSelectionInterval(int index0, int index1)
3025 if ((index0 < 0 || index0 > (getColumnCount()-1)
3026 || index1 < 0 || index1 > (getColumnCount()-1)))
3027 throw new IllegalArgumentException("Column index out of range.");
3029 getColumnModel().getSelectionModel().addSelectionInterval(index0, index1);
3032 public void addRowSelectionInterval(int index0, int index1)
3034 if ((index0 < 0 || index0 > (getRowCount()-1)
3035 || index1 < 0 || index1 > (getRowCount()-1)))
3036 throw new IllegalArgumentException("Row index out of range.");
3038 getSelectionModel().addSelectionInterval(index0, index1);
3041 public void setColumnSelectionInterval(int index0, int index1)
3043 if ((index0 < 0 || index0 > (getColumnCount()-1)
3044 || index1 < 0 || index1 > (getColumnCount()-1)))
3045 throw new IllegalArgumentException("Column index out of range.");
3047 getColumnModel().getSelectionModel().setSelectionInterval(index0, index1);
3050 public void setRowSelectionInterval(int index0, int index1)
3052 if ((index0 < 0 || index0 > (getRowCount()-1)
3053 || index1 < 0 || index1 > (getRowCount()-1)))
3054 throw new IllegalArgumentException("Row index out of range.");
3056 getSelectionModel().setSelectionInterval(index0, index1);
3059 public void removeColumnSelectionInterval(int index0, int index1)
3061 if ((index0 < 0 || index0 > (getColumnCount()-1)
3062 || index1 < 0 || index1 > (getColumnCount()-1)))
3063 throw new IllegalArgumentException("Column index out of range.");
3065 getColumnModel().getSelectionModel().removeSelectionInterval(index0, index1);
3068 public void removeRowSelectionInterval(int index0, int index1)
3070 if ((index0 < 0 || index0 > (getRowCount()-1)
3071 || index1 < 0 || index1 > (getRowCount()-1)))
3072 throw new IllegalArgumentException("Row index out of range.");
3074 getSelectionModel().removeSelectionInterval(index0, index1);
3077 public boolean isColumnSelected(int column)
3079 return getColumnModel().getSelectionModel().isSelectedIndex(column);
3082 public boolean isRowSelected(int row)
3084 return getSelectionModel().isSelectedIndex(row);
3087 public boolean isCellSelected(int row, int column)
3089 return isRowSelected(row) && isColumnSelected(column);
3092 public void selectAll()
3094 // rowLead and colLead store the current lead selection indices
3095 int rowLead = selectionModel.getLeadSelectionIndex();
3096 int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex();
3097 // the following calls to setSelectionInterval change the lead selection
3098 // indices
3099 setColumnSelectionInterval(0, getColumnCount() - 1);
3100 setRowSelectionInterval(0, getRowCount() - 1);
3101 // the following addSelectionInterval calls restore the lead selection
3102 // indices to their previous values
3103 addColumnSelectionInterval(colLead,colLead);
3104 addRowSelectionInterval(rowLead, rowLead);
3107 public Object getValueAt(int row, int column)
3109 return dataModel.getValueAt(row, convertColumnIndexToModel(column));
3112 public void setValueAt(Object value, int row, int column)
3114 if (!isCellEditable(row, column))
3115 return;
3117 if (value instanceof Component)
3118 add((Component)value);
3119 dataModel.setValueAt(value, row, convertColumnIndexToModel(column));
3122 public TableColumn getColumn(Object identifier)
3124 return columnModel.getColumn(columnModel.getColumnIndex(identifier));
3128 * Returns <code>true</code> if the specified cell is editable, and
3129 * <code>false</code> otherwise.
3131 * @param row the row index.
3132 * @param column the column index.
3134 * @return A boolean.
3136 public boolean isCellEditable(int row, int column)
3138 return dataModel.isCellEditable(row, convertColumnIndexToModel(column));
3142 * Clears any existing columns from the <code>JTable</code>'s
3143 * {@link TableColumnModel} and creates new columns to match the values in
3144 * the data ({@link TableModel}) used by the table.
3146 * @see #setAutoCreateColumnsFromModel(boolean)
3148 public void createDefaultColumnsFromModel()
3150 assert columnModel != null : "The columnModel must not be null.";
3152 // remove existing columns
3153 int columnIndex = columnModel.getColumnCount() - 1;
3154 while (columnIndex >= 0)
3156 columnModel.removeColumn(columnModel.getColumn(columnIndex));
3157 columnIndex--;
3160 // add new columns to match the TableModel
3161 int columnCount = dataModel.getColumnCount();
3162 for (int c = 0; c < columnCount; c++)
3164 TableColumn column = new TableColumn(c);
3165 column.setIdentifier(dataModel.getColumnName(c));
3166 column.setHeaderValue(dataModel.getColumnName(c));
3167 columnModel.addColumn(column);
3168 column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
3172 public void changeSelection (int rowIndex, int columnIndex, boolean toggle, boolean extend)
3174 if (toggle && extend)
3176 // Leave the selection state as is, but move the anchor
3177 // index to the specified location
3178 selectionModel.setAnchorSelectionIndex(rowIndex);
3179 getColumnModel().getSelectionModel().setAnchorSelectionIndex(columnIndex);
3181 else if (toggle)
3183 // Toggle the state of the specified cell
3184 if (isCellSelected(rowIndex,columnIndex))
3186 selectionModel.removeSelectionInterval(rowIndex,rowIndex);
3187 getColumnModel().getSelectionModel().removeSelectionInterval(columnIndex,columnIndex);
3189 else
3191 selectionModel.addSelectionInterval(rowIndex,rowIndex);
3192 getColumnModel().getSelectionModel().addSelectionInterval(columnIndex,columnIndex);
3195 else if (extend)
3197 // Extend the previous selection from the anchor to the
3198 // specified cell, clearing all other selections
3199 selectionModel.setLeadSelectionIndex(rowIndex);
3200 getColumnModel().getSelectionModel().setLeadSelectionIndex(columnIndex);
3202 else
3204 // Clear the previous selection and ensure the new cell
3205 // is selected
3206 selectionModel.clearSelection();
3207 selectionModel.setSelectionInterval(rowIndex,rowIndex);
3208 getColumnModel().getSelectionModel().clearSelection();
3209 getColumnModel().getSelectionModel().setSelectionInterval(columnIndex, columnIndex);
3216 * Programmatically starts editing the specified cell.
3218 * @param row the row of the cell to edit.
3219 * @param column the column of the cell to edit.
3221 public boolean editCellAt (int row, int column)
3223 oldCellValue = getValueAt(row, column);
3224 setCellEditor(getCellEditor(row, column));
3225 editorComp = prepareEditor(cellEditor, row, column);
3226 cellEditor.addCellEditorListener(this);
3227 rowBeingEdited = row;
3228 columnBeingEdited = column;
3229 setValueAt(editorComp, row, column);
3230 ((JTextField)editorComp).requestFocusInWindow(false);
3231 editorTimer.start();
3232 return true;
3236 * Programmatically starts editing the specified cell.
3238 * @param row the row of the cell to edit.
3239 * @param column the column of the cell to edit.
3241 public boolean editCellAt (int row, int column, EventObject e)
3243 return editCellAt(row, column);
3247 * Discards the editor object.
3249 public void removeEditor()
3251 editingStopped(new ChangeEvent(this));
3255 * Prepares the editor by querying for the value and selection state of the
3256 * cell at (row, column).
3258 * @param editor the TableCellEditor to set up
3259 * @param row the row of the cell to edit
3260 * @param column the column of the cell to edit
3261 * @return the Component being edited
3263 public Component prepareEditor (TableCellEditor editor, int row, int column)
3265 return editor.getTableCellEditorComponent
3266 (this, getValueAt(row, column), isCellSelected(row, column), row, column);
3270 * This revalidates the <code>JTable</code> and queues a repaint.
3272 protected void resizeAndRepaint()
3274 revalidate();
3275 repaint();