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)
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
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
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. */
41 import java
.awt
.Color
;
42 import java
.awt
.Component
;
43 import java
.awt
.Cursor
;
44 import java
.awt
.Dimension
;
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
;
93 implements TableModelListener
, Scrollable
, TableColumnModelListener
,
94 ListSelectionListener
, CellEditorListener
, Accessible
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.
129 * The column index of this cell.
134 * The index of this cell inside the AccessibleJTable parent.
139 * Creates a new <code>AccessibleJTableCell</code>.
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
)
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()
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()
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
)
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
225 * @return the accessible context of this table cell
227 public AccessibleContext
getAccessibleContext()
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>
359 * @return <code>true</code> if this cell is visible, <code>false</code>
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.
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
382 * @return <code>true</code> if this table cell is currently showing on
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
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);
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
;
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
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
)
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
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
,
560 this.firstRow
= firstRow
;
561 this.lastRow
= lastRow
;
562 this.firstColumn
= firstColumn
;
563 this.lastColumn
= lastColumn
;
571 public int getFirstRow()
576 public int getLastRow()
581 public int getFirstColumn()
586 public int getLastColumn()
593 * Creates a new <code>AccessibleJTable</code>.
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
619 public boolean isAccessibleChildSelected(int i
)
621 // TODO Auto-generated method stub
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
);
669 case TableModelEvent
.DELETE
:
670 tableRowsDeleted(event
);
676 * Receives notification when one or more rows have been inserted into the
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
688 * Receives notification when one or more rows have been deleted from the
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
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
787 public int getAccessibleColumn(int index
)
789 // TODO Auto-generated method stub
793 public int getAccessibleIndex(int r
, int c
)
795 // TODO Auto-generated method stub
799 public Accessible
getAccessibleCaption()
801 // TODO Auto-generated method stub
805 public void setAccessibleCaption(Accessible caption
)
807 // TODO Auto-generated method stub
811 public Accessible
getAccessibleSummary()
813 // TODO Auto-generated method stub
817 public void setAccessibleSummary(Accessible summary
)
819 // TODO Auto-generated method stub
823 public int getAccessibleRowCount()
825 // TODO Auto-generated method stub
829 public int getAccessibleColumnCount()
831 // TODO Auto-generated method stub
835 public Accessible
getAccessibleAt(int r
, int c
)
837 // TODO Auto-generated method stub
841 public int getAccessibleRowExtentAt(int r
, int c
)
843 // TODO Auto-generated method stub
847 public int getAccessibleColumnExtentAt(int r
, int c
)
849 // TODO Auto-generated method stub
853 public AccessibleTable
getAccessibleRowHeader()
855 // TODO Auto-generated method stub
859 public void setAccessibleRowHeader(AccessibleTable header
)
861 // TODO Auto-generated method stub
865 public AccessibleTable
getAccessibleColumnHeader()
867 // TODO Auto-generated method stub
871 public void setAccessibleColumnHeader(AccessibleTable header
)
873 // TODO Auto-generated method stub
877 public Accessible
getAccessibleRowDescription(int r
)
879 // TODO Auto-generated method stub
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
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
907 public boolean isAccessibleRowSelected(int r
)
909 // TODO Auto-generated method stub
913 public boolean isAccessibleColumnSelected(int c
)
915 // TODO Auto-generated method stub
919 public int[] getSelectedAccessibleRows()
921 // TODO Auto-generated method stub
925 public int[] getSelectedAccessibleColumns()
927 // TODO Auto-generated method stub
932 * Returns the accessible row at the specified index.
934 * @param index the index for which to query the row
936 * @return the row number at the specified table index
938 public int getAccessibleRowAtIndex(int index
)
940 // TODO: Back this up by a Mauve test and update API docs accordingly.
941 return index
/ getColumnCount();
945 * Returns the accessible column at the specified index.
947 * @param index the index for which to query the column
949 * @return the column number at the specified table index
951 public int getAccessibleColumnAtIndex(int index
)
953 // TODO: Back this up by a Mauve test and update API docs accordingly.
954 return index
% getColumnCount();
958 * Returns the accessible child index at the specified column and row.
961 * @param column the column
963 * @return the index of the accessible child at the specified row and
966 public int getAccessibleIndexAt(int row
, int column
)
968 // TODO: Back this up by a Mauve test and update API docs accordingly.
969 return row
* getColumnCount() + column
;
973 * Handles property changes from the <code>TableColumn</code>s of this
974 * <code>JTable</code>.
976 * More specifically, this triggers a {@link #revalidate()} call if the
977 * preferredWidth of one of the observed columns changes.
979 class TableColumnPropertyChangeHandler
implements PropertyChangeListener
982 * Receives notification that a property of the observed TableColumns
985 * @param ev the property change event
987 public void propertyChange(PropertyChangeEvent ev
)
989 if (ev
.getPropertyName().equals("preferredWidth"))
991 JTableHeader header
= getTableHeader();
994 TableColumn col
= (TableColumn
) ev
.getSource();
995 header
.setResizingColumn(col
);
997 header
.setResizingColumn(null);
1004 * A cell renderer for boolean values.
1006 private class BooleanCellRenderer
1007 extends DefaultTableCellRenderer
1011 * The CheckBox that is used for rendering.
1013 private JCheckBox checkBox
= new JCheckBox();
1016 * Returns the component that is used for rendering the value.
1018 * @param table the JTable
1019 * @param value the value of the object
1020 * @param isSelected is the cell selected?
1021 * @param hasFocus has the cell the focus?
1022 * @param row the row to render
1023 * @param column the cell to render
1025 * @return this component (the default table cell renderer)
1027 public Component
getTableCellRendererComponent(JTable table
, Object value
,
1029 boolean hasFocus
, int row
,
1032 Boolean boolValue
= (Boolean
) value
;
1033 checkBox
.setSelected(boolValue
.booleanValue());
1039 * A cell renderer for Date values.
1041 private class DateCellRenderer
1042 extends DefaultTableCellRenderer
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
,
1058 boolean hasFocus
, int row
,
1061 super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
,
1063 if (value
instanceof Date
)
1065 Date dateValue
= (Date
) value
;
1066 DateFormat df
= DateFormat
.getDateInstance(DateFormat
.SHORT
);
1067 setText(df
.format(dateValue
));
1074 * A cell renderer for Double values.
1076 private class DoubleCellRenderer
1077 extends DefaultTableCellRenderer
1080 * Creates a new instance of NumberCellRenderer.
1082 public DoubleCellRenderer()
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
,
1101 boolean hasFocus
, int row
,
1104 super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
,
1106 if (value
instanceof Double
)
1108 Double doubleValue
= (Double
) value
;
1109 NumberFormat nf
= NumberFormat
.getInstance();
1110 setText(nf
.format(doubleValue
.doubleValue()));
1117 * A cell renderer for Float values.
1119 private class FloatCellRenderer
1120 extends DefaultTableCellRenderer
1123 * Creates a new instance of NumberCellRenderer.
1125 public FloatCellRenderer()
1127 setHorizontalAlignment(JLabel
.RIGHT
);
1131 * Returns the component that is used for rendering the value.
1133 * @param table the JTable
1134 * @param value the value of the object
1135 * @param isSelected is the cell selected?
1136 * @param hasFocus has the cell the focus?
1137 * @param row the row to render
1138 * @param column the cell to render
1140 * @return this component (the default table cell renderer)
1142 public Component
getTableCellRendererComponent(JTable table
, Object value
,
1144 boolean hasFocus
, int row
,
1147 super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
,
1149 if (value
instanceof Float
)
1151 Float floatValue
= (Float
) value
;
1152 NumberFormat nf
= NumberFormat
.getInstance();
1153 setText(nf
.format(floatValue
.floatValue()));
1160 * A cell renderer for Number values.
1162 private class NumberCellRenderer
1163 extends DefaultTableCellRenderer
1166 * Creates a new instance of NumberCellRenderer.
1168 public NumberCellRenderer()
1170 setHorizontalAlignment(JLabel
.RIGHT
);
1175 * A cell renderer for Icon values.
1177 private class IconCellRenderer
1178 extends DefaultTableCellRenderer
1181 * Returns the component that is used for rendering the value.
1183 * @param table the JTable
1184 * @param value the value of the object
1185 * @param isSelected is the cell selected?
1186 * @param hasFocus has the cell the focus?
1187 * @param row the row to render
1188 * @param column the cell to render
1190 * @return this component (the default table cell renderer)
1192 public Component
getTableCellRendererComponent(JTable table
, Object value
,
1194 boolean hasFocus
, int row
,
1197 super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
,
1199 if (value
instanceof Icon
)
1201 Icon iconValue
= (Icon
) value
;
1208 private static final long serialVersionUID
= 3876025080382781659L;
1212 * When resizing columns, do not automatically change any columns. In this
1213 * case the table should be enclosed in a {@link JScrollPane} in order to
1214 * accomodate cases in which the table size exceeds its visible area.
1216 public static final int AUTO_RESIZE_OFF
= 0;
1219 * When resizing column <code>i</code>, automatically change only the
1220 * single column <code>i+1</code> to provide or absorb excess space
1223 public static final int AUTO_RESIZE_NEXT_COLUMN
= 1;
1226 * When resizing column <code>i</code> in a table of <code>n</code>
1227 * columns, automatically change all columns in the range <code>[i+1,
1228 * n)</code>, uniformly, to provide or absorb excess space requirements.
1230 public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS
= 2;
1233 * When resizing column <code>i</code> in a table of <code>n</code>
1234 * columns, automatically change all columns in the range <code>[0,
1235 * n)</code> (with the exception of column i) uniformly, to provide or
1236 * absorb excess space requirements.
1238 public static final int AUTO_RESIZE_ALL_COLUMNS
= 4;
1241 * When resizing column <code>i</code> in a table of <code>n</code>
1242 * columns, automatically change column <code>n-1</code> (the last column
1243 * in the table) to provide or absorb excess space requirements.
1245 public static final int AUTO_RESIZE_LAST_COLUMN
= 3;
1249 * A table mapping {@link java.lang.Class} objects to
1250 * {@link TableCellEditor} objects. This table is consulted by the
1253 protected Hashtable defaultEditorsByColumnClass
;
1256 * A table mapping {@link java.lang.Class} objects to
1257 * {@link TableCellEditor} objects. This table is consulted by the
1260 protected Hashtable defaultRenderersByColumnClass
;
1263 * The column that is edited, -1 if the table is not edited currently.
1265 protected int editingColumn
;
1268 * The row that is edited, -1 if the table is not edited currently.
1270 protected int editingRow
;
1273 * The component that is used for editing.
1274 * <code>null</code> if the table is not editing currently.
1277 protected transient Component editorComp
;
1281 * Whether or not the table should automatically compute a matching
1282 * {@link TableColumnModel} and assign it to the {@link #columnModel}
1283 * property when the {@link #dataModel} property is changed.
1285 * @see #setModel(TableModel)
1286 * @see #createDefaultColumnsFromModel()
1287 * @see #setColumnModel(TableColumnModel)
1288 * @see #setAutoCreateColumnsFromModel(boolean)
1289 * @see #getAutoCreateColumnsFromModel()
1291 protected boolean autoCreateColumnsFromModel
;
1294 * A numeric code specifying the resizing behavior of the table. Must be
1295 * one of {@link #AUTO_RESIZE_ALL_COLUMNS} (the default), {@link
1296 * #AUTO_RESIZE_LAST_COLUMN}, {@link #AUTO_RESIZE_NEXT_COLUMN}, {@link
1297 * #AUTO_RESIZE_SUBSEQUENT_COLUMNS}, or {@link #AUTO_RESIZE_OFF}.
1300 * @see #setAutoResizeMode(int)
1301 * @see #getAutoResizeMode()
1303 protected int autoResizeMode
;
1306 * The height in pixels of any row of the table. All rows in a table are
1307 * of uniform height. This differs from column width, which varies on a
1308 * per-column basis, and is stored in the individual columns of the
1309 * {@link #columnModel}.
1311 * @see #getRowHeight()
1312 * @see #setRowHeight(int)
1313 * @see TableColumn#getWidth()
1314 * @see TableColumn#setWidth(int)
1316 protected int rowHeight
;
1319 * The height in pixels of the gap left between any two rows of the table.
1321 * @see #setRowMargin(int)
1322 * @see #getRowHeight()
1323 * @see #getIntercellSpacing()
1324 * @see #setIntercellSpacing(Dimension)
1325 * @see TableColumnModel#getColumnMargin()
1326 * @see TableColumnModel#setColumnMargin(int)
1328 protected int rowMargin
;
1331 * Whether or not the table should allow row selection. If the table
1332 * allows both row <em>and</em> column selection, it is said to allow
1333 * "cell selection". Previous versions of the JDK supported cell
1334 * selection as an independent concept, but it is now represented solely
1335 * in terms of simultaneous row and column selection.
1337 * @see TableColumnModel#getColumnSelectionAllowed()
1338 * @see #setRowSelectionAllowed(boolean)
1339 * @see #getRowSelectionAllowed()
1340 * @see #getCellSelectionEnabled()
1341 * @see #setCellSelectionEnabled(boolean)
1343 protected boolean rowSelectionAllowed
;
1346 * @deprecated Use {@link #rowSelectionAllowed}, {@link
1347 * #getColumnSelectionAllowed}, or the combined methods {@link
1348 * #getCellSelectionEnabled} and {@link #setCellSelectionEnabled(boolean)}.
1350 protected boolean cellSelectionEnabled
;
1353 * The model for data stored in the table. Confusingly, the published API
1354 * requires that this field be called <code>dataModel</code>, despite its
1355 * property name. The table listens to its model as a {@link
1356 * TableModelListener}.
1358 * @see #tableChanged(TableModelEvent)
1359 * @see TableModel#addTableModelListener(TableModelListener)
1361 protected TableModel dataModel
;
1364 * <p>A model of various aspects of the columns of the table, <em>not
1365 * including</em> the data stored in them. The {@link TableColumnModel}
1366 * is principally concerned with holding a set of {@link TableColumn}
1367 * objects, each of which describes the display parameters of a column
1368 * and the numeric index of the column from the data model which the
1369 * column is presenting.</p>
1371 * <p>The TableColumnModel also contains a {@link ListSelectionModel} which
1372 * indicates which columns are currently selected. This selection model
1373 * works in combination with the {@link #selectionModel} of the table
1374 * itself to specify a <em>table selection</em>: a combination of row and
1375 * column selections.</p>
1377 * <p>Most application programmers do not need to work with this property
1378 * at all: setting {@link #autoCreateColumnsFromModel} will construct the
1379 * columnModel automatically, and the table acts as a facade for most of
1380 * the interesting properties of the columnModel anyways.</p>
1382 * @see #setColumnModel(TableColumnModel)
1383 * @see #getColumnModel()
1385 protected TableColumnModel columnModel
;
1388 * A model of the rows of this table which are currently selected. This
1389 * model is used in combination with the column selection model held as a
1390 * member of the {@link #columnModel} property, to represent the rows and
1391 * columns (or both: cells) of the table which are currently selected.
1393 * @see #rowSelectionAllowed
1394 * @see #setSelectionModel(ListSelectionModel)
1395 * @see #getSelectionModel()
1396 * @see TableColumnModel#getSelectionModel()
1397 * @see ListSelectionModel#addListSelectionListener(ListSelectionListener)
1399 protected ListSelectionModel selectionModel
;
1402 * The current cell editor.
1404 protected TableCellEditor cellEditor
;
1407 * Whether or not drag-and-drop is enabled on this table.
1409 * @see #setDragEnabled(boolean)
1410 * @see #getDragEnabled()
1412 private boolean dragEnabled
;
1415 * The color to paint the grid lines of the table, when either {@link
1416 * #showHorizontalLines} or {@link #showVerticalLines} is set.
1418 * @see #setGridColor(Color)
1419 * @see #getGridColor()
1421 protected Color gridColor
;
1424 * The size this table would prefer its viewport assume, if it is
1425 * contained in a {@link JScrollPane}.
1427 * @see #setPreferredScrollableViewportSize(Dimension)
1428 * @see #getPreferredScrollableViewportSize()
1430 protected Dimension preferredViewportSize
;
1433 * The color to paint the background of selected cells. Fires a property
1434 * change event with name {@link #SELECTION_BACKGROUND_CHANGED_PROPERTY}
1435 * when its value changes.
1437 * @see #setSelectionBackground(Color)
1438 * @see #getSelectionBackground()
1440 protected Color selectionBackground
;
1443 * The name carried in property change events when the {@link
1444 * #selectionBackground} property changes.
1446 private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY
= "selectionBackground";
1449 * The color to paint the foreground of selected cells. Fires a property
1450 * change event with name {@link #SELECTION_FOREGROUND_CHANGED_PROPERTY}
1451 * when its value changes.
1453 * @see #setSelectionForeground(Color)
1454 * @see #getSelectionForeground()
1456 protected Color selectionForeground
;
1459 * The name carried in property change events when the
1460 * {@link #selectionForeground} property changes.
1462 private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY
= "selectionForeground";
1465 * The showHorizontalLines property.
1467 protected boolean showHorizontalLines
;
1470 * The showVerticalLines property.
1472 protected boolean showVerticalLines
;
1475 * The tableHeader property.
1477 protected JTableHeader tableHeader
;
1480 * The row of the cell being edited.
1482 int rowBeingEdited
= -1;
1485 * The column of the cell being edited.
1487 int columnBeingEdited
= -1;
1490 * The action listener for the editor's Timer.
1492 Timer editorTimer
= new EditorUpdateTimer();
1495 * Stores the old value of a cell before it was edited, in case
1496 * editing is cancelled
1498 Object oldCellValue
;
1501 * The property handler for this table's columns.
1503 TableColumnPropertyChangeHandler tableColumnPropertyChangeHandler
=
1504 new TableColumnPropertyChangeHandler();
1507 * Whether cell editors should receive keyboard focus when the table is
1510 private boolean surrendersFocusOnKeystroke
= false;
1513 * Creates a new <code>JTable</code> instance.
1517 this(null, null, null);
1521 * Creates a new <code>JTable</code> instance.
1523 * @param numRows an <code>int</code> value
1524 * @param numColumns an <code>int</code> value
1526 public JTable (int numRows
, int numColumns
)
1528 this(new DefaultTableModel(numRows
, numColumns
));
1532 * Creates a new <code>JTable</code> instance.
1534 * @param data an <code>Object[][]</code> value
1535 * @param columnNames an <code>Object[]</code> value
1537 public JTable(Object
[][] data
, Object
[] columnNames
)
1539 this(new DefaultTableModel(data
, columnNames
));
1543 * Creates a new <code>JTable</code> instance.
1545 * @param dm a <code>TableModel</code> value
1547 public JTable (TableModel dm
)
1549 this(dm
, null, null);
1553 * Creates a new <code>JTable</code> instance.
1555 * @param dm a <code>TableModel</code> value
1556 * @param cm a <code>TableColumnModel</code> value
1558 public JTable (TableModel dm
, TableColumnModel cm
)
1564 * Creates a new <code>JTable</code> instance.
1566 * @param dm a <code>TableModel</code> value
1567 * @param cm a <code>TableColumnModel</code> value
1568 * @param sm a <code>ListSelectionModel</code> value
1570 public JTable (TableModel dm
, TableColumnModel cm
, ListSelectionModel sm
)
1572 boolean autoCreate
= false;
1577 setColumnModel(createDefaultColumnModel());
1580 setSelectionModel(sm
== null ?
createDefaultSelectionModel() : sm
);
1581 setModel(dm
== null ?
createDefaultDataModel() : dm
);
1582 setAutoCreateColumnsFromModel(autoCreate
);
1583 initializeLocalVars();
1584 // The following four lines properly set the lead selection indices.
1585 // After this, the UI will handle the lead selection indices.
1586 // FIXME: this should probably not be necessary, if the UI is installed
1587 // before the TableModel is set then the UI will handle things on its
1588 // own, but certain variables need to be set before the UI can be installed
1589 // so we must get the correct order for all the method calls in this
1591 selectionModel
.setAnchorSelectionIndex(0);
1592 selectionModel
.setLeadSelectionIndex(0);
1593 columnModel
.getSelectionModel().setAnchorSelectionIndex(0);
1594 columnModel
.getSelectionModel().setLeadSelectionIndex(0);
1598 protected void initializeLocalVars()
1600 setTableHeader(createDefaultTableHeader());
1601 if (autoCreateColumnsFromModel
)
1602 createDefaultColumnsFromModel();
1603 this.columnModel
.addColumnModelListener(this);
1605 this.defaultRenderersByColumnClass
= new Hashtable();
1606 createDefaultRenderers();
1608 this.defaultEditorsByColumnClass
= new Hashtable();
1609 createDefaultEditors();
1611 this.autoResizeMode
= AUTO_RESIZE_SUBSEQUENT_COLUMNS
;
1612 this.rowHeight
= 16;
1614 this.rowSelectionAllowed
= true;
1615 // this.accessibleContext = new AccessibleJTable();
1616 this.cellEditor
= null;
1617 // COMPAT: Both Sun and IBM have drag enabled
1618 this.dragEnabled
= true;
1619 this.preferredViewportSize
= new Dimension(450,400);
1620 this.showHorizontalLines
= true;
1621 this.showVerticalLines
= true;
1622 this.editingColumn
= -1;
1623 this.editingRow
= -1;
1624 setIntercellSpacing(new Dimension(1,1));
1628 * Creates a new <code>JTable</code> instance.
1630 * @param data a <code>Vector</code> value
1631 * @param columnNames a <code>Vector</code> value
1633 public JTable(Vector data
, Vector columnNames
)
1635 this(new DefaultTableModel(data
, columnNames
));
1639 * The timer that updates the editor component.
1641 private class EditorUpdateTimer
1643 implements ActionListener
1646 * Creates a new EditorUpdateTimer object with a default delay of 0.5 seconds.
1648 public EditorUpdateTimer()
1651 addActionListener(this);
1655 * Lets the caret blink and repaints the table.
1657 public void actionPerformed(ActionEvent ev
)
1659 Caret c
= ((JTextField
)JTable
.this.editorComp
).getCaret();
1661 c
.setVisible(!c
.isVisible());
1662 JTable
.this.repaint();
1666 * Updates the blink delay according to the current caret.
1668 public void update()
1671 Caret c
= ((JTextField
)JTable
.this.editorComp
).getCaret();
1674 setDelay(c
.getBlinkRate());
1675 if (((JTextField
)JTable
.this.editorComp
).isEditable())
1678 c
.setVisible(false);
1683 public void addColumn(TableColumn column
)
1685 if (column
.getHeaderValue() == null)
1687 String name
= dataModel
.getColumnName(column
.getModelIndex());
1688 column
.setHeaderValue(name
);
1691 columnModel
.addColumn(column
);
1692 column
.addPropertyChangeListener(tableColumnPropertyChangeHandler
);
1695 protected void createDefaultEditors()
1697 //FIXME: Create the editor object.
1700 protected void createDefaultRenderers()
1702 setDefaultRenderer(Boolean
.class, new BooleanCellRenderer());
1703 setDefaultRenderer(Number
.class, new NumberCellRenderer());
1704 setDefaultRenderer(Double
.class, new DoubleCellRenderer());
1705 setDefaultRenderer(Double
.class, new FloatCellRenderer());
1706 setDefaultRenderer(Date
.class, new DateCellRenderer());
1707 setDefaultRenderer(Icon
.class, new IconCellRenderer());
1711 * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code>
1713 public static JScrollPane
createScrollPaneForTable(JTable table
)
1715 return new JScrollPane(table
);
1718 protected TableColumnModel
createDefaultColumnModel()
1720 return new DefaultTableColumnModel();
1723 protected TableModel
createDefaultDataModel()
1725 return new DefaultTableModel();
1728 protected ListSelectionModel
createDefaultSelectionModel()
1730 return new DefaultListSelectionModel();
1733 protected JTableHeader
createDefaultTableHeader()
1735 return new JTableHeader(columnModel
);
1740 public void columnAdded (TableColumnModelEvent event
)
1746 public void columnMarginChanged (ChangeEvent event
)
1752 public void columnMoved (TableColumnModelEvent event
)
1758 public void columnRemoved (TableColumnModelEvent event
)
1764 public void columnSelectionChanged (ListSelectionEvent event
)
1769 public void editingCanceled (ChangeEvent event
)
1771 if (rowBeingEdited
> -1 && columnBeingEdited
> -1)
1773 if (getValueAt(rowBeingEdited
, columnBeingEdited
) instanceof JTextField
)
1775 remove ((Component
)getValueAt(rowBeingEdited
, columnBeingEdited
));
1776 setValueAt(oldCellValue
, rowBeingEdited
, columnBeingEdited
);
1778 rowBeingEdited
= -1;
1779 columnBeingEdited
= -1;
1784 requestFocusInWindow(false);
1788 public void editingStopped (ChangeEvent event
)
1790 if (rowBeingEdited
> -1 && columnBeingEdited
> -1)
1792 if (getValueAt(rowBeingEdited
, columnBeingEdited
) instanceof JTextField
)
1794 remove((Component
)getValueAt(rowBeingEdited
, columnBeingEdited
));
1795 setValueAt(((JTextField
)editorComp
).getText(),
1796 rowBeingEdited
, columnBeingEdited
);
1798 rowBeingEdited
= -1;
1799 columnBeingEdited
= -1;
1804 requestFocusInWindow(false);
1808 public void tableChanged (TableModelEvent event
)
1810 // update the column model from the table model if the structure has
1811 // changed and the flag autoCreateColumnsFromModel is set
1812 if ((event
.getFirstRow() ==TableModelEvent
.HEADER_ROW
)
1813 && autoCreateColumnsFromModel
)
1815 createDefaultColumnsFromModel();
1817 // If the structure changes, we need to revalidate, since that might
1818 // affect the size parameters of the JTable. Otherwise we only need
1819 // to perform a repaint to update the view.
1820 if (event
.getType() == TableModelEvent
.INSERT
)
1822 else if (event
.getType() == TableModelEvent
.DELETE
)
1824 if (dataModel
.getRowCount() == 0)
1831 public void valueChanged (ListSelectionEvent event
)
1837 * Returns index of the column that contains specified point
1838 * or -1 if this table doesn't contain this point.
1840 * @param point point to identify the column
1841 * @return index of the column that contains specified point or
1842 * -1 if this table doesn't contain this point.
1844 public int columnAtPoint(Point point
)
1848 int ncols
= getColumnCount();
1849 Dimension gap
= getIntercellSpacing();
1850 TableColumnModel cols
= getColumnModel();
1853 for (int i
= 0; i
< ncols
; ++i
)
1855 int width
= cols
.getColumn(i
).getWidth()
1856 + (gap
== null ?
0 : gap
.width
);
1857 if (0 <= x
&& x
< width
)
1866 * Returns index of the row that contains specified point or
1867 * -1 if this table doesn't contain this point.
1869 * @param point point to identify the row
1870 * @return index of the row that contains specified point or
1871 * -1 if this table doesn't contain this point.
1873 public int rowAtPoint(Point point
)
1877 int nrows
= getRowCount();
1878 int height
= getRowHeight();
1881 for (int i
= 0; i
< nrows
; ++i
)
1883 if (0 <= y
&& y
< height
)
1892 * Calculate the visible rectangle for a particular row and column. The
1893 * row and column are specified in visual terms; the column may not match
1894 * the {@link #dataModel} column.
1896 * @param row the visible row to get the cell rectangle of
1898 * @param column the visible column to get the cell rectangle of, which may
1899 * differ from the {@link #dataModel} column
1901 * @param includeSpacing whether or not to include the cell margins in the
1902 * resulting cell. If <code>false</code>, the result will only contain the
1903 * inner area of the target cell, not including its margins.
1905 * @return a rectangle enclosing the specified cell
1907 public Rectangle
getCellRect(int row
,
1909 boolean includeSpacing
)
1911 int height
= getRowHeight(row
);
1912 int width
= columnModel
.getColumn(column
).getWidth();
1913 int x_gap
= columnModel
.getColumnMargin();
1914 int y_gap
= rowMargin
;
1916 column
= Math
.max(0, Math
.min(column
, getColumnCount() - 1));
1917 row
= Math
.max(0, Math
.min(row
, getRowCount() - 1));
1920 int y
= (height
+ y_gap
) * row
;
1922 for (int i
= 0; i
< column
; ++i
)
1923 x
+= columnModel
.getColumn(i
).getWidth();
1926 return new Rectangle(x
, y
, width
, height
);
1928 return new Rectangle(x
, y
, width
- x_gap
, height
- y_gap
);
1931 public void clearSelection()
1933 selectionModel
.clearSelection();
1934 getColumnModel().getSelectionModel().clearSelection();
1938 * Get the value of the selectedRow property by delegation to
1939 * the {@link ListSelectionModel#getMinSelectionIndex} method of the
1940 * {@link #selectionModel} field.
1942 * @return The current value of the selectedRow property
1944 public int getSelectedRow ()
1946 return selectionModel
.getMinSelectionIndex();
1950 * Get the value of the {@link #selectionModel} property.
1952 * @return The current value of the property
1954 public ListSelectionModel
getSelectionModel()
1956 //Neither Sun nor IBM returns null if rowSelection not allowed
1957 return selectionModel
;
1960 public int getScrollableBlockIncrement(Rectangle visibleRect
, int orientation
, int direction
)
1962 if (orientation
== SwingConstants
.VERTICAL
)
1963 return visibleRect
.height
* direction
;
1965 return visibleRect
.width
* direction
;
1969 * Get the value of the <code>scrollableTracksViewportHeight</code> property.
1971 * @return The constant value <code>false</code>
1973 public boolean getScrollableTracksViewportHeight()
1979 * Get the value of the <code>scrollableTracksViewportWidth</code> property.
1981 * @return <code>true</code> unless the {@link #autoResizeMode} property is
1982 * <code>AUTO_RESIZE_OFF</code>
1984 public boolean getScrollableTracksViewportWidth()
1986 if (autoResizeMode
== AUTO_RESIZE_OFF
)
1992 public int getScrollableUnitIncrement(Rectangle visibleRect
, int orientation
, int direction
)
1994 // FIXME: I don't exactly know what sun does here. in both cases they
1995 // pick values which do *not* simply expose the next cell in a given
1996 // scroll direction.
1998 if (orientation
== SwingConstants
.VERTICAL
)
1999 return direction
* rowHeight
;
2003 for (int i
= 0; i
< getColumnCount(); ++i
)
2004 sum
+= columnModel
.getColumn(0).getWidth();
2005 int inc
= getColumnCount() == 0 ?
10 : sum
/ getColumnCount();
2006 return direction
* inc
;
2011 public TableCellEditor
getCellEditor(int row
, int column
)
2013 TableCellEditor editor
= columnModel
.getColumn(column
).getCellEditor();
2016 editor
= getDefaultEditor(dataModel
.getColumnClass(column
));
2021 public TableCellEditor
getDefaultEditor(Class columnClass
)
2023 if (defaultEditorsByColumnClass
.containsKey(columnClass
))
2024 return (TableCellEditor
) defaultEditorsByColumnClass
.get(columnClass
);
2027 // FIXME: We have at least an editor for Object.class in our defaults.
2028 TableCellEditor r
= new DefaultCellEditor(new JTextField());
2029 defaultEditorsByColumnClass
.put(columnClass
, r
);
2034 public TableCellRenderer
getCellRenderer(int row
, int column
)
2036 TableCellRenderer renderer
=
2037 columnModel
.getColumn(column
).getCellRenderer();
2038 if (renderer
== null)
2039 renderer
= getDefaultRenderer(getColumnClass(column
));
2044 public void setDefaultRenderer(Class columnClass
, TableCellRenderer rend
)
2046 defaultRenderersByColumnClass
.put(columnClass
, rend
);
2049 public TableCellRenderer
getDefaultRenderer(Class columnClass
)
2051 if (defaultRenderersByColumnClass
.containsKey(columnClass
))
2052 return (TableCellRenderer
) defaultRenderersByColumnClass
.get(columnClass
);
2055 TableCellRenderer r
= new DefaultTableCellRenderer();
2056 defaultRenderersByColumnClass
.put(columnClass
, r
);
2061 public int convertColumnIndexToModel(int vc
)
2066 return columnModel
.getColumn(vc
).getModelIndex();
2069 public int convertColumnIndexToView(int mc
)
2073 int ncols
= getColumnCount();
2074 for (int vc
= 0; vc
< ncols
; ++vc
)
2076 if (columnModel
.getColumn(vc
).getModelIndex() == mc
)
2082 public Component
prepareRenderer(TableCellRenderer renderer
,
2087 boolean rowSelAllowed
= getRowSelectionAllowed();
2088 boolean colSelAllowed
= getColumnSelectionAllowed();
2089 boolean isSel
= false;
2090 if (rowSelAllowed
&& colSelAllowed
|| !rowSelAllowed
&& !colSelAllowed
)
2091 isSel
= isCellSelected(row
, column
);
2093 isSel
= isRowSelected(row
) && getRowSelectionAllowed()
2094 || isColumnSelected(column
) && getColumnSelectionAllowed();
2096 // Determine the focused cell. The focused cell is the cell at the
2097 // leadSelectionIndices of the row and column selection model.
2098 ListSelectionModel rowSel
= getSelectionModel();
2099 ListSelectionModel colSel
= getColumnModel().getSelectionModel();
2100 boolean hasFocus
= hasFocus() && isEnabled()
2101 && rowSel
.getLeadSelectionIndex() == row
2102 && colSel
.getLeadSelectionIndex() == column
;
2104 return renderer
.getTableCellRendererComponent(this,
2105 dataModel
.getValueAt(row
,
2106 convertColumnIndexToModel(column
)),
2114 * Get the value of the {@link #autoCreateColumnsFromModel} property.
2116 * @return The current value of the property
2118 public boolean getAutoCreateColumnsFromModel()
2120 return autoCreateColumnsFromModel
;
2124 * Get the value of the {@link #autoResizeMode} property.
2126 * @return The current value of the property
2128 public int getAutoResizeMode()
2130 return autoResizeMode
;
2134 * Get the value of the {@link #rowHeight} property.
2136 * @return The current value of the property
2138 public int getRowHeight()
2144 * Get the height of the specified row.
2146 * @param row the row whose height to return
2148 public int getRowHeight(int row
)
2150 // FIXME: return the height of the specified row
2151 // which may be different from the general rowHeight
2157 * Get the value of the {@link #rowMargin} property.
2159 * @return The current value of the property
2161 public int getRowMargin()
2167 * Get the value of the {@link #rowSelectionAllowed} property.
2169 * @return The current value of the property
2171 public boolean getRowSelectionAllowed()
2173 return rowSelectionAllowed
;
2177 * Get the value of the {@link #cellSelectionEnabled} property.
2179 * @return The current value of the property
2181 public boolean getCellSelectionEnabled()
2183 return getColumnSelectionAllowed() && getRowSelectionAllowed();
2187 * Get the value of the {@link #dataModel} property.
2189 * @return The current value of the property
2191 public TableModel
getModel()
2197 * Get the value of the <code>columnCount</code> property by
2198 * delegation to the @{link #columnModel} field.
2200 * @return The current value of the columnCount property
2202 public int getColumnCount()
2204 return columnModel
.getColumnCount();
2208 * Get the value of the <code>rowCount</code> property by
2209 * delegation to the @{link #dataModel} field.
2211 * @return The current value of the rowCount property
2213 public int getRowCount()
2215 return dataModel
.getRowCount();
2219 * Get the value of the {@link #columnModel} property.
2221 * @return The current value of the property
2223 public TableColumnModel
getColumnModel()
2229 * Get the value of the <code>selectedColumn</code> property by
2230 * delegation to the @{link #columnModel} field.
2232 * @return The current value of the selectedColumn property
2234 public int getSelectedColumn()
2236 return columnModel
.getSelectionModel().getMinSelectionIndex();
2239 private static int countSelections(ListSelectionModel lsm
)
2241 int lo
= lsm
.getMinSelectionIndex();
2242 int hi
= lsm
.getMaxSelectionIndex();
2244 if (lo
!= -1 && hi
!= -1)
2246 switch (lsm
.getSelectionMode())
2248 case ListSelectionModel
.SINGLE_SELECTION
:
2252 case ListSelectionModel
.SINGLE_INTERVAL_SELECTION
:
2256 case ListSelectionModel
.MULTIPLE_INTERVAL_SELECTION
:
2257 for (int i
= lo
; i
<= hi
; ++i
)
2258 if (lsm
.isSelectedIndex(i
))
2266 private static int[] getSelections(ListSelectionModel lsm
)
2268 int sz
= countSelections(lsm
);
2269 int [] ret
= new int[sz
];
2271 int lo
= lsm
.getMinSelectionIndex();
2272 int hi
= lsm
.getMaxSelectionIndex();
2274 if (lo
!= -1 && hi
!= -1)
2276 switch (lsm
.getSelectionMode())
2278 case ListSelectionModel
.SINGLE_SELECTION
:
2282 case ListSelectionModel
.SINGLE_INTERVAL_SELECTION
:
2283 for (int i
= lo
; i
<= hi
; ++i
)
2287 case ListSelectionModel
.MULTIPLE_INTERVAL_SELECTION
:
2288 for (int i
= lo
; i
<= hi
; ++i
)
2289 if (lsm
.isSelectedIndex(i
))
2298 * Get the value of the <code>selectedColumnCount</code> property by
2299 * delegation to the @{link #columnModel} field.
2301 * @return The current value of the selectedColumnCount property
2303 public int getSelectedColumnCount()
2305 return countSelections(columnModel
.getSelectionModel());
2309 * Get the value of the <code>selectedColumns</code> property by
2310 * delegation to the @{link #columnModel} field.
2312 * @return The current value of the selectedColumns property
2314 public int[] getSelectedColumns()
2316 return getSelections(columnModel
.getSelectionModel());
2320 * Get the value of the <code>columnSelectionAllowed</code> property.
2322 * @return The current value of the columnSelectionAllowed property
2324 public boolean getColumnSelectionAllowed()
2326 return getColumnModel().getColumnSelectionAllowed();
2330 * Get the value of the <code>selectedRowCount</code> property by
2331 * delegation to the @{link #selectionModel} field.
2333 * @return The current value of the selectedRowCount property
2335 public int getSelectedRowCount()
2337 return countSelections(selectionModel
);
2341 * Get the value of the <code>selectedRows</code> property by
2342 * delegation to the @{link #selectionModel} field.
2344 * @return The current value of the selectedRows property
2346 public int[] getSelectedRows()
2348 return getSelections(selectionModel
);
2352 * Get the value of the {@link #accessibleContext} property.
2354 * @return The current value of the property
2356 public AccessibleContext
getAccessibleContext()
2358 return accessibleContext
;
2362 * Get the value of the {@link #cellEditor} property.
2364 * @return The current value of the property
2366 public TableCellEditor
getCellEditor()
2372 * Get the value of the {@link #dragEnabled} property.
2374 * @return The current value of the property
2376 public boolean getDragEnabled()
2382 * Get the value of the {@link #gridColor} property.
2384 * @return The current value of the property
2386 public Color
getGridColor()
2392 * Get the value of the <code>intercellSpacing</code> property.
2394 * @return The current value of the property
2396 public Dimension
getIntercellSpacing()
2398 return new Dimension(columnModel
.getColumnMargin(), rowMargin
);
2402 * Get the value of the {@link #preferredViewportSize} property.
2404 * @return The current value of the property
2406 public Dimension
getPreferredScrollableViewportSize()
2408 return preferredViewportSize
;
2412 * Get the value of the {@link #selectionBackground} property.
2414 * @return The current value of the property
2416 public Color
getSelectionBackground()
2418 return selectionBackground
;
2422 * Get the value of the {@link #selectionForeground} property.
2424 * @return The current value of the property
2426 public Color
getSelectionForeground()
2428 return selectionForeground
;
2432 * Get the value of the {@link #showHorizontalLines} property.
2434 * @return The current value of the property
2436 public boolean getShowHorizontalLines()
2438 return showHorizontalLines
;
2442 * Get the value of the {@link #showVerticalLines} property.
2444 * @return The current value of the property
2446 public boolean getShowVerticalLines()
2448 return showVerticalLines
;
2452 * Get the value of the {@link #tableHeader} property.
2454 * @return The current value of the property
2456 public JTableHeader
getTableHeader()
2462 * Removes specified column from displayable columns of this table.
2464 * @param column column to removed
2466 public void removeColumn(TableColumn column
)
2468 columnModel
.removeColumn(column
);
2472 * Moves column at the specified index to new given location.
2474 * @param column index of the column to move
2475 * @param targetColumn index specifying new location of the column
2477 public void moveColumn(int column
,int targetColumn
)
2479 columnModel
.moveColumn(column
, targetColumn
);
2483 * Set the value of the {@link #autoCreateColumnsFromModel} flag. If the
2484 * flag changes from <code>false</code> to <code>true</code>, the
2485 * {@link #createDefaultColumnsFromModel()} method is called.
2487 * @param autoCreate the new value of the flag.
2489 public void setAutoCreateColumnsFromModel(boolean autoCreate
)
2491 if (autoCreateColumnsFromModel
!= autoCreate
)
2493 autoCreateColumnsFromModel
= autoCreate
;
2495 createDefaultColumnsFromModel();
2500 * Set the value of the {@link #autoResizeMode} property.
2502 * @param a The new value of the autoResizeMode property
2504 public void setAutoResizeMode(int a
)
2512 * Set the value of the {@link #rowHeight} property.
2514 * @param r The new value of the rowHeight property
2516 public void setRowHeight(int r
)
2519 throw new IllegalArgumentException();
2527 * Sets the value of the rowHeight property for the specified
2530 * @param rh is the new rowHeight
2531 * @param row is the row to change the rowHeight of
2533 public void setRowHeight(int row
, int rh
)
2536 // FIXME: not implemented
2540 * Set the value of the {@link #rowMargin} property.
2542 * @param r The new value of the rowMargin property
2544 public void setRowMargin(int r
)
2552 * Set the value of the {@link #rowSelectionAllowed} property.
2554 * @param r The new value of the rowSelectionAllowed property
2556 public void setRowSelectionAllowed(boolean r
)
2558 rowSelectionAllowed
= r
;
2563 * Set the value of the {@link #cellSelectionEnabled} property.
2565 * @param c The new value of the cellSelectionEnabled property
2567 public void setCellSelectionEnabled(boolean c
)
2569 setColumnSelectionAllowed(c
);
2570 setRowSelectionAllowed(c
);
2571 // for backward-compatibility sake:
2572 cellSelectionEnabled
= true;
2576 * <p>Set the value of the {@link #dataModel} property.</p>
2578 * <p>Unregister <code>this</code> as a {@link TableModelListener} from
2579 * previous {@link #dataModel} and register it with new parameter
2580 * <code>m</code>.</p>
2582 * @param m The new value of the model property
2584 public void setModel(TableModel m
)
2586 // Throw exception is m is null.
2588 throw new IllegalArgumentException();
2590 // Don't do anything if setting the current model again.
2594 TableModel oldModel
= dataModel
;
2596 // Remove table as TableModelListener from old model.
2597 if (dataModel
!= null)
2598 dataModel
.removeTableModelListener(this);
2605 // Add table as TableModelListener to new model.
2606 dataModel
.addTableModelListener(this);
2608 // Automatically create columns.
2609 if (autoCreateColumnsFromModel
)
2610 createDefaultColumnsFromModel();
2613 // This property is bound, so we fire a property change event.
2614 firePropertyChange("model", oldModel
, dataModel
);
2622 * <p>Set the value of the {@link #columnModel} property.</p>
2624 * <p>Unregister <code>this</code> as a {@link TableColumnModelListener}
2625 * from previous {@link #columnModel} and register it with new parameter
2626 * <code>c</code>.</p>
2628 * @param c The new value of the columnModel property
2630 public void setColumnModel(TableColumnModel c
)
2633 throw new IllegalArgumentException();
2634 TableColumnModel tmp
= columnModel
;
2636 tmp
.removeColumnModelListener(this);
2638 c
.addColumnModelListener(this);
2640 if (dataModel
!= null && columnModel
!= null)
2642 int ncols
= getColumnCount();
2643 for (int i
= 0; i
< ncols
; ++i
)
2644 columnModel
.getColumn(i
).setHeaderValue(dataModel
.getColumnName(i
));
2647 // according to Sun's spec we also have to set the tableHeader's
2648 // column model here
2649 if (tableHeader
!= null)
2650 tableHeader
.setColumnModel(c
);
2657 * Set the value of the <code>columnSelectionAllowed</code> property.
2659 * @param c The new value of the property
2661 public void setColumnSelectionAllowed(boolean c
)
2663 getColumnModel().setColumnSelectionAllowed(c
);
2668 * <p>Set the value of the {@link #selectionModel} property.</p>
2670 * <p>Unregister <code>this</code> as a {@link ListSelectionListener}
2671 * from previous {@link #selectionModel} and register it with new
2672 * parameter <code>s</code>.</p>
2674 * @param s The new value of the selectionModel property
2676 public void setSelectionModel(ListSelectionModel s
)
2679 throw new IllegalArgumentException();
2680 ListSelectionModel tmp
= selectionModel
;
2682 tmp
.removeListSelectionListener(this);
2684 s
.addListSelectionListener(this);
2689 * Set the value of the <code>selectionMode</code> property by
2690 * delegation to the {@link #selectionModel} field. The same selection
2691 * mode is set for row and column selection models.
2693 * @param s The new value of the property
2695 public void setSelectionMode(int s
)
2697 selectionModel
.setSelectionMode(s
);
2698 columnModel
.getSelectionModel().setSelectionMode(s
);
2704 * <p>Set the value of the {@link #cellEditor} property.</p>
2706 * <p>Unregister <code>this</code> as a {@link CellEditorListener} from
2707 * previous {@link #cellEditor} and register it with new parameter
2708 * <code>c</code>.</p>
2710 * @param c The new value of the cellEditor property
2712 public void setCellEditor(TableCellEditor c
)
2714 TableCellEditor tmp
= cellEditor
;
2716 tmp
.removeCellEditorListener(this);
2718 c
.addCellEditorListener(this);
2723 * Set the value of the {@link #dragEnabled} property.
2725 * @param d The new value of the dragEnabled property
2727 public void setDragEnabled(boolean d
)
2733 * Set the value of the {@link #gridColor} property.
2735 * @param g The new value of the gridColor property
2737 public void setGridColor(Color g
)
2744 * Set the value of the <code>intercellSpacing</code> property.
2746 * @param i The new value of the intercellSpacing property
2748 public void setIntercellSpacing(Dimension i
)
2750 rowMargin
= i
.height
;
2751 columnModel
.setColumnMargin(i
.width
);
2756 * Set the value of the {@link #preferredViewportSize} property.
2758 * @param p The new value of the preferredViewportSize property
2760 public void setPreferredScrollableViewportSize(Dimension p
)
2762 preferredViewportSize
= p
;
2768 * <p>Set the value of the {@link #selectionBackground} property.</p>
2770 * <p>Fire a PropertyChangeEvent with name {@link
2771 * #SELECTION_BACKGROUND_CHANGED_PROPERTY} to registered listeners, if
2772 * selectionBackground changed.</p>
2774 * @param s The new value of the selectionBackground property
2776 public void setSelectionBackground(Color s
)
2778 Color tmp
= selectionBackground
;
2779 selectionBackground
= s
;
2780 if (((tmp
== null && s
!= null)
2781 || (s
== null && tmp
!= null)
2782 || (tmp
!= null && s
!= null && !tmp
.equals(s
))))
2783 firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY
, tmp
, s
);
2788 * <p>Set the value of the {@link #selectionForeground} property.</p>
2790 * <p>Fire a PropertyChangeEvent with name {@link
2791 * #SELECTION_FOREGROUND_CHANGED_PROPERTY} to registered listeners, if
2792 * selectionForeground changed.</p>
2794 * @param s The new value of the selectionForeground property
2796 public void setSelectionForeground(Color s
)
2798 Color tmp
= selectionForeground
;
2799 selectionForeground
= s
;
2800 if (((tmp
== null && s
!= null)
2801 || (s
== null && tmp
!= null)
2802 || (tmp
!= null && s
!= null && !tmp
.equals(s
))))
2803 firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY
, tmp
, s
);
2808 * Set the value of the <code>showGrid</code> property.
2810 * @param s The new value of the showGrid property
2812 public void setShowGrid(boolean s
)
2814 setShowVerticalLines(s
);
2815 setShowHorizontalLines(s
);
2819 * Set the value of the {@link #showHorizontalLines} property.
2821 * @param s The new value of the showHorizontalLines property
2823 public void setShowHorizontalLines(boolean s
)
2825 showHorizontalLines
= s
;
2830 * Set the value of the {@link #showVerticalLines} property.
2832 * @param s The new value of the showVerticalLines property
2834 public void setShowVerticalLines(boolean s
)
2836 showVerticalLines
= s
;
2841 * Set the value of the {@link #tableHeader} property.
2843 * @param t The new value of the tableHeader property
2845 public void setTableHeader(JTableHeader t
)
2847 if (tableHeader
!= null)
2848 tableHeader
.setTable(null);
2850 if (tableHeader
!= null)
2851 tableHeader
.setTable(this);
2856 protected void configureEnclosingScrollPane()
2858 JScrollPane jsp
= (JScrollPane
) SwingUtilities
.getAncestorOfClass(JScrollPane
.class, this);
2859 if (jsp
!= null && tableHeader
!= null)
2861 jsp
.setColumnHeaderView(tableHeader
);
2865 protected void unconfigureEnclosingScrollPane()
2867 JScrollPane jsp
= (JScrollPane
) SwingUtilities
.getAncestorOfClass(JScrollPane
.class, this);
2870 jsp
.setColumnHeaderView(null);
2875 public void addNotify()
2878 configureEnclosingScrollPane();
2881 public void removeNotify()
2884 unconfigureEnclosingScrollPane();
2889 * This distributes the superfluous width in a table evenly on its columns.
2891 * The implementation used here is different to that one described in
2892 * the JavaDocs. It is much simpler, and seems to work very well.
2894 * TODO: correctly implement the algorithm described in the JavaDoc
2896 private void distributeSpill(TableColumn
[] cols
, int spill
)
2898 int average
= spill
/ cols
.length
;
2899 for (int i
= 0; i
< cols
.length
; i
++)
2901 if (cols
[i
] != null)
2902 cols
[i
].setWidth(cols
[i
].getWidth() + average
);
2906 public void doLayout()
2908 TableColumn resizingColumn
= null;
2910 int ncols
= getColumnCount();
2914 int[] pref
= new int[ncols
];
2918 if (tableHeader
!= null)
2919 resizingColumn
= tableHeader
.getResizingColumn();
2921 for (int i
= 0; i
< ncols
; ++i
)
2923 TableColumn col
= columnModel
.getColumn(i
);
2924 int p
= col
.getWidth();
2927 if (resizingColumn
== col
)
2931 int spill
= getWidth() - prefSum
;
2933 if (resizingColumn
!= null)
2936 TableColumn
[] cols
;
2938 switch (getAutoResizeMode())
2940 case AUTO_RESIZE_LAST_COLUMN
:
2941 col
= columnModel
.getColumn(ncols
-1);
2942 col
.setWidth(col
.getPreferredWidth() + spill
);
2945 case AUTO_RESIZE_NEXT_COLUMN
:
2946 col
= columnModel
.getColumn(ncols
-1);
2947 col
.setWidth(col
.getPreferredWidth() + spill
);
2950 case AUTO_RESIZE_ALL_COLUMNS
:
2951 cols
= new TableColumn
[ncols
];
2952 for (int i
= 0; i
< ncols
; ++i
)
2953 cols
[i
] = columnModel
.getColumn(i
);
2954 distributeSpill(cols
, spill
);
2957 case AUTO_RESIZE_SUBSEQUENT_COLUMNS
:
2958 cols
= new TableColumn
[ncols
];
2959 for (int i
= rCol
; i
< ncols
; ++i
)
2960 cols
[i
] = columnModel
.getColumn(i
);
2961 distributeSpill(cols
, spill
);
2964 case AUTO_RESIZE_OFF
:
2966 int prefWidth
= resizingColumn
.getPreferredWidth();
2967 resizingColumn
.setWidth(prefWidth
);
2972 TableColumn
[] cols
= new TableColumn
[ncols
];
2973 for (int i
= 0; i
< ncols
; ++i
)
2974 cols
[i
] = columnModel
.getColumn(i
);
2975 distributeSpill(cols
, spill
);
2980 * @deprecated Replaced by <code>doLayout()</code>
2982 public void sizeColumnsToFit(boolean lastColumnOnly
)
2988 * Obsolete since JDK 1.4. Please use <code>doLayout()</code>.
2990 public void sizeColumnsToFit(int resizingColumn
)
2995 public String
getUIClassID()
3001 * This method returns the table's UI delegate.
3003 * @return The table's UI delegate.
3005 public TableUI
getUI()
3007 return (TableUI
) ui
;
3011 * This method sets the table's UI delegate.
3013 * @param ui The table's UI delegate.
3015 public void setUI(TableUI ui
)
3020 public void updateUI()
3022 setUI((TableUI
) UIManager
.getUI(this));
3027 public Class
getColumnClass(int column
)
3029 return getModel().getColumnClass(column
);
3032 public String
getColumnName(int column
)
3034 int modelColumn
= columnModel
.getColumn(column
).getModelIndex();
3035 return dataModel
.getColumnName(modelColumn
);
3038 public int getEditingColumn()
3040 return editingColumn
;
3043 public void setEditingColumn(int column
)
3045 editingColumn
= column
;
3048 public int getEditingRow()
3053 public void setEditingRow(int column
)
3055 editingRow
= column
;
3058 public Component
getEditorComponent()
3063 public boolean isEditing()
3065 return editorComp
!= null;
3068 public void setDefaultEditor(Class columnClass
, TableCellEditor editor
)
3071 defaultEditorsByColumnClass
.put(columnClass
, editor
);
3073 defaultEditorsByColumnClass
.remove(columnClass
);
3076 public void addColumnSelectionInterval(int index0
, int index1
)
3078 if ((index0
< 0 || index0
> (getColumnCount()-1)
3079 || index1
< 0 || index1
> (getColumnCount()-1)))
3080 throw new IllegalArgumentException("Column index out of range.");
3082 getColumnModel().getSelectionModel().addSelectionInterval(index0
, index1
);
3085 public void addRowSelectionInterval(int index0
, int index1
)
3087 if ((index0
< 0 || index0
> (getRowCount()-1)
3088 || index1
< 0 || index1
> (getRowCount()-1)))
3089 throw new IllegalArgumentException("Row index out of range.");
3091 getSelectionModel().addSelectionInterval(index0
, index1
);
3094 public void setColumnSelectionInterval(int index0
, int index1
)
3096 if ((index0
< 0 || index0
> (getColumnCount()-1)
3097 || index1
< 0 || index1
> (getColumnCount()-1)))
3098 throw new IllegalArgumentException("Column index out of range.");
3100 getColumnModel().getSelectionModel().setSelectionInterval(index0
, index1
);
3103 public void setRowSelectionInterval(int index0
, int index1
)
3105 if ((index0
< 0 || index0
> (getRowCount()-1)
3106 || index1
< 0 || index1
> (getRowCount()-1)))
3107 throw new IllegalArgumentException("Row index out of range.");
3109 getSelectionModel().setSelectionInterval(index0
, index1
);
3112 public void removeColumnSelectionInterval(int index0
, int index1
)
3114 if ((index0
< 0 || index0
> (getColumnCount()-1)
3115 || index1
< 0 || index1
> (getColumnCount()-1)))
3116 throw new IllegalArgumentException("Column index out of range.");
3118 getColumnModel().getSelectionModel().removeSelectionInterval(index0
, index1
);
3121 public void removeRowSelectionInterval(int index0
, int index1
)
3123 if ((index0
< 0 || index0
> (getRowCount()-1)
3124 || index1
< 0 || index1
> (getRowCount()-1)))
3125 throw new IllegalArgumentException("Row index out of range.");
3127 getSelectionModel().removeSelectionInterval(index0
, index1
);
3130 public boolean isColumnSelected(int column
)
3132 return getColumnModel().getSelectionModel().isSelectedIndex(column
);
3135 public boolean isRowSelected(int row
)
3137 return getSelectionModel().isSelectedIndex(row
);
3140 public boolean isCellSelected(int row
, int column
)
3142 return isRowSelected(row
) && isColumnSelected(column
);
3145 public void selectAll()
3147 // rowLead and colLead store the current lead selection indices
3148 int rowLead
= selectionModel
.getLeadSelectionIndex();
3149 int colLead
= getColumnModel().getSelectionModel().getLeadSelectionIndex();
3150 // the following calls to setSelectionInterval change the lead selection
3152 setColumnSelectionInterval(0, getColumnCount() - 1);
3153 setRowSelectionInterval(0, getRowCount() - 1);
3154 // the following addSelectionInterval calls restore the lead selection
3155 // indices to their previous values
3156 addColumnSelectionInterval(colLead
,colLead
);
3157 addRowSelectionInterval(rowLead
, rowLead
);
3160 public Object
getValueAt(int row
, int column
)
3162 return dataModel
.getValueAt(row
, convertColumnIndexToModel(column
));
3165 public void setValueAt(Object value
, int row
, int column
)
3167 if (!isCellEditable(row
, column
))
3170 if (value
instanceof Component
)
3171 add((Component
)value
);
3172 dataModel
.setValueAt(value
, row
, convertColumnIndexToModel(column
));
3175 public TableColumn
getColumn(Object identifier
)
3177 return columnModel
.getColumn(columnModel
.getColumnIndex(identifier
));
3181 * Returns <code>true</code> if the specified cell is editable, and
3182 * <code>false</code> otherwise.
3184 * @param row the row index.
3185 * @param column the column index.
3187 * @return A boolean.
3189 public boolean isCellEditable(int row
, int column
)
3191 return dataModel
.isCellEditable(row
, convertColumnIndexToModel(column
));
3195 * Clears any existing columns from the <code>JTable</code>'s
3196 * {@link TableColumnModel} and creates new columns to match the values in
3197 * the data ({@link TableModel}) used by the table.
3199 * @see #setAutoCreateColumnsFromModel(boolean)
3201 public void createDefaultColumnsFromModel()
3203 assert columnModel
!= null : "The columnModel must not be null.";
3205 // remove existing columns
3206 int columnIndex
= columnModel
.getColumnCount() - 1;
3207 while (columnIndex
>= 0)
3209 columnModel
.removeColumn(columnModel
.getColumn(columnIndex
));
3213 // add new columns to match the TableModel
3214 int columnCount
= dataModel
.getColumnCount();
3215 for (int c
= 0; c
< columnCount
; c
++)
3217 TableColumn column
= new TableColumn(c
);
3218 column
.setIdentifier(dataModel
.getColumnName(c
));
3219 column
.setHeaderValue(dataModel
.getColumnName(c
));
3220 columnModel
.addColumn(column
);
3221 column
.addPropertyChangeListener(tableColumnPropertyChangeHandler
);
3225 public void changeSelection (int rowIndex
, int columnIndex
, boolean toggle
, boolean extend
)
3227 if (toggle
&& extend
)
3229 // Leave the selection state as is, but move the anchor
3230 // index to the specified location
3231 selectionModel
.setAnchorSelectionIndex(rowIndex
);
3232 getColumnModel().getSelectionModel().setAnchorSelectionIndex(columnIndex
);
3236 // Toggle the state of the specified cell
3237 if (isCellSelected(rowIndex
,columnIndex
))
3239 selectionModel
.removeSelectionInterval(rowIndex
,rowIndex
);
3240 getColumnModel().getSelectionModel().removeSelectionInterval(columnIndex
,columnIndex
);
3244 selectionModel
.addSelectionInterval(rowIndex
,rowIndex
);
3245 getColumnModel().getSelectionModel().addSelectionInterval(columnIndex
,columnIndex
);
3250 // Extend the previous selection from the anchor to the
3251 // specified cell, clearing all other selections
3252 selectionModel
.setLeadSelectionIndex(rowIndex
);
3253 getColumnModel().getSelectionModel().setLeadSelectionIndex(columnIndex
);
3257 // Clear the previous selection and ensure the new cell
3259 selectionModel
.clearSelection();
3260 selectionModel
.setSelectionInterval(rowIndex
,rowIndex
);
3261 getColumnModel().getSelectionModel().clearSelection();
3262 getColumnModel().getSelectionModel().setSelectionInterval(columnIndex
, columnIndex
);
3269 * Programmatically starts editing the specified cell.
3271 * @param row the row of the cell to edit.
3272 * @param column the column of the cell to edit.
3274 public boolean editCellAt (int row
, int column
)
3276 oldCellValue
= getValueAt(row
, column
);
3277 setCellEditor(getCellEditor(row
, column
));
3278 editorComp
= prepareEditor(cellEditor
, row
, column
);
3279 cellEditor
.addCellEditorListener(this);
3280 rowBeingEdited
= row
;
3281 columnBeingEdited
= column
;
3282 setValueAt(editorComp
, row
, column
);
3283 ((JTextField
)editorComp
).requestFocusInWindow(false);
3284 editorTimer
.start();
3289 * Programmatically starts editing the specified cell.
3291 * @param row the row of the cell to edit.
3292 * @param column the column of the cell to edit.
3294 public boolean editCellAt (int row
, int column
, EventObject e
)
3296 return editCellAt(row
, column
);
3300 * Discards the editor object.
3302 public void removeEditor()
3304 editingStopped(new ChangeEvent(this));
3308 * Prepares the editor by querying for the value and selection state of the
3309 * cell at (row, column).
3311 * @param editor the TableCellEditor to set up
3312 * @param row the row of the cell to edit
3313 * @param column the column of the cell to edit
3314 * @return the Component being edited
3316 public Component
prepareEditor (TableCellEditor editor
, int row
, int column
)
3318 return editor
.getTableCellEditorComponent
3319 (this, getValueAt(row
, column
), isCellSelected(row
, column
), row
, column
);
3323 * This revalidates the <code>JTable</code> and queues a repaint.
3325 protected void resizeAndRepaint()
3332 * Sets whether cell editors of this table should receive keyboard focus
3333 * when the editor is activated by a keystroke. The default setting is
3334 * <code>false</code> which means that the table should keep the keyboard
3335 * focus until the cell is selected by a mouse click.
3337 * @param value the value to set
3341 public void setSurrendersFocusOnKeystroke(boolean value
)
3343 // TODO: Implement functionality of this property (in UI impl).
3344 surrendersFocusOnKeystroke
= value
;
3348 * Returns whether cell editors of this table should receive keyboard focus
3349 * when the editor is activated by a keystroke. The default setting is
3350 * <code>false</code> which means that the table should keep the keyboard
3351 * focus until the cell is selected by a mouse click.
3353 * @return whether cell editors of this table should receive keyboard focus
3354 * when the editor is activated by a keystroke
3358 public boolean getSurrendersFocusOnKeystroke()
3360 // TODO: Implement functionality of this property (in UI impl).
3361 return surrendersFocusOnKeystroke
;