summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/table
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/table')
-rw-r--r--libjava/classpath/javax/swing/table/AbstractTableModel.java303
-rw-r--r--libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java276
-rw-r--r--libjava/classpath/javax/swing/table/DefaultTableColumnModel.java671
-rw-r--r--libjava/classpath/javax/swing/table/DefaultTableModel.java634
-rw-r--r--libjava/classpath/javax/swing/table/JTableHeader.java1055
-rw-r--r--libjava/classpath/javax/swing/table/TableCellEditor.java65
-rw-r--r--libjava/classpath/javax/swing/table/TableCellRenderer.java66
-rw-r--r--libjava/classpath/javax/swing/table/TableColumn.java693
-rw-r--r--libjava/classpath/javax/swing/table/TableColumnModel.java232
-rw-r--r--libjava/classpath/javax/swing/table/TableModel.java134
-rw-r--r--libjava/classpath/javax/swing/table/package.html47
11 files changed, 4176 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/table/AbstractTableModel.java b/libjava/classpath/javax/swing/table/AbstractTableModel.java
new file mode 100644
index 000000000..7e9886d30
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/AbstractTableModel.java
@@ -0,0 +1,303 @@
+/* AbstractTableModel.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.io.Serializable;
+import java.util.EventListener;
+
+import javax.swing.event.EventListenerList;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+
+/**
+ * A base class that can be used to create implementations of the
+ * {@link TableModel} interface.
+ *
+ * @author Andrew Selkirk
+ */
+public abstract class AbstractTableModel implements TableModel, Serializable
+{
+ static final long serialVersionUID = -5798593159423650347L;
+
+ /**
+ * Storage for the listeners registered with this model.
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * Creates a default instance.
+ */
+ public AbstractTableModel()
+ {
+ // no setup required here
+ }
+
+ /**
+ * Returns the name of the specified column. This method generates default
+ * names in a sequence (starting with column 0): A, B, C, ..., Z, AA, AB,
+ * AC, ..., AZ, BA, BB, BC, and so on. Subclasses may override this method
+ * to allow column names to be specified on some other basis.
+ *
+ * @param columnIndex the column index.
+ *
+ * @return The name of the column.
+ */
+ public String getColumnName(int columnIndex)
+ {
+ CPStringBuilder buffer = new CPStringBuilder();
+ while (columnIndex >= 0)
+ {
+ buffer.insert(0, (char) ('A' + columnIndex % 26));
+ columnIndex = columnIndex / 26 - 1;
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Return the index of the specified column, or <code>-1</code> if there is
+ * no column with the specified name.
+ *
+ * @param columnName the name of the column (<code>null</code> not permitted).
+ *
+ * @return The index of the column, -1 if not found.
+ *
+ * @see #getColumnName(int)
+ * @throws NullPointerException if <code>columnName</code> is
+ * <code>null</code>.
+ */
+ public int findColumn(String columnName)
+ {
+ int count = getColumnCount();
+
+ for (int index = 0; index < count; index++)
+ {
+ String name = getColumnName(index);
+
+ if (columnName.equals(name))
+ return index;
+ }
+
+ // Unable to locate.
+ return -1;
+ }
+
+ /**
+ * Returns the <code>Class</code> for all <code>Object</code> instances
+ * in the specified column.
+ *
+ * @param columnIndex the column index.
+ *
+ * @return The class.
+ */
+ public Class<?> getColumnClass(int columnIndex)
+ {
+ return Object.class;
+ }
+
+ /**
+ * Returns <code>true</code> if the specified cell is editable, and
+ * <code>false</code> if it is not. This implementation returns
+ * <code>false</code> for all arguments, subclasses should override the
+ * method if necessary.
+ *
+ * @param rowIndex the row index of the cell.
+ * @param columnIndex the column index of the cell.
+ *
+ * @return <code>false</code>.
+ */
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ return false;
+ }
+
+ /**
+ * Sets the value of the given cell. This implementation ignores all
+ * arguments and does nothing, subclasses should override the
+ * method if necessary.
+ *
+ * @param value the new value (<code>null</code> permitted).
+ * @param rowIndex the row index of the cell.
+ * @param columnIndex the column index of the cell.
+ */
+ public void setValueAt(Object value, int rowIndex, int columnIndex)
+ {
+ // Do nothing...
+ }
+
+ /**
+ * Adds a listener to the table model. The listener will receive notification
+ * of all changes to the table model.
+ *
+ * @param listener the listener.
+ */
+ public void addTableModelListener(TableModelListener listener)
+ {
+ listenerList.add(TableModelListener.class, listener);
+ }
+
+ /**
+ * Removes a listener from the table model so that it will no longer receive
+ * notification of changes to the table model.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeTableModelListener(TableModelListener listener)
+ {
+ listenerList.remove(TableModelListener.class, listener);
+ }
+
+ /**
+ * Returns an array containing the listeners that have been added to the
+ * table model.
+ *
+ * @return Array of {@link TableModelListener} objects.
+ *
+ * @since 1.4
+ */
+ public TableModelListener[] getTableModelListeners()
+ {
+ return (TableModelListener[])
+ listenerList.getListeners(TableModelListener.class);
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that the table data has changed.
+ */
+ public void fireTableDataChanged()
+ {
+ fireTableChanged(new TableModelEvent(this, 0, Integer.MAX_VALUE));
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that the table structure has changed.
+ */
+ public void fireTableStructureChanged()
+ {
+ fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that some rows have been inserted into the model.
+ *
+ * @param firstRow the index of the first row.
+ * @param lastRow the index of the last row.
+ */
+ public void fireTableRowsInserted(int firstRow, int lastRow)
+ {
+ fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
+ TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.INSERT));
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that some rows have been updated.
+ *
+ * @param firstRow the index of the first row.
+ * @param lastRow the index of the last row.
+ */
+ public void fireTableRowsUpdated(int firstRow, int lastRow)
+ {
+ fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
+ TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.UPDATE));
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that some rows have been deleted from the model.
+ *
+ * @param firstRow the index of the first row.
+ * @param lastRow the index of the last row.
+ */
+ public void fireTableRowsDeleted(int firstRow, int lastRow)
+ {
+ fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
+ TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.DELETE));
+ }
+
+ /**
+ * Sends a {@link TableModelEvent} to all registered listeners to inform
+ * them that a single cell has been updated.
+ *
+ * @param row the row index.
+ * @param column the column index.
+ */
+ public void fireTableCellUpdated(int row, int column)
+ {
+ fireTableChanged(new TableModelEvent(this, row, row, column));
+ }
+
+ /**
+ * Sends the specified event to all registered listeners.
+ *
+ * @param event the event to send.
+ */
+ public void fireTableChanged(TableModelEvent event)
+ {
+ int index;
+ TableModelListener listener;
+ Object[] list = listenerList.getListenerList();
+
+ for (index = 0; index < list.length; index += 2)
+ {
+ listener = (TableModelListener) list [index + 1];
+ listener.tableChanged(event);
+ }
+ }
+
+ /**
+ * Returns an array of listeners of the given type that are registered with
+ * this model.
+ *
+ * @param listenerType the listener class.
+ *
+ * @return An array of listeners (possibly empty).
+ */
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
new file mode 100644
index 000000000..5d4a16024
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
@@ -0,0 +1,276 @@
+/* DefaultTableCellRenderer.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.io.Serializable;
+
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * Class to display every cells.
+ */
+public class DefaultTableCellRenderer extends JLabel
+ implements TableCellRenderer, Serializable
+{
+ static final long serialVersionUID = 7878911414715528324L;
+
+ protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+
+ public static class UIResource extends DefaultTableCellRenderer
+ implements javax.swing.plaf.UIResource
+ {
+ public UIResource()
+ {
+ super();
+ }
+ }
+
+ /**
+ * Stores the color set by setForeground().
+ */
+ Color foreground;
+
+ /**
+ * Stores the color set by setBackground().
+ */
+ Color background;
+
+ /**
+ * Creates a default table cell renderer with an empty border.
+ */
+ public DefaultTableCellRenderer()
+ {
+ super();
+ }
+
+ /**
+ * Assign the unselected-foreground.
+ *
+ * @param c the color to assign
+ */
+ public void setForeground(Color c)
+ {
+ super.setForeground(c);
+ foreground = c;
+ }
+
+ /**
+ * Assign the unselected-background.
+ *
+ * @param c the color to assign
+ */
+ public void setBackground(Color c)
+ {
+ super.setBackground(c);
+ background = c;
+ }
+
+ /**
+ * Look and feel has changed.
+ *
+ * <p>Replaces the current UI object with the latest version from
+ * the UIManager.</p>
+ */
+ public void updateUI()
+ {
+ super.updateUI();
+ background = null;
+ foreground = null;
+ }
+
+ /**
+ * Get the string value of the object and pass it to setText().
+ *
+ * @param table the JTable
+ * @param value the value of the object. For the text content,
+ * null is rendered as an empty cell.
+ * @param isSelected is the cell selected?
+ * @param hasFocus has the cell the focus?
+ * @param row the row to render
+ * @param column the cell to render
+ *
+ * @return this component (the default table cell renderer)
+ */
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row, int column)
+ {
+ setValue(value);
+ setOpaque(true);
+
+ if (table == null)
+ return this;
+
+ if (isSelected)
+ {
+ super.setBackground(table.getSelectionBackground());
+ super.setForeground(table.getSelectionForeground());
+ }
+ else
+ {
+ if (background != null)
+ super.setBackground(background);
+ else
+ super.setBackground(table.getBackground());
+ if (foreground != null)
+ super.setForeground(foreground);
+ else
+ super.setForeground(table.getForeground());
+ }
+
+ Border b = null;
+ if (hasFocus)
+ {
+ if (isSelected)
+ b = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
+ if (b == null)
+ b = UIManager.getBorder("Table.focusCellHighlightBorder");
+ }
+ else
+ b = noFocusBorder;
+ setBorder(b);
+
+ setFont(table.getFont());
+
+ // If the current background is equal to the table's background, then we
+ // can avoid filling the background by setting the renderer opaque.
+ Color back = getBackground();
+ setOpaque(back != null && back.equals(table.getBackground()));
+
+ return this;
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ *
+ * @return always true
+ */
+ public boolean isOpaque()
+ {
+ return true;
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ */
+ public void validate()
+ {
+ // Does nothing.
+ }
+
+ public void revalidate()
+ {
+ // Does nothing.
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ */
+ public void repaint(long tm, int x, int y, int width, int height)
+ {
+ // Does nothing.
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ */
+ public void repaint(Rectangle r)
+ {
+ // Does nothing.
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ */
+ protected void firePropertyChange(String propertyName, Object oldValue,
+ Object newValue)
+ {
+ // Does nothing.
+ }
+
+ /**
+ * Overriden for performance.
+ *
+ * <p>This method needs to be overridden in a subclass to actually
+ * do something.</p>
+ */
+ public void firePropertyChange(String propertyName, boolean oldValue,
+ boolean newValue)
+ {
+ // Does nothing.
+ }
+
+ /**
+ * Sets the String for this cell.
+ *
+ * @param value the string value for this cell; if value is null it
+ * sets the text value to an empty string
+ */
+ protected void setValue(Object value)
+ {
+ if (value != null)
+ setText(value.toString());
+ else
+ // null is rendered as an empty cell.
+ setText("");
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java b/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java
new file mode 100644
index 000000000..532b513a9
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java
@@ -0,0 +1,671 @@
+/* DefaultTableColumnModel.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Vector;
+
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableColumnModelEvent;
+import javax.swing.event.TableColumnModelListener;
+
+/**
+ * A model that stores information about the columns used in a {@link JTable}.
+ *
+ * @see JTable#setColumnModel(TableColumnModel)
+ *
+ * @author Andrew Selkirk
+ */
+public class DefaultTableColumnModel
+ implements TableColumnModel, PropertyChangeListener, ListSelectionListener,
+ Serializable
+{
+ private static final long serialVersionUID = 6580012493508960512L;
+
+ /**
+ * Storage for the table columns.
+ */
+ protected Vector<TableColumn> tableColumns;
+
+ /**
+ * A selection model that keeps track of column selections.
+ */
+ protected ListSelectionModel selectionModel;
+
+ /**
+ * The space between the columns (the default value is <code>1</code>).
+ */
+ protected int columnMargin;
+
+ /**
+ * Storage for the listeners registered with the model.
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * A change event used when notifying listeners of a change to the
+ * <code>columnMargin</code> field. This single event is reused for all
+ * notifications (it is lazily instantiated within the
+ * {@link #fireColumnMarginChanged()} method).
+ */
+ protected transient ChangeEvent changeEvent;
+
+ /**
+ * A flag that indicates whether or not columns can be selected.
+ */
+ protected boolean columnSelectionAllowed;
+
+ /**
+ * The total width of all the columns in this model.
+ */
+ protected int totalColumnWidth;
+
+ /**
+ * Creates a new table column model with zero columns. A default column
+ * selection model is created by calling {@link #createSelectionModel()}.
+ * The default value for <code>columnMargin</code> is <code>1</code> and
+ * the default value for <code>columnSelectionAllowed</code> is
+ * <code>false</code>.
+ */
+ public DefaultTableColumnModel()
+ {
+ tableColumns = new Vector();
+ selectionModel = createSelectionModel();
+ selectionModel.addListSelectionListener(this);
+ columnMargin = 1;
+ columnSelectionAllowed = false;
+ }
+
+ /**
+ * Adds a column to the model then calls
+ * {@link #fireColumnAdded(TableColumnModelEvent)} to notify the registered
+ * listeners. The model registers itself with the column as a
+ * {@link PropertyChangeListener} so that changes to the column width will
+ * invalidate the cached {@link #totalColumnWidth} value.
+ *
+ * @param column the column (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>column</code> is
+ * <code>null</code>.
+ *
+ * @see #removeColumn(TableColumn)
+ */
+ public void addColumn(TableColumn column)
+ {
+ if (column == null)
+ throw new IllegalArgumentException("Null 'col' argument.");
+ tableColumns.add(column);
+ column.addPropertyChangeListener(this);
+ invalidateWidthCache();
+ fireColumnAdded(new TableColumnModelEvent(this, 0,
+ tableColumns.size() - 1));
+ }
+
+ /**
+ * Removes a column from the model then calls
+ * {@link #fireColumnRemoved(TableColumnModelEvent)} to notify the registered
+ * listeners. If the specified column does not belong to the model, or is
+ * <code>null</code>, this method does nothing.
+ *
+ * @param column the column to be removed (<code>null</code> permitted).
+ *
+ * @see #addColumn(TableColumn)
+ */
+ public void removeColumn(TableColumn column)
+ {
+ int index = this.tableColumns.indexOf(column);
+ if (index < 0)
+ return;
+ tableColumns.remove(column);
+ fireColumnRemoved(new TableColumnModelEvent(this, index, 0));
+ column.removePropertyChangeListener(this);
+ invalidateWidthCache();
+ }
+
+ /**
+ * Moves the column at index i to the position specified by index j, then
+ * calls {@link #fireColumnMoved(TableColumnModelEvent)} to notify registered
+ * listeners.
+ *
+ * @param i index of the column that will be moved.
+ * @param j index of the column's new location.
+ *
+ * @throws IllegalArgumentException if <code>i</code> or <code>j</code> are
+ * outside the range <code>0</code> to <code>N-1</code>, where
+ * <code>N</code> is the column count.
+ */
+ public void moveColumn(int i, int j)
+ {
+ int columnCount = getColumnCount();
+ if (i < 0 || i >= columnCount)
+ throw new IllegalArgumentException("Index 'i' out of range.");
+ if (j < 0 || j >= columnCount)
+ throw new IllegalArgumentException("Index 'j' out of range.");
+ TableColumn column = tableColumns.remove(i);
+ tableColumns.add(j, column);
+ fireColumnMoved(new TableColumnModelEvent(this, i, j));
+ }
+
+ /**
+ * Sets the column margin then calls {@link #fireColumnMarginChanged()} to
+ * notify the registered listeners.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
+ */
+ public void setColumnMargin(int margin)
+ {
+ columnMargin = margin;
+ fireColumnMarginChanged();
+ }
+
+ /**
+ * Returns the number of columns in the model.
+ *
+ * @return The column count.
+ */
+ public int getColumnCount()
+ {
+ return tableColumns.size();
+ }
+
+ /**
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
+ */
+ public Enumeration<TableColumn> getColumns()
+ {
+ return tableColumns.elements();
+ }
+
+ /**
+ * Returns the index of the {@link TableColumn} with the given identifier.
+ *
+ * @param identifier the identifier (<code>null</code> not permitted).
+ *
+ * @return The index of the {@link TableColumn} with the given identifier.
+ *
+ * @throws IllegalArgumentException if <code>identifier</code> is
+ * <code>null</code> or there is no column with that identifier.
+ */
+ public int getColumnIndex(Object identifier)
+ {
+ if (identifier == null)
+ throw new IllegalArgumentException("Null identifier.");
+ int columnCount = tableColumns.size();
+ for (int i = 0; i < columnCount; i++)
+ {
+ TableColumn tc = tableColumns.get(i);
+ if (identifier.equals(tc.getIdentifier()))
+ return i;
+ }
+ throw new IllegalArgumentException("No TableColumn with that identifier.");
+ }
+
+ /**
+ * Returns the column at the specified index.
+ *
+ * @param columnIndex the column index (in the range from <code>0</code> to
+ * <code>N-1</code>, where <code>N</code> is the number of columns in
+ * the model).
+ *
+ * @return The column at the specified index.
+ *
+ * @throws ArrayIndexOutOfBoundsException if <code>i</code> is not within
+ * the specified range.
+ */
+ public TableColumn getColumn(int columnIndex)
+ {
+ return tableColumns.get(columnIndex);
+ }
+
+ /**
+ * Returns the column margin.
+ *
+ * @return The column margin.
+ *
+ * @see #setColumnMargin(int)
+ */
+ public int getColumnMargin()
+ {
+ return columnMargin;
+ }
+
+ /**
+ * Returns the index of the column that contains the specified x-coordinate.
+ * This method assumes that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param x the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
+ */
+ public int getColumnIndexAtX(int x)
+ {
+ for (int i = 0; i < tableColumns.size(); ++i)
+ {
+ int w = (tableColumns.get(i)).getWidth();
+ if (0 <= x && x < w)
+ return i;
+ else
+ x -= w;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns total width of all the columns in the model, ignoring the
+ * {@link #columnMargin}.
+ *
+ * @return The total width of all the columns.
+ */
+ public int getTotalColumnWidth()
+ {
+ if (totalColumnWidth == -1)
+ recalcWidthCache();
+ return totalColumnWidth;
+ }
+
+ /**
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
+ *
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
+ *
+ * @see #getSelectionModel()
+ */
+ public void setSelectionModel(ListSelectionModel model)
+ {
+ if (model == null)
+ throw new IllegalArgumentException();
+
+ selectionModel.removeListSelectionListener(this);
+ selectionModel = model;
+ selectionModel.addListSelectionListener(this);
+ }
+
+ /**
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
+ */
+ public ListSelectionModel getSelectionModel()
+ {
+ return selectionModel;
+ }
+
+ /**
+ * Sets the flag that indicates whether or not column selection is allowed.
+ *
+ * @param flag the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
+ */
+ public void setColumnSelectionAllowed(boolean flag)
+ {
+ columnSelectionAllowed = flag;
+ }
+
+ /**
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
+ *
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
+ */
+ public boolean getColumnSelectionAllowed()
+ {
+ return columnSelectionAllowed;
+ }
+
+ /**
+ * Returns an array containing the indices of the selected columns.
+ *
+ * @return An array containing the indices of the selected columns.
+ */
+ public int[] getSelectedColumns()
+ {
+ // FIXME: Implementation of this method was taken from private method
+ // JTable.getSelections(), which is used in various places in JTable
+ // including selected row calculations and cannot be simply removed.
+ // This design should be improved to illuminate duplication of code.
+
+ ListSelectionModel lsm = this.selectionModel;
+ int sz = getSelectedColumnCount();
+ int [] ret = new int[sz];
+
+ int lo = lsm.getMinSelectionIndex();
+ int hi = lsm.getMaxSelectionIndex();
+ int j = 0;
+ java.util.ArrayList ls = new java.util.ArrayList();
+ if (lo != -1 && hi != -1)
+ {
+ switch (lsm.getSelectionMode())
+ {
+ case ListSelectionModel.SINGLE_SELECTION:
+ ret[0] = lo;
+ break;
+
+ case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
+ for (int i = lo; i <= hi; ++i)
+ ret[j++] = i;
+ break;
+
+ case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:
+ for (int i = lo; i <= hi; ++i)
+ if (lsm.isSelectedIndex(i))
+ ret[j++] = i;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
+ */
+ public int getSelectedColumnCount()
+ {
+ // FIXME: Implementation of this method was taken from private method
+ // JTable.countSelections(), which is used in various places in JTable
+ // including selected row calculations and cannot be simply removed.
+ // This design should be improved to illuminate duplication of code.
+
+ ListSelectionModel lsm = this.selectionModel;
+ int lo = lsm.getMinSelectionIndex();
+ int hi = lsm.getMaxSelectionIndex();
+ int sum = 0;
+
+ if (lo != -1 && hi != -1)
+ {
+ switch (lsm.getSelectionMode())
+ {
+ case ListSelectionModel.SINGLE_SELECTION:
+ sum = 1;
+ break;
+
+ case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
+ sum = hi - lo + 1;
+ break;
+
+ case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:
+ for (int i = lo; i <= hi; ++i)
+ if (lsm.isSelectedIndex(i))
+ ++sum;
+ break;
+ }
+ }
+
+ return sum;
+ }
+
+ /**
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener (<code>null</code> ignored).
+ */
+ public void addColumnModelListener(TableColumnModelListener listener)
+ {
+ listenerList.add(TableColumnModelListener.class, listener);
+ }
+
+ /**
+ * Deregisters a listener so that it no longer receives notification of
+ * changes to this model.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeColumnModelListener(TableColumnModelListener listener)
+ {
+ listenerList.remove(TableColumnModelListener.class, listener);
+ }
+
+ /**
+ * Returns an array containing the listeners that are registered with the
+ * model. If there are no listeners, an empty array is returned.
+ *
+ * @return An array containing the listeners that are registered with the
+ * model.
+ *
+ * @see #addColumnModelListener(TableColumnModelListener)
+ * @since 1.4
+ */
+ public TableColumnModelListener[] getColumnModelListeners()
+ {
+ return (TableColumnModelListener[])
+ listenerList.getListeners(TableColumnModelListener.class);
+ }
+
+ /**
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been added to the model. The
+ * event's <code>toIndex</code> attribute should contain the index of the
+ * added column.
+ *
+ * @param e the event.
+ *
+ * @see #addColumn(TableColumn)
+ */
+ protected void fireColumnAdded(TableColumnModelEvent e)
+ {
+ TableColumnModelListener[] listeners = getColumnModelListeners();
+
+ for (int i = 0; i < listeners.length; i++)
+ listeners[i].columnAdded(e);
+ }
+
+ /**
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been removed from the model. The
+ * event's <code>fromIndex</code> attribute should contain the index of the
+ * removed column.
+ *
+ * @param e the event.
+ *
+ * @see #removeColumn(TableColumn)
+ */
+ protected void fireColumnRemoved(TableColumnModelEvent e)
+ {
+ TableColumnModelListener[] listeners = getColumnModelListeners();
+
+ for (int i = 0; i < listeners.length; i++)
+ listeners[i].columnRemoved(e);
+ }
+
+ /**
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column in the model has been moved. The
+ * event's <code>fromIndex</code> attribute should contain the old column
+ * index, and the <code>toIndex</code> attribute should contain the new
+ * column index.
+ *
+ * @param e the event.
+ *
+ * @see #moveColumn(int, int)
+ */
+ protected void fireColumnMoved(TableColumnModelEvent e)
+ {
+ TableColumnModelListener[] listeners = getColumnModelListeners();
+
+ for (int i = 0; i < listeners.length; i++)
+ listeners[i].columnMoved(e);
+ }
+
+ /**
+ * Sends the specified {@link ListSelectionEvent} to all registered listeners,
+ * to indicate that the column selections have changed.
+ *
+ * @param e the event.
+ *
+ * @see #valueChanged(ListSelectionEvent)
+ */
+ protected void fireColumnSelectionChanged(ListSelectionEvent e)
+ {
+ EventListener [] listeners = getListeners(TableColumnModelListener.class);
+ for (int i = 0; i < listeners.length; ++i)
+ ((TableColumnModelListener) listeners[i]).columnSelectionChanged(e);
+ }
+
+ /**
+ * Sends a {@link ChangeEvent} to the model's registered listeners to
+ * indicate that the column margin was changed.
+ *
+ * @see #setColumnMargin(int)
+ */
+ protected void fireColumnMarginChanged()
+ {
+ EventListener[] listeners = getListeners(TableColumnModelListener.class);
+ if (changeEvent == null && listeners.length > 0)
+ changeEvent = new ChangeEvent(this);
+ for (int i = 0; i < listeners.length; ++i)
+ ((TableColumnModelListener) listeners[i]).columnMarginChanged(changeEvent);
+ }
+
+ /**
+ * Returns an array containing the listeners (of the specified type) that
+ * are registered with this model.
+ *
+ * @param listenerType the listener type (must indicate a subclass of
+ * {@link EventListener}, <code>null</code> not permitted).
+ *
+ * @return An array containing the listeners (of the specified type) that
+ * are registered with this model.
+ */
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+
+ /**
+ * Receives notification of property changes for the columns in the model.
+ * If the <code>width</code> property for any column changes, we invalidate
+ * the {@link #totalColumnWidth} value here.
+ *
+ * @param event the event.
+ */
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ if (event.getPropertyName().equals("width"))
+ invalidateWidthCache();
+ }
+
+ /**
+ * Receives notification of the change to the list selection model, and
+ * responds by calling
+ * {@link #fireColumnSelectionChanged(ListSelectionEvent)}.
+ *
+ * @param e the list selection event.
+ *
+ * @see #getSelectionModel()
+ */
+ public void valueChanged(ListSelectionEvent e)
+ {
+ fireColumnSelectionChanged(e);
+ }
+
+ /**
+ * Creates a default selection model to track the currently selected
+ * column(s). This method is called by the constructor and returns a new
+ * instance of {@link DefaultListSelectionModel}.
+ *
+ * @return A new default column selection model.
+ */
+ protected ListSelectionModel createSelectionModel()
+ {
+ return new DefaultListSelectionModel();
+ }
+
+ /**
+ * Recalculates the total width of the columns, if the cached value is
+ * <code>-1</code>. Otherwise this method does nothing.
+ *
+ * @see #getTotalColumnWidth()
+ */
+ protected void recalcWidthCache()
+ {
+ if (totalColumnWidth == -1)
+ {
+ totalColumnWidth = 0;
+ for (int i = 0; i < tableColumns.size(); ++i)
+ {
+ totalColumnWidth += tableColumns.get(i).getWidth();
+ }
+ }
+ }
+
+ /**
+ * Sets the {@link #totalColumnWidth} field to <code>-1</code>.
+ *
+ * @see #recalcWidthCache()
+ */
+ private void invalidateWidthCache()
+ {
+ totalColumnWidth = -1;
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/DefaultTableModel.java b/libjava/classpath/javax/swing/table/DefaultTableModel.java
new file mode 100644
index 000000000..e1d5e6888
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/DefaultTableModel.java
@@ -0,0 +1,634 @@
+/* DefaultTableModel.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.io.Serializable;
+import java.util.Vector;
+
+import javax.swing.event.TableModelEvent;
+
+/**
+ * A two dimensional data structure used to store <code>Object</code>
+ * instances, usually for display in a <code>JTable</code> component.
+ *
+ * @author Andrew Selkirk
+ */
+public class DefaultTableModel extends AbstractTableModel
+ implements Serializable
+{
+ static final long serialVersionUID = 6680042567037222321L;
+
+ /**
+ * Storage for the rows in the table (each row is itself
+ * a <code>Vector</code>).
+ */
+ protected Vector dataVector;
+
+ /**
+ * Storage for the column identifiers.
+ */
+ protected Vector columnIdentifiers;
+
+ /**
+ * Creates an empty table with zero rows and zero columns.
+ */
+ public DefaultTableModel()
+ {
+ this(0, 0);
+ }
+
+ /**
+ * Creates a new table with the specified number of rows and columns.
+ * All cells in the table are initially empty (set to <code>null</code>).
+ *
+ * @param numRows the number of rows.
+ * @param numColumns the number of columns.
+ */
+ public DefaultTableModel(int numRows, int numColumns)
+ {
+ Vector defaultNames = new Vector(numColumns);
+ Vector data = new Vector(numRows);
+ for (int i = 0; i < numColumns; i++)
+ {
+ defaultNames.add(super.getColumnName(i));
+ }
+ for (int r = 0; r < numRows; r++)
+ {
+ Vector tmp = new Vector(numColumns);
+ tmp.setSize(numColumns);
+ data.add(tmp);
+ }
+ setDataVector(data, defaultNames);
+ }
+
+ /**
+ * Creates a new table with the specified column names and number of
+ * rows. The number of columns is determined by the number of column
+ * names supplied.
+ *
+ * @param columnNames the column names.
+ * @param numRows the number of rows.
+ */
+ public DefaultTableModel(Vector columnNames, int numRows)
+ {
+ if (numRows < 0)
+ throw new IllegalArgumentException("numRows < 0");
+ Vector data = new Vector();
+ int numColumns = 0;
+
+ if (columnNames != null)
+ numColumns = columnNames.size();
+
+ while (0 < numRows--)
+ {
+ Vector rowData = new Vector();
+ rowData.setSize(numColumns);
+ data.add(rowData);
+ }
+ setDataVector(data, columnNames);
+ }
+
+ /**
+ * Creates a new table with the specified column names and row count.
+ *
+ * @param columnNames the column names.
+ * @param numRows the number of rows.
+ */
+ public DefaultTableModel(Object[] columnNames, int numRows)
+ {
+ this(convertToVector(columnNames), numRows);
+ }
+
+ /**
+ * Creates a new table with the specified data values and column names.
+ *
+ * @param data the data values.
+ * @param columnNames the column names.
+ */
+ public DefaultTableModel(Vector data, Vector columnNames)
+ {
+ setDataVector(data, columnNames);
+ }
+
+ /**
+ * Creates a new table with the specified data values and column names.
+ *
+ * @param data the data values.
+ * @param columnNames the column names.
+ */
+ public DefaultTableModel(Object[][] data, Object[] columnNames)
+ {
+ this(convertToVector(data), convertToVector(columnNames));
+ }
+
+ /**
+ * Returns the vector containing the row data for the table.
+ *
+ * @return The data vector.
+ */
+ public Vector getDataVector()
+ {
+ return dataVector;
+ }
+
+ /**
+ * Sets the data and column identifiers for the table. The data vector
+ * contains a <code>Vector</code> for each row in the table - if the
+ * number of objects in each row does not match the number of column
+ * names specified, the row data is truncated or expanded (by adding
+ * <code>null</code> values) as required.
+ *
+ * @param data the data for the table (a vector of row vectors).
+ * @param columnNames the column names.
+ *
+ * @throws NullPointerException if either argument is <code>null</code>.
+ */
+ public void setDataVector(Vector data, Vector columnNames)
+ {
+ if (data == null)
+ dataVector = new Vector();
+ else
+ dataVector = data;
+ setColumnIdentifiers(columnNames);
+ }
+
+ /**
+ * Sets the data and column identifiers for the table.
+ *
+ * @param data the data for the table.
+ * @param columnNames the column names.
+ *
+ * @throws NullPointerException if either argument is <code>null</code>.
+ */
+ public void setDataVector(Object[][] data, Object[] columnNames)
+ {
+ setDataVector(convertToVector(data),
+ convertToVector(columnNames));
+ }
+
+ /**
+ * Sends the specified <code>event</code> to all registered listeners.
+ * This method is equivalent to
+ * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
+ *
+ * @param event the event.
+ */
+ public void newDataAvailable(TableModelEvent event)
+ {
+ fireTableChanged(event);
+ }
+
+ /**
+ * Sends the specified <code>event</code> to all registered listeners.
+ * This method is equivalent to
+ * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
+ *
+ * @param event the event.
+ */
+ public void newRowsAdded(TableModelEvent event)
+ {
+ fireTableChanged(event);
+ }
+
+ /**
+ * Sends the specified <code>event</code> to all registered listeners.
+ * This method is equivalent to
+ * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
+ *
+ * @param event the event.
+ */
+ public void rowsRemoved(TableModelEvent event)
+ {
+ fireTableChanged(event);
+ }
+
+ /**
+ * Sets the column identifiers, updates the data rows (truncating
+ * or padding each row with <code>null</code> values) to match the
+ * number of columns, and sends a {@link TableModelEvent} to all
+ * registered listeners.
+ *
+ * @param columnIdentifiers the column identifiers.
+ */
+ public void setColumnIdentifiers(Vector columnIdentifiers)
+ {
+ this.columnIdentifiers = columnIdentifiers;
+ setColumnCount(columnIdentifiers == null ? 0 : columnIdentifiers.size());
+ }
+
+ /**
+ * Sets the column identifiers, updates the data rows (truncating
+ * or padding each row with <code>null</code> values) to match the
+ * number of columns, and sends a {@link TableModelEvent} to all
+ * registered listeners.
+ *
+ * @param columnIdentifiers the column identifiers.
+ */
+ public void setColumnIdentifiers(Object[] columnIdentifiers)
+ {
+ setColumnIdentifiers(convertToVector(columnIdentifiers));
+ }
+
+ /**
+ * This method is obsolete, use {@link #setRowCount(int)} instead.
+ *
+ * @param numRows the number of rows.
+ */
+ public void setNumRows(int numRows)
+ {
+ setRowCount(numRows);
+ }
+
+ /**
+ * Sets the number of rows in the table. If <code>rowCount</code> is less
+ * than the current number of rows in the table, rows are discarded.
+ * If <code>rowCount</code> is greater than the current number of rows in
+ * the table, new (empty) rows are added.
+ *
+ * @param rowCount the row count.
+ */
+ public void setRowCount(int rowCount)
+ {
+ int existingRowCount = dataVector.size();
+ if (rowCount < existingRowCount)
+ {
+ dataVector.setSize(rowCount);
+ fireTableRowsDeleted(rowCount, existingRowCount - 1);
+ }
+ else
+ {
+ int rowsToAdd = rowCount - existingRowCount;
+ addExtraRows(rowsToAdd, columnIdentifiers.size());
+ fireTableRowsInserted(existingRowCount, rowCount - 1);
+ }
+ }
+
+ /**
+ * Sets the number of columns in the table. Existing rows are truncated
+ * or padded with <code>null</code> values to match the new column count.
+ * A {@link TableModelEvent} is sent to all registered listeners.
+ *
+ * @param columnCount the column count.
+ */
+ public void setColumnCount(int columnCount)
+ {
+ for (int i = 0; i < dataVector.size(); ++i)
+ {
+ ((Vector) dataVector.get(i)).setSize(columnCount);
+ }
+ if (columnIdentifiers != null)
+ columnIdentifiers.setSize(columnCount);
+ fireTableStructureChanged();
+ }
+
+ /**
+ * Adds a column with the specified name to the table. All cell values
+ * for the column are initially set to <code>null</code>.
+ *
+ * @param columnName the column name (<code>null</code> permitted).
+ */
+ public void addColumn(Object columnName)
+ {
+ addColumn(columnName, (Object[]) null);
+ }
+
+ /**
+ * Adds a column with the specified name and data values to the table.
+ *
+ * @param columnName the column name (<code>null</code> permitted).
+ * @param columnData the column data.
+ */
+ public void addColumn(Object columnName, Vector columnData)
+ {
+ Object[] dataArray = null;
+ if (columnData != null)
+ {
+ int rowCount = dataVector.size();
+ if (columnData.size() < rowCount)
+ columnData.setSize(rowCount);
+ dataArray = columnData.toArray();
+ }
+ addColumn(columnName, dataArray);
+ }
+
+ /**
+ * Adds a column with the specified name and data values to the table.
+ *
+ * @param columnName the column name (<code>null</code> permitted).
+ * @param columnData the column data.
+ */
+ public void addColumn(Object columnName, Object[] columnData)
+ {
+ if (columnData != null)
+ {
+ // check columnData array for cases where the number of items
+ // doesn't match the number of rows in the existing table
+ if (columnData.length > dataVector.size())
+ {
+ int rowsToAdd = columnData.length - dataVector.size();
+ addExtraRows(rowsToAdd, columnIdentifiers.size());
+ }
+ else if (columnData.length < dataVector.size())
+ {
+ Object[] tmp = new Object[dataVector.size()];
+ System.arraycopy(columnData, 0, tmp, 0, columnData.length);
+ columnData = tmp;
+ }
+ }
+ for (int i = 0; i < dataVector.size(); ++i)
+ {
+ ((Vector) dataVector.get(i)).add(columnData == null ? null : columnData[i]);
+ }
+ columnIdentifiers.add(columnName);
+ fireTableStructureChanged();
+ }
+
+ /**
+ * Adds a new row containing the specified data to the table and sends a
+ * {@link TableModelEvent} to all registered listeners.
+ *
+ * @param rowData the row data (<code>null</code> permitted).
+ */
+ public void addRow(Vector rowData)
+ {
+ int rowIndex = dataVector.size();
+ dataVector.add(rowData);
+ newRowsAdded(new TableModelEvent(
+ this, rowIndex, rowIndex, -1, TableModelEvent.INSERT)
+ );
+ }
+
+ /**
+ * Adds a new row containing the specified data to the table and sends a
+ * {@link TableModelEvent} to all registered listeners.
+ *
+ * @param rowData the row data (<code>null</code> permitted).
+ */
+ public void addRow(Object[] rowData)
+ {
+ addRow(convertToVector(rowData));
+ }
+
+ /**
+ * Inserts a new row into the table.
+ *
+ * @param row the row index.
+ * @param rowData the row data.
+ */
+ public void insertRow(int row, Vector rowData)
+ {
+ dataVector.add(row, rowData);
+ fireTableRowsInserted(row, row);
+ }
+
+ /**
+ * Inserts a new row into the table.
+ *
+ * @param row the row index.
+ * @param rowData the row data.
+ */
+ public void insertRow(int row, Object[] rowData)
+ {
+ insertRow(row, convertToVector(rowData));
+ }
+
+ /**
+ * Moves the rows from <code>startIndex</code> to <code>endIndex</code>
+ * (inclusive) to the specified row.
+ *
+ * @param startIndex the start row.
+ * @param endIndex the end row.
+ * @param toIndex the row to move to.
+ */
+ public void moveRow(int startIndex, int endIndex, int toIndex)
+ {
+ Vector removed = new Vector();
+ for (int i = endIndex; i >= startIndex; i--)
+ {
+ removed.add(this.dataVector.remove(i));
+ }
+ for (int i = 0; i <= endIndex - startIndex; i++)
+ {
+ dataVector.insertElementAt(removed.get(i), toIndex);
+ }
+ int firstRow = Math.min(startIndex, toIndex);
+ int lastRow = Math.max(endIndex, toIndex + (endIndex - startIndex));
+ fireTableRowsUpdated(firstRow, lastRow);
+ }
+
+ /**
+ * Removes a row from the table and sends a {@link TableModelEvent} to
+ * all registered listeners.
+ *
+ * @param row the row index.
+ */
+ public void removeRow(int row)
+ {
+ dataVector.remove(row);
+ fireTableRowsDeleted(row, row);
+ }
+
+ /**
+ * Returns the number of rows in the model.
+ *
+ * @return The row count.
+ */
+ public int getRowCount()
+ {
+ return dataVector.size();
+ }
+
+ /**
+ * Returns the number of columns in the model.
+ *
+ * @return The column count.
+ */
+ public int getColumnCount()
+ {
+ return columnIdentifiers == null ? 0 : columnIdentifiers.size();
+ }
+
+ /**
+ * Get the name of the column. If the column has the column identifier set,
+ * the return value is the result of the .toString() method call on that
+ * identifier. If the identifier is not explicitly set, the returned value
+ * is calculated by {@link AbstractTableModel#getColumnName(int)}.
+ *
+ * @param column the column index.
+ *
+ * @return The column name.
+ */
+ public String getColumnName(int column)
+ {
+ String result = "";
+ if (columnIdentifiers == null)
+ result = super.getColumnName(column);
+ else
+ {
+ if (column < getColumnCount())
+ {
+ checkSize();
+ Object id = columnIdentifiers.get(column);
+ if (id != null)
+ result = id.toString();
+ else
+ result = super.getColumnName(column);
+ }
+ else
+ result = super.getColumnName(column);
+ }
+ return result;
+ }
+
+ /**
+ * Returns <code>true</code> if the specified cell can be modified, and
+ * <code>false</code> otherwise. For this implementation, the method
+ * always returns <code>true</code>.
+ *
+ * @param row the row index.
+ * @param column the column index.
+ *
+ * @return <code>true</code> in all cases.
+ */
+ public boolean isCellEditable(int row, int column)
+ {
+ return true;
+ }
+
+ /**
+ * Returns the value at the specified cell in the table.
+ *
+ * @param row the row index.
+ * @param column the column index.
+ *
+ * @return The value (<code>Object</code>, possibly <code>null</code>) at
+ * the specified cell in the table.
+ */
+ public Object getValueAt(int row, int column)
+ {
+ return ((Vector) dataVector.get(row)).get(column);
+ }
+
+ /**
+ * Sets the value for the specified cell in the table and sends a
+ * {@link TableModelEvent} to all registered listeners.
+ *
+ * @param value the value (<code>Object</code>, <code>null</code> permitted).
+ * @param row the row index.
+ * @param column the column index.
+ */
+ public void setValueAt(Object value, int row, int column)
+ {
+ ((Vector) dataVector.get(row)).set(column, value);
+ fireTableCellUpdated(row, column);
+ }
+
+ /**
+ * Converts the data array to a <code>Vector</code>.
+ *
+ * @param data the data array (<code>null</code> permitted).
+ *
+ * @return A vector (or <code>null</code> if the data array
+ * is <code>null</code>).
+ */
+ protected static Vector convertToVector(Object[] data)
+ {
+ if (data == null)
+ return null;
+ Vector vector = new Vector(data.length);
+ for (int i = 0; i < data.length; i++)
+ vector.add(data[i]);
+ return vector;
+ }
+
+ /**
+ * Converts the data array to a <code>Vector</code> of rows.
+ *
+ * @param data the data array (<code>null</code> permitted).
+ *
+ * @return A vector (or <code>null</code> if the data array
+ * is <code>null</code>.
+ */
+ protected static Vector convertToVector(Object[][] data)
+ {
+ if (data == null)
+ return null;
+ Vector vector = new Vector(data.length);
+ for (int i = 0; i < data.length; i++)
+ vector.add(convertToVector(data[i]));
+ return vector;
+ }
+
+ /**
+ * This method adds some rows to <code>dataVector</code>.
+ *
+ * @param rowsToAdd number of rows to add
+ * @param nbColumns size of the added rows
+ */
+ private void addExtraRows(int rowsToAdd, int nbColumns)
+ {
+ for (int i = 0; i < rowsToAdd; i++)
+ {
+ Vector tmp = new Vector();
+ tmp.setSize(columnIdentifiers.size());
+ dataVector.add(tmp);
+ }
+ }
+
+ /**
+ * Checks the real columns/rows sizes against the ones returned by
+ * <code>getColumnCount()</code> and <code>getRowCount()</code>.
+ * If the supposed one are bigger, then we grow <code>columIdentifiers</code>
+ * and <code>dataVector</code> to their expected size.
+ */
+ private void checkSize()
+ {
+ int columnCount = getColumnCount();
+ int rowCount = getRowCount();
+
+ if (columnCount > columnIdentifiers.size())
+ columnIdentifiers.setSize(columnCount);
+
+ if (dataVector != null && rowCount > dataVector.size())
+ {
+ int rowsToAdd = rowCount - dataVector.size();
+ addExtraRows(rowsToAdd, columnCount);
+ }
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/JTableHeader.java b/libjava/classpath/javax/swing/table/JTableHeader.java
new file mode 100644
index 000000000..4eb91156b
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/JTableHeader.java
@@ -0,0 +1,1055 @@
+/* JTableHeader.java --
+ Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.FocusListener;
+import java.beans.PropertyChangeListener;
+import java.util.Locale;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleText;
+import javax.accessibility.AccessibleValue;
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.TableColumnModelEvent;
+import javax.swing.event.TableColumnModelListener;
+import javax.swing.plaf.TableHeaderUI;
+
+/**
+ * Represents the table header. The header displays the column header values,
+ * is always visible event if the rest of the table scrolls up and down and
+ * supports column reordering and resizing with mouse.
+ */
+public class JTableHeader extends JComponent
+ implements TableColumnModelListener, Accessible
+{
+ protected class AccessibleJTableHeader extends AccessibleJComponent
+ {
+ protected class AccessibleJTableHeaderEntry extends AccessibleContext
+ implements Accessible, AccessibleComponent
+ {
+
+ private int columnIndex;
+
+ private JTableHeader parent;
+
+ private JTable table;
+
+ public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)
+ {
+ columnIndex = c;
+ parent = p;
+ table = t;
+ }
+
+ /**
+ * Returns the column header renderer.
+ *
+ * @return The column header renderer.
+ */
+ Component getColumnHeaderRenderer()
+ {
+ TableColumn tc = parent.getColumnModel().getColumn(columnIndex);
+ TableCellRenderer r = tc.getHeaderRenderer();
+ if (r == null)
+ r = parent.getDefaultRenderer();
+ return r.getTableCellRendererComponent(table, tc.headerValue,
+ false, false, -1, columnIndex);
+ }
+
+ /**
+ * Returns the accessible context for the column header renderer, or
+ * <code>null</code>.
+ *
+ * @return The accessible context.
+ */
+ AccessibleContext getAccessibleColumnHeaderRenderer()
+ {
+ Component c = getColumnHeaderRenderer();
+ if (c instanceof Accessible)
+ return c.getAccessibleContext();
+ return null;
+ }
+
+ /**
+ * @see #removeFocusListener(FocusListener)
+ */
+ public void addFocusListener(FocusListener l)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.addFocusListener(l);
+ }
+
+ /**
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ // add the listener to the accessible context for the header
+ // renderer...
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.addPropertyChangeListener(l);
+ }
+
+ public boolean contains(Point p)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.contains(p);
+ else
+ return false;
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleAction)
+ return (AccessibleAction) ac;
+ else
+ return null;
+ }
+
+ public Accessible getAccessibleAt(Point p)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getAccessibleAt(p);
+ else
+ return null;
+ }
+
+ /**
+ * Returns <code>null</code> as the header entry has no accessible
+ * children.
+ *
+ * @return <code>null</code>.
+ */
+ public Accessible getAccessibleChild(int i)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the number of accessible children, zero in this case.
+ *
+ * @return 0
+ */
+ public int getAccessibleChildrenCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the accessible component for this header entry.
+ *
+ * @return <code>this</code>.
+ */
+ public AccessibleComponent getAccessibleComponent()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the accessible context for this header entry.
+ *
+ * @return <code>this</code>.
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the accessible description.
+ *
+ * @return The accessible description.
+ *
+ * @see #setAccessibleDescription(String)
+ */
+ public String getAccessibleDescription()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleDescription();
+ return accessibleDescription;
+ }
+
+ /**
+ * Returns the index of this header entry.
+ *
+ * @return The index of this header entry.
+ */
+ public int getAccessibleIndexInParent()
+ {
+ return columnIndex;
+ }
+
+ /**
+ * Returns the accessible name.
+ *
+ * @return The accessible name.
+ *
+ * @see #setAccessibleName(String)
+ */
+ public String getAccessibleName()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleName();
+ return accessibleName;
+ }
+
+ /**
+ * Returns the accessible role for the header entry.
+ *
+ * @return The accessible role.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleRole();
+ else
+ return null;
+ }
+
+ public AccessibleSelection getAccessibleSelection()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleValue)
+ return (AccessibleSelection) ac;
+ else
+ return null;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleStateSet();
+ else
+ return null;
+ }
+
+ public AccessibleText getAccessibleText()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleText();
+ else
+ return null;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleValue)
+ return (AccessibleValue) ac;
+ else
+ return null;
+ }
+
+ public Color getBackground()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getBackground();
+ else
+ return null;
+ }
+
+ public Rectangle getBounds()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getBounds();
+ else
+ return null;
+ }
+
+ public Cursor getCursor()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getCursor();
+ else
+ return null;
+ }
+
+ public Font getFont()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getFont();
+ else
+ return null;
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getFontMetrics(f);
+ else
+ return null;
+ }
+
+ public Color getForeground()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getForeground();
+ else
+ return null;
+ }
+
+ public Locale getLocale()
+ {
+ Component c = getColumnHeaderRenderer();
+ if (c != null)
+ return c.getLocale();
+ return null;
+ }
+
+ public Point getLocation()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getLocation();
+ else
+ return null;
+ }
+
+ public Point getLocationOnScreen()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getLocationOnScreen();
+ else
+ return null;
+ }
+
+ public Dimension getSize()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getSize();
+ else
+ return null;
+ }
+
+ public boolean isEnabled()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isEnabled();
+ else
+ return false;
+ }
+
+ public boolean isFocusTraversable()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isFocusTraversable();
+ else
+ return false;
+ }
+
+ public boolean isShowing()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isShowing();
+ else
+ return false;
+ }
+
+ public boolean isVisible()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isVisible();
+ else
+ return false;
+ }
+
+ /**
+ * @see #addFocusListener(FocusListener)
+ */
+ public void removeFocusListener(FocusListener l)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.removeFocusListener(l);
+ }
+
+ /**
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.removePropertyChangeListener(l);
+ }
+
+ /**
+ * @see #addFocusListener(FocusListener)
+ */
+ public void requestFocus()
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.requestFocus();
+ }
+
+ /**
+ * @see #getAccessibleDescription()
+ */
+ public void setAccessibleDescription(String s)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.setAccessibleDescription(s);
+ else
+ accessibleDescription = s;
+ }
+
+ /**
+ * @see #getAccessibleName()
+ */
+ public void setAccessibleName(String s)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.setAccessibleName(s);
+ }
+
+ public void setBackground(Color c)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setBackground(c);
+ }
+
+ public void setBounds(Rectangle r)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setBounds(r);
+ }
+
+ public void setCursor(Cursor c)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setCursor(c);
+ }
+
+ public void setEnabled(boolean b)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setEnabled(b);
+ }
+
+ public void setFont(Font f)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setFont(f);
+ }
+
+ public void setForeground(Color c)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setForeground(c);
+ }
+
+ public void setLocation(Point p)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setLocation(p);
+ }
+
+ public void setSize(Dimension d)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setSize(d);
+ }
+
+ public void setVisible(boolean b)
+ {
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setVisible(b);
+ }
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PANEL;
+ }
+
+ public int getAccessibleChildrenCount()
+ {
+ return table.getColumnCount();
+ }
+
+ public Accessible getAccessibleChild(int i)
+ {
+ return new AccessibleJTableHeaderEntry(i, JTableHeader.this, table);
+ }
+
+ public Accessible getAccessibleAt(Point p)
+ {
+ return getAccessibleChild(columnAtPoint(p));
+ }
+ }
+
+ /**
+ * Use serialVersionUid for interoperability.
+ */
+ private static final long serialVersionUID = 5144633983372967710L;
+
+ /**
+ * The columnModel property.
+ */
+ protected TableColumnModel columnModel;
+
+ /**
+ * The draggedColumn property.
+ */
+ protected TableColumn draggedColumn;
+
+ /**
+ * The draggedDistance property.
+ */
+ protected int draggedDistance;
+
+ /**
+ * The opaque property.
+ */
+ boolean opaque;
+
+ /**
+ * The reorderingAllowed property.
+ */
+ protected boolean reorderingAllowed;
+
+ /**
+ * The resizingAllowed property.
+ */
+ protected boolean resizingAllowed = true;
+
+ /**
+ * The resizingColumn property.
+ */
+ protected TableColumn resizingColumn;
+
+ /**
+ * The table property.
+ */
+ protected JTable table;
+
+ /**
+ * The updateTableInRealTime property.
+ */
+ protected boolean updateTableInRealTime;
+
+ TableCellRenderer cellRenderer;
+
+ /**
+ * Creates a new default instance.
+ */
+ public JTableHeader()
+ {
+ this(null);
+ }
+
+ /**
+ * Creates a new header. If <code>cm</code> is <code>null</code>, a new
+ * table column model is created by calling
+ * {@link #createDefaultColumnModel()}.
+ *
+ * @param cm the table column model (<code>null</code> permitted).
+ */
+ public JTableHeader(TableColumnModel cm)
+ {
+ columnModel = cm == null ? createDefaultColumnModel() : cm;
+ initializeLocalVars();
+ updateUI();
+ }
+
+ /**
+ * Creates a default table column model.
+ *
+ * @return A default table column model.
+ */
+ protected TableColumnModel createDefaultColumnModel()
+ {
+ return new DefaultTableColumnModel();
+ }
+
+ /**
+ * Get the value of the {@link #accessibleContext} property.
+ *
+ * @return The current value of the property
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return accessibleContext;
+ }
+
+ /**
+ * Get the value of the {@link #columnModel} property.
+ *
+ * @return The current value of the property
+ */
+ public TableColumnModel getColumnModel()
+ {
+ return columnModel;
+ }
+
+ /**
+ * Get the column that is currently being dragged. This is used when
+ * handling the column reordering with mouse.
+ *
+ * @return the column being dragged, null if none.
+ */
+ public TableColumn getDraggedColumn()
+ {
+ return draggedColumn;
+ }
+
+ /**
+ * Get the value of the {@link #draggedDistance} property.
+ *
+ * @return The current value of the property
+ */
+ public int getDraggedDistance()
+ {
+ return draggedDistance;
+ }
+
+ /**
+ * Check if it is possible to reorder the table columns by dragging column
+ * header with mouse. The table reordering is enabled by default, but can be
+ * disabled with {@link #setReorderingAllowed(boolean)}.
+ *
+ * @return true if reordering is allowed, false otherwise.
+ */
+ public boolean getReorderingAllowed()
+ {
+ return reorderingAllowed;
+ }
+
+ /**
+ * Check if it is possible to resize the table columns by dragging the column
+ * boundary in the table header with mouse. The resizing is enabled
+ * by default, but can be disabled with {@link #setResizingAllowed(boolean)}.
+ *
+ * @return true if resizing is allowed, false otherwise.
+ */
+ public boolean getResizingAllowed()
+ {
+ return resizingAllowed;
+ }
+
+ /**
+ * Get the column that is currently being resized. This is used when
+ * handling the column resizing with mouse.
+ *
+ * @return the column being currently resized, null if none.
+ */
+ public TableColumn getResizingColumn()
+ {
+ return resizingColumn;
+ }
+
+ /**
+ * Get the table, having this header.
+ *
+ * @return the table, having this header.
+ */
+ public JTable getTable()
+ {
+ return table;
+ }
+
+ /**
+ * Get the value of the {@link #updateTableInRealTime} property.
+ *
+ * @return The current value of the property
+ */
+ public boolean getUpdateTableInRealTime()
+ {
+ return updateTableInRealTime;
+ }
+
+ /**
+ * Get the value of the {@link #opaque} property.
+ *
+ * @return The current value of the property
+ */
+ public boolean isOpaque()
+ {
+ return opaque;
+ }
+
+ /**
+ * Set the value of the {@link #columnModel} property.
+ *
+ * @param c The new value of the property
+ */
+ public void setColumnModel(TableColumnModel c)
+ {
+ columnModel.removeColumnModelListener(this);
+ columnModel = c;
+ columnModel.addColumnModelListener(this);
+ }
+
+ /**
+ * Set the column that is currently being dragged. This is used when
+ * dragging the column with mouse. Setting to null will stop the
+ * dragging session immediately.
+ *
+ * @param draggingIt the column being currently dragged, null if none.
+ */
+ public void setDraggedColumn(TableColumn draggingIt)
+ {
+ draggedColumn = draggingIt;
+ }
+
+ /**
+ * Set the value of the {@link #draggedDistance} property.
+ *
+ * @param d The new value of the property
+ */
+ public void setDraggedDistance(int d)
+ {
+ draggedDistance = d;
+ }
+
+ /**
+ * Set the value of the {@link #opaque} property.
+ *
+ * @param o The new value of the property
+ */
+ public void setOpaque(boolean o)
+ {
+ opaque = o;
+ }
+
+ /**
+ * Set the table ability to reorder columns by dragging column header
+ * with mouse. The table reordering is enabled by default, but can be
+ * disabled with this method.
+ *
+ * @param allowed true if reordering is allowed, false otherwise.
+ */
+ public void setReorderingAllowed(boolean allowed)
+ {
+ reorderingAllowed = allowed;
+ }
+
+ /**
+ * Set the table ability to resize columns by dragging the column
+ * boundary in the table header with mouse. The resizing is enabled
+ * by default, but can be disabled using this method.
+ *
+ * @param allowed true if resizing is allowed, false otherwise.
+ */
+ public void setResizingAllowed(boolean allowed)
+ {
+ resizingAllowed = allowed;
+ }
+
+ /**
+ * The the column that is currently being resized. This property is used
+ * when handling table resizing with mouse. Setting to null would stop
+ * the resizing session immediately.
+ *
+ * @param resizingIt the column being currently resized
+ */
+ public void setResizingColumn(TableColumn resizingIt)
+ {
+ resizingColumn = resizingIt;
+ }
+
+ /**
+ * Set the value of the {@link #table} property.
+ *
+ * @param t The new value of the property
+ */
+ public void setTable(JTable t)
+ {
+ table = t;
+ }
+
+ /**
+ * Set the value of the {@link #updateTableInRealTime} property.
+ *
+ * @param u The new value of the property
+ */
+ public void setUpdateTableInRealTime(boolean u)
+ {
+ updateTableInRealTime = u;
+ }
+
+ /**
+ * Creates a default renderer.
+ *
+ * @return A default renderer.
+ */
+ protected TableCellRenderer createDefaultRenderer()
+ {
+ return new DefaultTableCellRenderer();
+ }
+
+ /**
+ * Returns the default table cell renderer.
+ *
+ * @return The default table cell renderer.
+ */
+ public TableCellRenderer getDefaultRenderer()
+ {
+ return cellRenderer;
+ }
+
+ /**
+ * Sets the default table cell renderer.
+ *
+ * @param cellRenderer the renderer.
+ */
+ public void setDefaultRenderer(TableCellRenderer cellRenderer)
+ {
+ this.cellRenderer = cellRenderer;
+ }
+
+ /**
+ * Get the rectangle, occupied by the header of the given column.
+ *
+ * @param column the column, for that the header area is requested.
+ *
+ * @return the column header area.
+ */
+ public Rectangle getHeaderRect(int column)
+ {
+ Rectangle r = getTable().getCellRect(-1, column, false);
+ r.height = getHeight();
+ return r;
+ }
+
+ protected String paramString()
+ {
+ return "JTableHeader";
+ }
+
+ // UI support
+
+ public String getUIClassID()
+ {
+ return "TableHeaderUI";
+ }
+
+ public TableHeaderUI getUI()
+ {
+ return (TableHeaderUI) ui;
+ }
+
+ public void setUI(TableHeaderUI u)
+ {
+ super.setUI(u);
+ }
+
+ public void updateUI()
+ {
+ setUI((TableHeaderUI) UIManager.getUI(this));
+ }
+
+ /**
+ * Returns the index of the column at the specified point.
+ *
+ * @param point the point.
+ *
+ * @return The column index, or -1.
+ */
+ public int columnAtPoint(Point point)
+ {
+ if (getBounds().contains(point))
+ return columnModel.getColumnIndexAtX(point.x);
+
+ return -1;
+ }
+
+ /**
+ * Receives notification when a column is added to the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnAdded(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column margin changes in the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnMarginChanged(ChangeEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column is moved within the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnMoved(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when a column is removed from the column model.
+ *
+ * @param event the table column model event
+ */
+ public void columnRemoved(TableColumnModelEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Receives notification when the column selection has changed.
+ *
+ * @param event the table column model event
+ */
+ public void columnSelectionChanged(ListSelectionEvent event)
+ {
+ // TODO: What else to do here (if anything)?
+ resizeAndRepaint();
+ }
+
+ /**
+ * Validates the layout of this table header and repaints it. This is
+ * equivalent to <code>revalidate()</code> followed by
+ * <code>repaint()</code>.
+ */
+ public void resizeAndRepaint()
+ {
+ revalidate();
+ repaint();
+ }
+
+ /**
+ * Initializes the fields and properties of this class with default values.
+ * This is called by the constructors.
+ */
+ protected void initializeLocalVars()
+ {
+ accessibleContext = new AccessibleJTableHeader();
+ draggedColumn = null;
+ draggedDistance = 0;
+ opaque = true;
+ reorderingAllowed = true;
+ resizingAllowed = true;
+ resizingColumn = null;
+ table = null;
+ updateTableInRealTime = true;
+ cellRenderer = createDefaultRenderer();
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/TableCellEditor.java b/libjava/classpath/javax/swing/table/TableCellEditor.java
new file mode 100644
index 000000000..933eb9ed7
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/TableCellEditor.java
@@ -0,0 +1,65 @@
+/* TableCellEditor.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.awt.Component;
+
+import javax.swing.CellEditor;
+import javax.swing.JTable;
+
+/**
+ * TableCellEditor public interface
+ * @author Andrew Selkirk
+ */
+public interface TableCellEditor extends CellEditor
+{
+
+ /**
+ * Get table cell editor component
+ * @param table JTable
+ * @param value Value of cell
+ * @param isSelected Cell selected
+ * @param row Row of cell
+ * @param column Column of cell
+ * @return Component
+ */
+ Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row, int column);
+
+}
diff --git a/libjava/classpath/javax/swing/table/TableCellRenderer.java b/libjava/classpath/javax/swing/table/TableCellRenderer.java
new file mode 100644
index 000000000..da7296de8
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/TableCellRenderer.java
@@ -0,0 +1,66 @@
+/* TableCellRenderer.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.awt.Component;
+
+import javax.swing.JTable;
+
+/**
+ * TableCellRenderer public interface
+ * @author Andrew Selkirk
+ */
+public interface TableCellRenderer
+{
+
+ /**
+ * Get table cell renderer component
+ * @param table JTable
+ * @param value Value of cell
+ * @param isSelected Cell selected
+ * @param hasFocus Cell has focus
+ * @param row Row of cell
+ * @param column Column of cell
+ * @return Component
+ */
+ Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column);
+
+
+}
diff --git a/libjava/classpath/javax/swing/table/TableColumn.java b/libjava/classpath/javax/swing/table/TableColumn.java
new file mode 100644
index 000000000..8db4bf6d0
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/TableColumn.java
@@ -0,0 +1,693 @@
+/* TableColumn.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.Serializable;
+
+import javax.swing.event.SwingPropertyChangeSupport;
+
+/**
+ * Represents the attributes of a column in a table, including the column index,
+ * width, minimum width, preferred width and maximum width.
+ *
+ * @author Andrew Selkirk
+ */
+public class TableColumn
+ implements Serializable
+{
+ static final long serialVersionUID = -6113660025878112608L;
+
+ /**
+ * The name for the <code>columnWidth</code> property (this field is
+ * obsolete and no longer used). Note also that the typo in the value
+ * string is deliberate, to match the specification.
+ */
+ public static final String COLUMN_WIDTH_PROPERTY = "columWidth";
+
+ /**
+ * The name for the <code>headerValue</code> property.
+ */
+ public static final String HEADER_VALUE_PROPERTY = "headerValue";
+
+ /**
+ * The name for the <code>headerRenderer</code> property.
+ */
+ public static final String HEADER_RENDERER_PROPERTY = "headerRenderer";
+
+ /**
+ * The name for the <code>cellRenderer</code> property.
+ */
+ public static final String CELL_RENDERER_PROPERTY = "cellRenderer";
+
+ /**
+ * The index of the corresponding column in the table model.
+ */
+ protected int modelIndex;
+
+ /**
+ * The identifier for the column.
+ */
+ protected Object identifier;
+
+ /**
+ * The current width for the column.
+ */
+ protected int width;
+
+ /**
+ * The minimum width for the column.
+ */
+ protected int minWidth = 15;
+
+ /**
+ * The preferred width for the column.
+ */
+ private int preferredWidth;
+
+ /**
+ * The maximum width for the column.
+ */
+ protected int maxWidth = Integer.MAX_VALUE;
+
+ /**
+ * The renderer for the column header.
+ */
+ protected TableCellRenderer headerRenderer;
+
+ /**
+ * The value for the column header.
+ */
+ protected Object headerValue;
+
+ /**
+ * The renderer for the regular cells in this column.
+ */
+ protected TableCellRenderer cellRenderer;
+
+ /**
+ * An editor for the regular cells in this column.
+ */
+ protected TableCellEditor cellEditor;
+
+ /**
+ * A flag that determines whether or not the column is resizable (the default
+ * is <code>true</code>).
+ */
+ protected boolean isResizable = true;
+
+ /**
+ * resizedPostingDisableCount
+ *
+ * @deprecated 1.3
+ */
+ protected transient int resizedPostingDisableCount;
+
+ /**
+ * A storage and notification mechanism for property change listeners.
+ */
+ private SwingPropertyChangeSupport changeSupport =
+ new SwingPropertyChangeSupport(this);
+
+ /**
+ * Creates a new <code>TableColumn</code> that maps to column 0 in the
+ * related table model. The default width is <code>75</code> units.
+ */
+ public TableColumn()
+ {
+ this(0, 75, null, null);
+ }
+
+ /**
+ * Creates a new <code>TableColumn</code> that maps to the specified column
+ * in the related table model. The default width is <code>75</code> units.
+ *
+ * @param modelIndex the index of the column in the model
+ */
+ public TableColumn(int modelIndex)
+ {
+ this(modelIndex, 75, null, null);
+ }
+
+ /**
+ * Creates a new <code>TableColumn</code> that maps to the specified column
+ * in the related table model, and has the specified <code>width</code>.
+ *
+ * @param modelIndex the index of the column in the model
+ * @param width the width
+ */
+ public TableColumn(int modelIndex, int width)
+ {
+ this(modelIndex, width, null, null);
+ }
+
+ /**
+ * Creates a new <code>TableColumn</code> that maps to the specified column
+ * in the related table model, and has the specified <code>width</code>,
+ * <code>cellRenderer</code> and <code>cellEditor</code>.
+ *
+ * @param modelIndex the index of the column in the model
+ * @param width the width
+ * @param cellRenderer the cell renderer (<code>null</code> permitted).
+ * @param cellEditor the cell editor (<code>null</code> permitted).
+ */
+ public TableColumn(int modelIndex, int width,
+ TableCellRenderer cellRenderer, TableCellEditor cellEditor)
+ {
+ this.modelIndex = modelIndex;
+ this.width = width;
+ this.preferredWidth = width;
+ this.cellRenderer = cellRenderer;
+ this.cellEditor = cellEditor;
+ this.headerValue = null;
+ this.identifier = null;
+ }
+
+ /**
+ * Sets the index of the column in the related {@link TableModel} that this
+ * <code>TableColumn</code> maps to, and sends a {@link PropertyChangeEvent}
+ * (with the property name 'modelIndex') to all registered listeners.
+ *
+ * @param modelIndex the column index in the model.
+ *
+ * @see #getModelIndex()
+ */
+ public void setModelIndex(int modelIndex)
+ {
+ if (this.modelIndex != modelIndex)
+ {
+ int oldValue = this.modelIndex;
+ this.modelIndex = modelIndex;
+ changeSupport.firePropertyChange("modelIndex", oldValue, modelIndex);
+ }
+ }
+
+ /**
+ * Returns the index of the column in the related {@link TableModel} that
+ * this <code>TableColumn</code> maps to.
+ *
+ * @return the model index.
+ *
+ * @see #setModelIndex(int)
+ */
+ public int getModelIndex()
+ {
+ return modelIndex;
+ }
+
+ /**
+ * Sets the identifier for the column and sends a {@link PropertyChangeEvent}
+ * (with the property name 'identifier') to all registered listeners.
+ *
+ * @param identifier the identifier (<code>null</code> permitted).
+ *
+ * @see #getIdentifier()
+ */
+ public void setIdentifier(Object identifier)
+ {
+ if (this.identifier != identifier)
+ {
+ Object oldValue = this.identifier;
+ this.identifier = identifier;
+ changeSupport.firePropertyChange("identifier", oldValue, identifier);
+ }
+ }
+
+ /**
+ * Returns the identifier for the column, or {@link #getHeaderValue()} if the
+ * identifier is <code>null</code>.
+ *
+ * @return The identifier (or {@link #getHeaderValue()} if the identifier is
+ * <code>null</code>).
+ */
+ public Object getIdentifier()
+ {
+ if (identifier == null)
+ return getHeaderValue();
+ return identifier;
+ }
+
+ /**
+ * Sets the header value and sends a {@link PropertyChangeEvent} (with the
+ * property name {@link #HEADER_VALUE_PROPERTY}) to all registered listeners.
+ *
+ * @param headerValue the value of the header (<code>null</code> permitted).
+ *
+ * @see #getHeaderValue()
+ */
+ public void setHeaderValue(Object headerValue)
+ {
+ if (this.headerValue == headerValue)
+ return;
+
+ Object oldValue = this.headerValue;
+ this.headerValue = headerValue;
+ changeSupport.firePropertyChange(HEADER_VALUE_PROPERTY, oldValue,
+ headerValue);
+ }
+
+ /**
+ * Returns the header value.
+ *
+ * @return the value of the header.
+ *
+ * @see #getHeaderValue()
+ */
+ public Object getHeaderValue()
+ {
+ return headerValue;
+ }
+
+ /**
+ * Sets the renderer for the column header and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #HEADER_RENDERER_PROPERTY}) to all registered listeners.
+ *
+ * @param renderer the header renderer (<code>null</code> permitted).
+ *
+ * @see #getHeaderRenderer()
+ */
+ public void setHeaderRenderer(TableCellRenderer renderer)
+ {
+ if (headerRenderer == renderer)
+ return;
+
+ TableCellRenderer oldRenderer = headerRenderer;
+ headerRenderer = renderer;
+ changeSupport.firePropertyChange(HEADER_RENDERER_PROPERTY, oldRenderer,
+ headerRenderer);
+ }
+
+ /**
+ * Returns the renderer for the column header.
+ *
+ * @return The renderer for the column header (possibly <code>null</code>).
+ *
+ * @see #setHeaderRenderer(TableCellRenderer)
+ */
+ public TableCellRenderer getHeaderRenderer()
+ {
+ return headerRenderer;
+ }
+
+ /**
+ * Sets the renderer for cells in this column and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #CELL_RENDERER_PROPERTY}) to all registered listeners.
+ *
+ * @param renderer the cell renderer (<code>null</code> permitted).
+ *
+ * @see #getCellRenderer()
+ */
+ public void setCellRenderer(TableCellRenderer renderer)
+ {
+ if (cellRenderer == renderer)
+ return;
+
+ TableCellRenderer oldRenderer = cellRenderer;
+ cellRenderer = renderer;
+ changeSupport.firePropertyChange(CELL_RENDERER_PROPERTY, oldRenderer,
+ cellRenderer);
+ }
+
+ /**
+ * Returns the renderer for the table cells in this column.
+ *
+ * @return The cell renderer (possibly <code>null</code>).
+ *
+ * @see #setCellRenderer(TableCellRenderer)
+ */
+ public TableCellRenderer getCellRenderer()
+ {
+ return cellRenderer;
+ }
+
+ /**
+ * Sets the cell editor for the column and sends a {@link PropertyChangeEvent}
+ * (with the property name 'cellEditor') to all registered listeners.
+ *
+ * @param cellEditor the cell editor (<code>null</code> permitted).
+ *
+ * @see #getCellEditor()
+ */
+ public void setCellEditor(TableCellEditor cellEditor)
+ {
+ if (this.cellEditor != cellEditor)
+ {
+ TableCellEditor oldValue = this.cellEditor;
+ this.cellEditor = cellEditor;
+ changeSupport.firePropertyChange("cellEditor", oldValue, cellEditor);
+ }
+ }
+
+ /**
+ * Returns the cell editor for the column (the default value is
+ * <code>null</code>).
+ *
+ * @return The cell editor (possibly <code>null</code>).
+ *
+ * @see #setCellEditor(TableCellEditor)
+ */
+ public TableCellEditor getCellEditor()
+ {
+ return cellEditor;
+ }
+
+ /**
+ * Sets the width for the column and sends a {@link PropertyChangeEvent}
+ * (with the property name 'width') to all registered listeners. If the new
+ * width falls outside the range getMinWidth() to getMaxWidth() it is
+ * adjusted to the appropriate boundary value.
+ *
+ * @param newWidth the width.
+ *
+ * @see #getWidth()
+ */
+ public void setWidth(int newWidth)
+ {
+ int oldWidth = width;
+
+ if (newWidth < minWidth)
+ width = minWidth;
+ else if (newWidth > maxWidth)
+ width = maxWidth;
+ else
+ width = newWidth;
+
+ if (width == oldWidth)
+ return;
+
+ // We do have a constant field COLUMN_WIDTH_PROPERTY,
+ // however, tests show that the actual fired property name is 'width'
+ // and even Sun's API docs say that this constant field is obsolete and
+ // not used.
+ changeSupport.firePropertyChange("width", oldWidth, width);
+ }
+
+ /**
+ * Returns the width for the column (the default value is <code>75</code>).
+ *
+ * @return The width.
+ *
+ * @see #setWidth(int)
+ */
+ public int getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Sets the preferred width for the column and sends a
+ * {@link PropertyChangeEvent} (with the property name 'preferredWidth') to
+ * all registered listeners. If necessary, the supplied value will be
+ * adjusted to fit in the range {@link #getMinWidth()} to
+ * {@link #getMaxWidth()}.
+ *
+ * @param preferredWidth the preferred width.
+ *
+ * @see #getPreferredWidth()
+ */
+ public void setPreferredWidth(int preferredWidth)
+ {
+ int oldPrefWidth = this.preferredWidth;
+
+ if (preferredWidth < minWidth)
+ this.preferredWidth = minWidth;
+ else if (preferredWidth > maxWidth)
+ this.preferredWidth = maxWidth;
+ else
+ this.preferredWidth = preferredWidth;
+
+ changeSupport.firePropertyChange("preferredWidth", oldPrefWidth,
+ this.preferredWidth);
+ }
+
+ /**
+ * Returns the preferred width for the column (the default value is
+ * <code>75</code>).
+ *
+ * @return The preferred width.
+ *
+ * @see #setPreferredWidth(int)
+ */
+ public int getPreferredWidth()
+ {
+ return preferredWidth;
+ }
+
+ /**
+ * Sets the minimum width for the column and sends a
+ * {@link PropertyChangeEvent} (with the property name 'minWidth') to all
+ * registered listeners. If the current <code>width</code> and/or
+ * <code>preferredWidth</code> are less than the new minimum width, they are
+ * adjusted accordingly.
+ *
+ * @param minWidth the minimum width (negative values are treated as 0).
+ *
+ * @see #getMinWidth()
+ */
+ public void setMinWidth(int minWidth)
+ {
+ if (minWidth < 0)
+ minWidth = 0;
+ if (this.minWidth != minWidth)
+ {
+ if (width < minWidth)
+ setWidth(minWidth);
+ if (preferredWidth < minWidth)
+ setPreferredWidth(minWidth);
+ int oldValue = this.minWidth;
+ this.minWidth = minWidth;
+ changeSupport.firePropertyChange("minWidth", oldValue, minWidth);
+ }
+ }
+
+ /**
+ * Returns the <code>TableColumn</code>'s minimum width (the default value
+ * is <code>15</code>).
+ *
+ * @return The minimum width.
+ *
+ * @see #setMinWidth(int)
+ */
+ public int getMinWidth()
+ {
+ return minWidth;
+ }
+
+ /**
+ * Sets the maximum width for the column and sends a
+ * {@link PropertyChangeEvent} (with the property name 'maxWidth') to all
+ * registered listeners. If the current <code>width</code> and/or
+ * <code>preferredWidth</code> are greater than the new maximum width, they
+ * are adjusted accordingly.
+ *
+ * @param maxWidth the maximum width.
+ *
+ * @see #getMaxWidth()
+ */
+ public void setMaxWidth(int maxWidth)
+ {
+ if (this.maxWidth != maxWidth)
+ {
+ if (width > maxWidth)
+ setWidth(maxWidth);
+ if (preferredWidth > maxWidth)
+ setPreferredWidth(maxWidth);
+ int oldValue = this.maxWidth;
+ this.maxWidth = maxWidth;
+ changeSupport.firePropertyChange("maxWidth", oldValue, maxWidth);
+ }
+ }
+
+ /**
+ * Returns the maximum width for the column (the default value is
+ * {@link Integer#MAX_VALUE}).
+ *
+ * @return The maximum width for the column.
+ *
+ * @see #setMaxWidth(int)
+ */
+ public int getMaxWidth()
+ {
+ return maxWidth;
+ }
+
+ /**
+ * Sets the flag that controls whether or not the column is resizable, and
+ * sends a {@link PropertyChangeEvent} (with the property name 'isResizable')
+ * to all registered listeners.
+ *
+ * @param isResizable <code>true</code> if this column is resizable,
+ * <code>false</code> otherwise.
+ *
+ * @see #getResizable()
+ */
+ public void setResizable(boolean isResizable)
+ {
+ if (this.isResizable != isResizable)
+ {
+ this.isResizable = isResizable;
+ changeSupport.firePropertyChange("isResizable", !this.isResizable,
+ isResizable);
+ }
+ }
+
+ /**
+ * Returns the flag that controls whether or not the column is resizable.
+ *
+ * @return <code>true</code> if this column is resizable,
+ * <code>false</code> otherwise.
+ *
+ * @see #setResizable(boolean)
+ */
+ public boolean getResizable()
+ {
+ return isResizable;
+ }
+
+ /**
+ * Sets the minimum, maximum, preferred and current width to match the
+ * minimum, maximum and preferred width of the header renderer component.
+ * If there is no header renderer component, this method does nothing.
+ */
+ public void sizeWidthToFit()
+ {
+ if (headerRenderer == null)
+ return;
+ Component c = headerRenderer.getTableCellRendererComponent(null,
+ getHeaderValue(), false, false, 0, 0);
+ Dimension min = c.getMinimumSize();
+ Dimension max = c.getMaximumSize();
+ Dimension pref = c.getPreferredSize();
+ setMinWidth(min.width);
+ setMaxWidth(max.width);
+ setPreferredWidth(pref.width);
+ setWidth(pref.width);
+ }
+
+ /**
+ * This method is empty, unused and deprecated.
+ * @deprecated 1.3
+ */
+ public void disableResizedPosting()
+ {
+ // Does nothing
+ }
+
+ /**
+ * This method is empty, unused and deprecated.
+ * @deprecated 1.3
+ */
+ public void enableResizedPosting()
+ {
+ // Does nothing
+ }
+
+ /**
+ * Adds a listener so that it receives {@link PropertyChangeEvent}
+ * notifications from this column. The properties defined by the column are:
+ * <ul>
+ * <li><code>width</code> - see {@link #setWidth(int)};</li>
+ * <li><code>preferredWidth</code> - see {@link #setPreferredWidth(int)};</li>
+ * <li><code>minWidth</code> - see {@link #setMinWidth(int)};</li>
+ * <li><code>maxWidth</code> - see {@link #setMaxWidth(int)};</li>
+ * <li><code>modelIndex</code> - see {@link #setModelIndex(int)};</li>
+ * <li><code>isResizable</code> - see {@link #setResizable(boolean)};</li>
+ * <li><code>cellRenderer</code> - see
+ * {@link #setCellRenderer(TableCellRenderer)};</li>
+ * <li><code>cellEditor</code> - see
+ * {@link #setCellEditor(TableCellEditor)};</li>
+ * <li><code>headerRenderer</code> - see
+ * {@link #setHeaderRenderer(TableCellRenderer)};</li>
+ * <li><code>headerValue</code> - see {@link #setHeaderValue(Object)};</li>
+ * <li><code>identifier</code> - see {@link #setIdentifier(Object)}.</li>
+ * </ul>
+ *
+ * @param listener the listener to add (<code>null</code> is ignored).
+ *
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ */
+ public synchronized void addPropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a listener so that it no longer receives
+ * {@link PropertyChangeEvent} notifications from this column. If
+ * <code>listener</code> is not registered with the column, or is
+ * <code>null</code>, this method does nothing.
+ *
+ * @param listener the listener to remove (<code>null</code> is ignored).
+ */
+ public synchronized void removePropertyChangeListener(
+ PropertyChangeListener listener)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Returns the property change listeners for this <code>TableColumn</code>.
+ * An empty array is returned if there are currently no listeners registered.
+ *
+ * @return The property change listeners registered with this column.
+ *
+ * @since 1.4
+ */
+ public PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ return changeSupport.getPropertyChangeListeners();
+ }
+
+ /**
+ * Creates and returns a default renderer for the column header (in this case,
+ * a new instance of {@link DefaultTableCellRenderer}).
+ *
+ * @return A default renderer for the column header.
+ */
+ protected TableCellRenderer createDefaultHeaderRenderer()
+ {
+ return new DefaultTableCellRenderer();
+ }
+}
diff --git a/libjava/classpath/javax/swing/table/TableColumnModel.java b/libjava/classpath/javax/swing/table/TableColumnModel.java
new file mode 100644
index 000000000..9a95f92cc
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/TableColumnModel.java
@@ -0,0 +1,232 @@
+/* TableColumnModel.java --
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.table;
+
+import java.util.Enumeration;
+
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.TableColumnModelEvent;
+import javax.swing.event.TableColumnModelListener;
+
+/**
+ * The interface used by {@link JTable} to access the columns in the table
+ * view.
+ *
+ * @author Andrew Selkirk
+ */
+public interface TableColumnModel
+{
+ /**
+ * Adds a column to the model.
+ *
+ * @param column the new column (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>column</code> is
+ * <code>null</code>.
+ */
+ void addColumn(TableColumn column);
+
+ /**
+ * Removes a column from the model. If <code>column</code> is not defined
+ * in the model, this method does nothing.
+ *
+ * @param column TableColumn
+ */
+ void removeColumn(TableColumn column);
+
+ /**
+ * Moves a column.
+ *
+ * @param columnIndex Index of column to move
+ * @param newIndex New index of column
+ */
+ void moveColumn(int columnIndex, int newIndex);
+
+ /**
+ * Sets the column margin and sends a {@link ChangeEvent} to all registered
+ * {@link TableColumnModelListener}s registered with the model.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
+ */
+ void setColumnMargin(int margin);
+
+ /**
+ * Returns the number of columns in the model.
+ *
+ * @return The column count.
+ */
+ int getColumnCount();
+
+ /**
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
+ */
+ Enumeration<TableColumn> getColumns();
+
+ /**
+ * Returns the index of the {@link TableColumn} with the given identifier.
+ *
+ * @param identifier the identifier (<code>null</code> not permitted).
+ *
+ * @return The index of the {@link TableColumn} with the given identifier.
+ *
+ * @throws IllegalArgumentException if <code>identifier</code> is
+ * <code>null</code> or there is no column with that identifier.
+ */
+ int getColumnIndex(Object identifier);
+
+ /**
+ * Returns the <code>TableColumn</code> at the specified index.
+ *
+ * @param columnIndex the column index.
+ *
+ * @return The table column.
+ */
+ TableColumn getColumn(int columnIndex);
+
+ /**
+ * Returns the column margin.
+ *
+ * @return The column margin.
+ *
+ * @see #setColumnMargin(int)
+ */
+ int getColumnMargin();
+
+ /**
+ * Returns the index of the column that contains the specified x-coordinate,
+ * assuming that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param xPosition the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
+ */
+ int getColumnIndexAtX(int xPosition);
+
+ /**
+ * Returns total width of all the columns in the model, ignoring the
+ * column margin (see {@link #getColumnMargin()}).
+ *
+ * @return The total width of all the columns.
+ */
+ int getTotalColumnWidth();
+
+ /**
+ * Sets the flag that indicates whether or not column selection is allowed.
+ *
+ * @param allowed the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
+ */
+ void setColumnSelectionAllowed(boolean allowed);
+
+ /**
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
+ *
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
+ */
+ boolean getColumnSelectionAllowed();
+
+ /**
+ * getSelectedColumns
+ * @return Selected columns
+ */
+ int[] getSelectedColumns();
+
+ /**
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
+ */
+ int getSelectedColumnCount();
+
+ /**
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
+ *
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
+ */
+ void setSelectionModel(ListSelectionModel model);
+
+ /**
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
+ */
+ ListSelectionModel getSelectionModel();
+
+ /**
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener (<code>null</code> ignored).
+ */
+ void addColumnModelListener(TableColumnModelListener listener);
+
+ /**
+ * Deregisters a listener, so that it will no longer receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener.
+ */
+ void removeColumnModelListener(TableColumnModelListener listener);
+}
diff --git a/libjava/classpath/javax/swing/table/TableModel.java b/libjava/classpath/javax/swing/table/TableModel.java
new file mode 100644
index 000000000..d8fb7131f
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/TableModel.java
@@ -0,0 +1,134 @@
+/* TableModel.java --
+ Copyright (C) 2002, 2005, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.table;
+
+import javax.swing.event.TableModelListener;
+
+/**
+ * A <code>TableModel</code> is a two dimensional data structure that
+ * can store arbitrary <code>Object</code> instances, usually for the
+ * purpose of display in a {@link javax.swing.JTable} component. Individual
+ * objects can be accessed by specifying the row index and column index for
+ * the object. Each column in the model has a name associated with it.
+ * <p>
+ * The {@link DefaultTableModel} class provides one implementation of
+ * this interface.
+ *
+ * @author Andrew Selkirk
+ */
+public interface TableModel
+{
+ /**
+ * Returns the number of rows in the model.
+ *
+ * @return The row count.
+ */
+ int getRowCount();
+
+ /**
+ * Returns the number of columns in the model.
+ *
+ * @return The column count
+ */
+ int getColumnCount();
+
+ /**
+ * Returns the name of a column in the model.
+ *
+ * @param columnIndex the column index.
+ *
+ * @return The column name.
+ */
+ String getColumnName(int columnIndex);
+
+ /**
+ * Returns the <code>Class</code> for all <code>Object</code> instances
+ * in the specified column.
+ *
+ * @param columnIndex the column index.
+ *
+ * @return The class.
+ */
+ Class<?> getColumnClass(int columnIndex);
+
+ /**
+ * Returns <code>true</code> if the cell is editable, and <code>false</code>
+ * otherwise.
+ *
+ * @param rowIndex the row index.
+ * @param columnIndex the column index.
+ *
+ * @return <code>true</code> if editable, <code>false</code> otherwise.
+ */
+ boolean isCellEditable(int rowIndex, int columnIndex);
+
+ /**
+ * Returns the value (<code>Object</code>) at a particular cell in the
+ * table.
+ *
+ * @param rowIndex the row index.
+ * @param columnIndex the column index.
+ *
+ * @return The value at the specified cell.
+ */
+ Object getValueAt(int rowIndex, int columnIndex);
+
+ /**
+ * Sets the value at a particular cell in the table.
+ *
+ * @param aValue the value (<code>null</code> permitted).
+ * @param rowIndex the row index.
+ * @param columnIndex the column index.
+ */
+ void setValueAt(Object aValue, int rowIndex, int columnIndex);
+
+ /**
+ * Adds a listener to the model. The listener will receive notification
+ * of updates to the model.
+ *
+ * @param listener the listener.
+ */
+ void addTableModelListener(TableModelListener listener);
+
+ /**
+ * Removes a listener from the model.
+ *
+ * @param listener the listener.
+ */
+ void removeTableModelListener(TableModelListener listener);
+}
diff --git a/libjava/classpath/javax/swing/table/package.html b/libjava/classpath/javax/swing/table/package.html
new file mode 100644
index 000000000..84e6f1aa3
--- /dev/null
+++ b/libjava/classpath/javax/swing/table/package.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.swing.table package.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.swing.table</title></head>
+
+<body>
+<p>Interfaces and classes that support the {@link javax.swing.JTable}
+component.</p>
+
+</body>
+</html>