feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,340 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import javax.swing.*;
import javax.swing.event.*;
import java.io.Serializable;
import java.util.EventListener;
/**
* This abstract class provides default implementations for most of
* the methods in the <code>TableModel</code> interface. It takes care of
* the management of listeners and provides some conveniences for generating
* <code>TableModelEvents</code> and dispatching them to the listeners.
* To create a concrete <code>TableModel</code> as a subclass of
* <code>AbstractTableModel</code> you need only provide implementations
* for the following three methods:
*
* <pre>
* public int getRowCount();
* public int getColumnCount();
* public Object getValueAt(int row, int column);
* </pre>
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Alan Chung
* @author Philip Milne
*/
public abstract class AbstractTableModel implements TableModel, Serializable
{
//
// Instance Variables
//
/** List of listeners */
protected EventListenerList listenerList = new EventListenerList();
//
// Default Implementation of the Interface
//
/**
* Returns a default name for the column using spreadsheet conventions:
* A, B, C, ... Z, AA, AB, etc. If <code>column</code> cannot be found,
* returns an empty string.
*
* @param column the column being queried
* @return a string containing the default name of <code>column</code>
*/
public String getColumnName(int column) {
String result = "";
for (; column >= 0; column = column / 26 - 1) {
result = (char)((char)(column%26)+'A') + result;
}
return result;
}
/**
* Returns a column given its name.
* Implementation is naive so this should be overridden if
* this method is to be called often. This method is not
* in the <code>TableModel</code> interface and is not used by the
* <code>JTable</code>.
*
* @param columnName string containing name of column to be located
* @return the column with <code>columnName</code>, or -1 if not found
*/
public int findColumn(String columnName) {
for (int i = 0; i < getColumnCount(); i++) {
if (columnName.equals(getColumnName(i))) {
return i;
}
}
return -1;
}
/**
* Returns <code>Object.class</code> regardless of <code>columnIndex</code>.
*
* @param columnIndex the column being queried
* @return the Object.class
*/
public Class<?> getColumnClass(int columnIndex) {
return Object.class;
}
/**
* Returns false. This is the default implementation for all cells.
*
* @param rowIndex the row being queried
* @param columnIndex the column being queried
* @return false
*/
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
/**
* This empty implementation is provided so users don't have to implement
* this method if their data model is not editable.
*
* @param aValue value to assign to cell
* @param rowIndex row of cell
* @param columnIndex column of cell
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
//
// Managing Listeners
//
/**
* Adds a listener to the list that's notified each time a change
* to the data model occurs.
*
* @param l the TableModelListener
*/
public void addTableModelListener(TableModelListener l) {
listenerList.add(TableModelListener.class, l);
}
/**
* Removes a listener from the list that's notified each time a
* change to the data model occurs.
*
* @param l the TableModelListener
*/
public void removeTableModelListener(TableModelListener l) {
listenerList.remove(TableModelListener.class, l);
}
/**
* Returns an array of all the table model listeners
* registered on this model.
*
* @return all of this model's <code>TableModelListener</code>s
* or an empty
* array if no table model listeners are currently registered
*
* @see #addTableModelListener
* @see #removeTableModelListener
*
* @since 1.4
*/
public TableModelListener[] getTableModelListeners() {
return listenerList.getListeners(TableModelListener.class);
}
//
// Fire methods
//
/**
* Notifies all listeners that all cell values in the table's
* rows may have changed. The number of rows may also have changed
* and the <code>JTable</code> should redraw the
* table from scratch. The structure of the table (as in the order of the
* columns) is assumed to be the same.
*
* @see TableModelEvent
* @see EventListenerList
* @see javax.swing.JTable#tableChanged(TableModelEvent)
*/
public void fireTableDataChanged() {
fireTableChanged(new TableModelEvent(this));
}
/**
* Notifies all listeners that the table's structure has changed.
* The number of columns in the table, and the names and types of
* the new columns may be different from the previous state.
* If the <code>JTable</code> receives this event and its
* <code>autoCreateColumnsFromModel</code>
* flag is set it discards any table columns that it had and reallocates
* default columns in the order they appear in the model. This is the
* same as calling <code>setModel(TableModel)</code> on the
* <code>JTable</code>.
*
* @see TableModelEvent
* @see EventListenerList
*/
public void fireTableStructureChanged() {
fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
}
/**
* Notifies all listeners that rows in the range
* <code>[firstRow, lastRow]</code>, inclusive, have been inserted.
*
* @param firstRow the first row
* @param lastRow the last row
*
* @see TableModelEvent
* @see EventListenerList
*
*/
public void fireTableRowsInserted(int firstRow, int lastRow) {
fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
}
/**
* Notifies all listeners that rows in the range
* <code>[firstRow, lastRow]</code>, inclusive, have been updated.
*
* @param firstRow the first row
* @param lastRow the last row
*
* @see TableModelEvent
* @see EventListenerList
*/
public void fireTableRowsUpdated(int firstRow, int lastRow) {
fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
TableModelEvent.ALL_COLUMNS, TableModelEvent.UPDATE));
}
/**
* Notifies all listeners that rows in the range
* <code>[firstRow, lastRow]</code>, inclusive, have been deleted.
*
* @param firstRow the first row
* @param lastRow the last row
*
* @see TableModelEvent
* @see EventListenerList
*/
public void fireTableRowsDeleted(int firstRow, int lastRow) {
fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
}
/**
* Notifies all listeners that the value of the cell at
* <code>[row, column]</code> has been updated.
*
* @param row row of cell which has been updated
* @param column column of cell which has been updated
* @see TableModelEvent
* @see EventListenerList
*/
public void fireTableCellUpdated(int row, int column) {
fireTableChanged(new TableModelEvent(this, row, row, column));
}
/**
* Forwards the given notification event to all
* <code>TableModelListeners</code> that registered
* themselves as listeners for this table model.
*
* @param e the event to be forwarded
*
* @see #addTableModelListener
* @see TableModelEvent
* @see EventListenerList
*/
public void fireTableChanged(TableModelEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableModelListener.class) {
((TableModelListener)listeners[i+1]).tableChanged(e);
}
}
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>AbstractTableModel</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
*
* You can specify the <code>listenerType</code> argument
* with a class literal,
* such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* model <code>m</code>
* for its table model listeners with the following code:
*
* <pre>TableModelListener[] tmls = (TableModelListener[])(m.getListeners(TableModelListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this component,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getTableModelListeners
*
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
return listenerList.getListeners(listenerType);
}
} // End of class AbstractTableModel

View File

@@ -0,0 +1,399 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.Component;
import java.awt.Color;
import java.awt.Rectangle;
import java.io.Serializable;
import sun.swing.DefaultLookup;
/**
* The standard class for rendering (displaying) individual cells
* in a <code>JTable</code>.
* <p>
*
* <strong><a name="override">Implementation Note:</a></strong>
* This class inherits from <code>JLabel</code>, a standard component class.
* However <code>JTable</code> employs a unique mechanism for rendering
* its cells and therefore requires some slightly modified behavior
* from its cell renderer.
* The table class defines a single cell renderer and uses it as a
* as a rubber-stamp for rendering all cells in the table;
* it renders the first cell,
* changes the contents of that cell renderer,
* shifts the origin to the new location, re-draws it, and so on.
* The standard <code>JLabel</code> component was not
* designed to be used this way and we want to avoid
* triggering a <code>revalidate</code> each time the
* cell is drawn. This would greatly decrease performance because the
* <code>revalidate</code> message would be
* passed up the hierarchy of the container to determine whether any other
* components would be affected.
* As the renderer is only parented for the lifetime of a painting operation
* we similarly want to avoid the overhead associated with walking the
* hierarchy for painting operations.
* So this class
* overrides the <code>validate</code>, <code>invalidate</code>,
* <code>revalidate</code>, <code>repaint</code>, and
* <code>firePropertyChange</code> methods to be
* no-ops and override the <code>isOpaque</code> method solely to improve
* performance. If you write your own renderer,
* please keep this performance consideration in mind.
* <p>
*
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Philip Milne
* @see JTable
*/
public class DefaultTableCellRenderer extends JLabel
implements TableCellRenderer, Serializable
{
/**
* An empty <code>Border</code>. This field might not be used. To change the
* <code>Border</code> used by this renderer override the
* <code>getTableCellRendererComponent</code> method and set the border
* of the returned component directly.
*/
private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
// We need a place to store the color the JLabel should be returned
// to after its foreground and background colors have been set
// to the selection background color.
// These ivars will be made protected when their names are finalized.
private Color unselectedForeground;
private Color unselectedBackground;
/**
* Creates a default table cell renderer.
*/
public DefaultTableCellRenderer() {
super();
setOpaque(true);
setBorder(getNoFocusBorder());
setName("Table.cellRenderer");
}
private Border getNoFocusBorder() {
Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder");
if (System.getSecurityManager() != null) {
if (border != null) return border;
return SAFE_NO_FOCUS_BORDER;
} else if (border != null) {
if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
return border;
}
}
return noFocusBorder;
}
/**
* Overrides <code>JComponent.setForeground</code> to assign
* the unselected-foreground color to the specified color.
*
* @param c set the foreground color to this value
*/
public void setForeground(Color c) {
super.setForeground(c);
unselectedForeground = c;
}
/**
* Overrides <code>JComponent.setBackground</code> to assign
* the unselected-background color to the specified color.
*
* @param c set the background color to this value
*/
public void setBackground(Color c) {
super.setBackground(c);
unselectedBackground = c;
}
/**
* Notification from the <code>UIManager</code> that the look and feel
* [L&amp;F] has changed.
* Replaces the current UI object with the latest version from the
* <code>UIManager</code>.
*
* @see JComponent#updateUI
*/
public void updateUI() {
super.updateUI();
setForeground(null);
setBackground(null);
}
// implements javax.swing.table.TableCellRenderer
/**
*
* Returns the default table cell renderer.
* <p>
* During a printing operation, this method will be called with
* <code>isSelected</code> and <code>hasFocus</code> values of
* <code>false</code> to prevent selection and focus from appearing
* in the printed output. To do other customization based on whether
* or not the table is being printed, check the return value from
* {@link javax.swing.JComponent#isPaintingForPrint()}.
*
* @param table the <code>JTable</code>
* @param value the value to assign to the cell at
* <code>[row, column]</code>
* @param isSelected true if cell is selected
* @param hasFocus true if cell has focus
* @param row the row of the cell to render
* @param column the column of the cell to render
* @return the default table cell renderer
* @see javax.swing.JComponent#isPaintingForPrint()
*/
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (table == null) {
return this;
}
Color fg = null;
Color bg = null;
JTable.DropLocation dropLocation = table.getDropLocation();
if (dropLocation != null
&& !dropLocation.isInsertRow()
&& !dropLocation.isInsertColumn()
&& dropLocation.getRow() == row
&& dropLocation.getColumn() == column) {
fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
isSelected = true;
}
if (isSelected) {
super.setForeground(fg == null ? table.getSelectionForeground()
: fg);
super.setBackground(bg == null ? table.getSelectionBackground()
: bg);
} else {
Color background = unselectedBackground != null
? unselectedBackground
: table.getBackground();
if (background == null || background instanceof javax.swing.plaf.UIResource) {
Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor");
if (alternateColor != null && row % 2 != 0) {
background = alternateColor;
}
}
super.setForeground(unselectedForeground != null
? unselectedForeground
: table.getForeground());
super.setBackground(background);
}
setFont(table.getFont());
if (hasFocus) {
Border border = null;
if (isSelected) {
border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");
}
if (border == null) {
border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");
}
setBorder(border);
if (!isSelected && table.isCellEditable(row, column)) {
Color col;
col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");
if (col != null) {
super.setForeground(col);
}
col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");
if (col != null) {
super.setBackground(col);
}
}
} else {
setBorder(getNoFocusBorder());
}
setValue(value);
return this;
}
/*
* The following methods are overridden as a performance measure to
* to prune code-paths are often called in the case of renders
* but which we know are unnecessary. Great care should be taken
* when writing your own renderer to weigh the benefits and
* drawbacks of overriding methods like these.
*/
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public boolean isOpaque() {
Color back = getBackground();
Component p = getParent();
if (p != null) {
p = p.getParent();
}
// p should now be the JTable.
boolean colorMatch = (back != null) && (p != null) &&
back.equals(p.getBackground()) &&
p.isOpaque();
return !colorMatch && super.isOpaque();
}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*
* @since 1.5
*/
public void invalidate() {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void validate() {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void revalidate() {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void repaint(long tm, int x, int y, int width, int height) {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void repaint(Rectangle r) { }
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*
* @since 1.5
*/
public void repaint() {
}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned...
if (propertyName=="text"
|| propertyName == "labelFor"
|| propertyName == "displayedMnemonic"
|| ((propertyName == "font" || propertyName == "foreground")
&& oldValue != newValue
&& getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
super.firePropertyChange(propertyName, oldValue, newValue);
}
}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
/**
* Sets the <code>String</code> object for the cell being rendered to
* <code>value</code>.
*
* @param value the string value for this cell; if value is
* <code>null</code> it sets the text value to an empty string
* @see JLabel#setText
*
*/
protected void setValue(Object value) {
setText((value == null) ? "" : value.toString());
}
/**
* A subclass of <code>DefaultTableCellRenderer</code> that
* implements <code>UIResource</code>.
* <code>DefaultTableCellRenderer</code> doesn't implement
* <code>UIResource</code>
* directly so that applications can safely override the
* <code>cellRenderer</code> property with
* <code>DefaultTableCellRenderer</code> subclasses.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*/
public static class UIResource extends DefaultTableCellRenderer
implements javax.swing.plaf.UIResource
{
}
}

View File

@@ -0,0 +1,739 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.util.Vector;
import java.util.Enumeration;
import java.util.EventListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.io.Serializable;
import sun.swing.SwingUtilities2;
/**
* The standard column-handler for a <code>JTable</code>.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Alan Chung
* @author Philip Milne
* @see JTable
*/
public class DefaultTableColumnModel implements TableColumnModel,
PropertyChangeListener, ListSelectionListener, Serializable
{
//
// Instance Variables
//
/** Array of TableColumn objects in this model */
protected Vector<TableColumn> tableColumns;
/** Model for keeping track of column selections */
protected ListSelectionModel selectionModel;
/** Width margin between each column */
protected int columnMargin;
/** List of TableColumnModelListener */
protected EventListenerList listenerList = new EventListenerList();
/** Change event (only one needed) */
transient protected ChangeEvent changeEvent = null;
/** Column selection allowed in this column model */
protected boolean columnSelectionAllowed;
/** A local cache of the combined width of all columns */
protected int totalColumnWidth;
//
// Constructors
//
/**
* Creates a default table column model.
*/
public DefaultTableColumnModel() {
super();
// Initialize local ivars to default
tableColumns = new Vector<TableColumn>();
setSelectionModel(createSelectionModel());
setColumnMargin(1);
invalidateWidthCache();
setColumnSelectionAllowed(false);
}
//
// Modifying the model
//
/**
* Appends <code>aColumn</code> to the end of the
* <code>tableColumns</code> array.
* This method also posts the <code>columnAdded</code>
* event to its listeners.
*
* @param aColumn the <code>TableColumn</code> to be added
* @exception IllegalArgumentException if <code>aColumn</code> is
* <code>null</code>
* @see #removeColumn
*/
public void addColumn(TableColumn aColumn) {
if (aColumn == null) {
throw new IllegalArgumentException("Object is null");
}
tableColumns.addElement(aColumn);
aColumn.addPropertyChangeListener(this);
invalidateWidthCache();
// Post columnAdded event notification
fireColumnAdded(new TableColumnModelEvent(this, 0,
getColumnCount() - 1));
}
/**
* Deletes the <code>column</code> from the
* <code>tableColumns</code> array. This method will do nothing if
* <code>column</code> is not in the table's columns list.
* <code>tile</code> is called
* to resize both the header and table views.
* This method also posts a <code>columnRemoved</code>
* event to its listeners.
*
* @param column the <code>TableColumn</code> to be removed
* @see #addColumn
*/
public void removeColumn(TableColumn column) {
int columnIndex = tableColumns.indexOf(column);
if (columnIndex != -1) {
// Adjust for the selection
if (selectionModel != null) {
selectionModel.removeIndexInterval(columnIndex,columnIndex);
}
column.removePropertyChangeListener(this);
tableColumns.removeElementAt(columnIndex);
invalidateWidthCache();
// Post columnAdded event notification. (JTable and JTableHeader
// listens so they can adjust size and redraw)
fireColumnRemoved(new TableColumnModelEvent(this,
columnIndex, 0));
}
}
/**
* Moves the column and heading at <code>columnIndex</code> to
* <code>newIndex</code>. The old column at <code>columnIndex</code>
* will now be found at <code>newIndex</code>. The column
* that used to be at <code>newIndex</code> is shifted
* left or right to make room. This will not move any columns if
* <code>columnIndex</code> equals <code>newIndex</code>. This method
* also posts a <code>columnMoved</code> event to its listeners.
*
* @param columnIndex the index of column to be moved
* @param newIndex new index to move the column
* @exception IllegalArgumentException if <code>column</code> or
* <code>newIndex</code>
* are not in the valid range
*/
public void moveColumn(int columnIndex, int newIndex) {
if ((columnIndex < 0) || (columnIndex >= getColumnCount()) ||
(newIndex < 0) || (newIndex >= getColumnCount()))
throw new IllegalArgumentException("moveColumn() - Index out of range");
TableColumn aColumn;
// If the column has not yet moved far enough to change positions
// post the event anyway, the "draggedDistance" property of the
// tableHeader will say how far the column has been dragged.
// Here we are really trying to get the best out of an
// API that could do with some rethinking. We preserve backward
// compatibility by slightly bending the meaning of these methods.
if (columnIndex == newIndex) {
fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));
return;
}
aColumn = tableColumns.elementAt(columnIndex);
tableColumns.removeElementAt(columnIndex);
boolean selected = selectionModel.isSelectedIndex(columnIndex);
selectionModel.removeIndexInterval(columnIndex,columnIndex);
tableColumns.insertElementAt(aColumn, newIndex);
selectionModel.insertIndexInterval(newIndex, 1, true);
if (selected) {
selectionModel.addSelectionInterval(newIndex, newIndex);
}
else {
selectionModel.removeSelectionInterval(newIndex, newIndex);
}
fireColumnMoved(new TableColumnModelEvent(this, columnIndex,
newIndex));
}
/**
* Sets the column margin to <code>newMargin</code>. This method
* also posts a <code>columnMarginChanged</code> event to its
* listeners.
*
* @param newMargin the new margin width, in pixels
* @see #getColumnMargin
* @see #getTotalColumnWidth
*/
public void setColumnMargin(int newMargin) {
if (newMargin != columnMargin) {
columnMargin = newMargin;
// Post columnMarginChanged event notification.
fireColumnMarginChanged();
}
}
//
// Querying the model
//
/**
* Returns the number of columns in the <code>tableColumns</code> array.
*
* @return the number of columns in the <code>tableColumns</code> array
* @see #getColumns
*/
public int getColumnCount() {
return tableColumns.size();
}
/**
* Returns an <code>Enumeration</code> of all the columns in the model.
* @return an <code>Enumeration</code> of the columns in the model
*/
public Enumeration<TableColumn> getColumns() {
return tableColumns.elements();
}
/**
* Returns the index of the first column in the <code>tableColumns</code>
* array whose identifier is equal to <code>identifier</code>,
* when compared using <code>equals</code>.
*
* @param identifier the identifier object
* @return the index of the first column in the
* <code>tableColumns</code> array whose identifier
* is equal to <code>identifier</code>
* @exception IllegalArgumentException if <code>identifier</code>
* is <code>null</code>, or if no
* <code>TableColumn</code> has this
* <code>identifier</code>
* @see #getColumn
*/
public int getColumnIndex(Object identifier) {
if (identifier == null) {
throw new IllegalArgumentException("Identifier is null");
}
Enumeration enumeration = getColumns();
TableColumn aColumn;
int index = 0;
while (enumeration.hasMoreElements()) {
aColumn = (TableColumn)enumeration.nextElement();
// Compare them this way in case the column's identifier is null.
if (identifier.equals(aColumn.getIdentifier()))
return index;
index++;
}
throw new IllegalArgumentException("Identifier not found");
}
/**
* Returns the <code>TableColumn</code> object for the column
* at <code>columnIndex</code>.
*
* @param columnIndex the index of the column desired
* @return the <code>TableColumn</code> object for the column
* at <code>columnIndex</code>
*/
public TableColumn getColumn(int columnIndex) {
return tableColumns.elementAt(columnIndex);
}
/**
* Returns the width margin for <code>TableColumn</code>.
* The default <code>columnMargin</code> is 1.
*
* @return the maximum width for the <code>TableColumn</code>
* @see #setColumnMargin
*/
public int getColumnMargin() {
return columnMargin;
}
/**
* Returns the index of the column that lies at position <code>x</code>,
* or -1 if no column covers this point.
*
* In keeping with Swing's separable model architecture, a
* TableColumnModel does not know how the table columns actually appear on
* screen. The visual presentation of the columns is the responsibility
* of the view/controller object using this model (typically JTable). The
* view/controller need not display the columns sequentially from left to
* right. For example, columns could be displayed from right to left to
* accommodate a locale preference or some columns might be hidden at the
* request of the user. Because the model does not know how the columns
* are laid out on screen, the given <code>xPosition</code> should not be
* considered to be a coordinate in 2D graphics space. Instead, it should
* be considered to be a width from the start of the first column in the
* model. If the column index for a given X coordinate in 2D space is
* required, <code>JTable.columnAtPoint</code> can be used instead.
*
* @param x the horizontal location of interest
* @return the index of the column or -1 if no column is found
* @see javax.swing.JTable#columnAtPoint
*/
public int getColumnIndexAtX(int x) {
if (x < 0) {
return -1;
}
int cc = getColumnCount();
for(int column = 0; column < cc; column++) {
x = x - getColumn(column).getWidth();
if (x < 0) {
return column;
}
}
return -1;
}
/**
* Returns the total combined width of all columns.
* @return the <code>totalColumnWidth</code> property
*/
public int getTotalColumnWidth() {
if (totalColumnWidth == -1) {
recalcWidthCache();
}
return totalColumnWidth;
}
//
// Selection model
//
/**
* Sets the selection model for this <code>TableColumnModel</code>
* to <code>newModel</code>
* and registers for listener notifications from the new selection
* model. If <code>newModel</code> is <code>null</code>,
* an exception is thrown.
*
* @param newModel the new selection model
* @exception IllegalArgumentException if <code>newModel</code>
* is <code>null</code>
* @see #getSelectionModel
*/
public void setSelectionModel(ListSelectionModel newModel) {
if (newModel == null) {
throw new IllegalArgumentException("Cannot set a null SelectionModel");
}
ListSelectionModel oldModel = selectionModel;
if (newModel != oldModel) {
if (oldModel != null) {
oldModel.removeListSelectionListener(this);
}
selectionModel= newModel;
newModel.addListSelectionListener(this);
}
}
/**
* Returns the <code>ListSelectionModel</code> that is used to
* maintain column selection state.
*
* @return the object that provides column selection state. Or
* <code>null</code> if row selection is not allowed.
* @see #setSelectionModel
*/
public ListSelectionModel getSelectionModel() {
return selectionModel;
}
// implements javax.swing.table.TableColumnModel
/**
* Sets whether column selection is allowed. The default is false.
* @param flag true if column selection will be allowed, false otherwise
*/
public void setColumnSelectionAllowed(boolean flag) {
columnSelectionAllowed = flag;
}
// implements javax.swing.table.TableColumnModel
/**
* Returns true if column selection is allowed, otherwise false.
* The default is false.
* @return the <code>columnSelectionAllowed</code> property
*/
public boolean getColumnSelectionAllowed() {
return columnSelectionAllowed;
}
// implements javax.swing.table.TableColumnModel
/**
* Returns an array of selected columns. If <code>selectionModel</code>
* is <code>null</code>, returns an empty array.
* @return an array of selected columns or an empty array if nothing
* is selected or the <code>selectionModel</code> is
* <code>null</code>
*/
public int[] getSelectedColumns() {
if (selectionModel != null) {
int iMin = selectionModel.getMinSelectionIndex();
int iMax = selectionModel.getMaxSelectionIndex();
if ((iMin == -1) || (iMax == -1)) {
return new int[0];
}
int[] rvTmp = new int[1+ (iMax - iMin)];
int n = 0;
for(int i = iMin; i <= iMax; i++) {
if (selectionModel.isSelectedIndex(i)) {
rvTmp[n++] = i;
}
}
int[] rv = new int[n];
System.arraycopy(rvTmp, 0, rv, 0, n);
return rv;
}
return new int[0];
}
// implements javax.swing.table.TableColumnModel
/**
* Returns the number of columns selected.
* @return the number of columns selected
*/
public int getSelectedColumnCount() {
if (selectionModel != null) {
int iMin = selectionModel.getMinSelectionIndex();
int iMax = selectionModel.getMaxSelectionIndex();
int count = 0;
for(int i = iMin; i <= iMax; i++) {
if (selectionModel.isSelectedIndex(i)) {
count++;
}
}
return count;
}
return 0;
}
//
// Listener Support Methods
//
// implements javax.swing.table.TableColumnModel
/**
* Adds a listener for table column model events.
* @param x a <code>TableColumnModelListener</code> object
*/
public void addColumnModelListener(TableColumnModelListener x) {
listenerList.add(TableColumnModelListener.class, x);
}
// implements javax.swing.table.TableColumnModel
/**
* Removes a listener for table column model events.
* @param x a <code>TableColumnModelListener</code> object
*/
public void removeColumnModelListener(TableColumnModelListener x) {
listenerList.remove(TableColumnModelListener.class, x);
}
/**
* Returns an array of all the column model listeners
* registered on this model.
*
* @return all of this default table column model's <code>ColumnModelListener</code>s
* or an empty
* array if no column model listeners are currently registered
*
* @see #addColumnModelListener
* @see #removeColumnModelListener
*
* @since 1.4
*/
public TableColumnModelListener[] getColumnModelListeners() {
return listenerList.getListeners(TableColumnModelListener.class);
}
//
// Event firing methods
//
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @param e the event received
* @see EventListenerList
*/
protected void fireColumnAdded(TableColumnModelEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableColumnModelListener.class) {
// Lazily create the event:
// if (e == null)
// e = new ChangeEvent(this);
((TableColumnModelListener)listeners[i+1]).
columnAdded(e);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @param e the event received
* @see EventListenerList
*/
protected void fireColumnRemoved(TableColumnModelEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableColumnModelListener.class) {
// Lazily create the event:
// if (e == null)
// e = new ChangeEvent(this);
((TableColumnModelListener)listeners[i+1]).
columnRemoved(e);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @param e the event received
* @see EventListenerList
*/
protected void fireColumnMoved(TableColumnModelEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableColumnModelListener.class) {
// Lazily create the event:
// if (e == null)
// e = new ChangeEvent(this);
((TableColumnModelListener)listeners[i+1]).
columnMoved(e);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @param e the event received
* @see EventListenerList
*/
protected void fireColumnSelectionChanged(ListSelectionEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableColumnModelListener.class) {
// Lazily create the event:
// if (e == null)
// e = new ChangeEvent(this);
((TableColumnModelListener)listeners[i+1]).
columnSelectionChanged(e);
}
}
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireColumnMarginChanged() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TableColumnModelListener.class) {
// Lazily create the event:
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((TableColumnModelListener)listeners[i+1]).
columnMarginChanged(changeEvent);
}
}
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this model.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
*
* You can specify the <code>listenerType</code> argument
* with a class literal,
* such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>DefaultTableColumnModel</code> <code>m</code>
* for its column model listeners with the following code:
*
* <pre>ColumnModelListener[] cmls = (ColumnModelListener[])(m.getListeners(ColumnModelListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this model,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getColumnModelListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
return listenerList.getListeners(listenerType);
}
//
// Implementing the PropertyChangeListener interface
//
// PENDING(alan)
// implements java.beans.PropertyChangeListener
/**
* Property Change Listener change method. Used to track changes
* to the column width or preferred column width.
*
* @param evt <code>PropertyChangeEvent</code>
*/
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if (name == "width" || name == "preferredWidth") {
invalidateWidthCache();
// This is a misnomer, we're using this method
// simply to cause a relayout.
fireColumnMarginChanged();
}
}
//
// Implementing ListSelectionListener interface
//
// implements javax.swing.event.ListSelectionListener
/**
* A <code>ListSelectionListener</code> that forwards
* <code>ListSelectionEvents</code> when there is a column
* selection change.
*
* @param e the change event
*/
public void valueChanged(ListSelectionEvent e) {
fireColumnSelectionChanged(e);
}
//
// Protected Methods
//
/**
* Creates a new default list selection model.
*/
protected ListSelectionModel createSelectionModel() {
return new DefaultListSelectionModel();
}
/**
* Recalculates the total combined width of all columns. Updates the
* <code>totalColumnWidth</code> property.
*/
protected void recalcWidthCache() {
Enumeration enumeration = getColumns();
totalColumnWidth = 0;
while (enumeration.hasMoreElements()) {
totalColumnWidth += ((TableColumn)enumeration.nextElement()).getWidth();
}
}
private void invalidateWidthCache() {
totalColumnWidth = -1;
}
} // End of class DefaultTableColumnModel

View File

@@ -0,0 +1,707 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.io.Serializable;
import java.util.Vector;
import java.util.Enumeration;
import javax.swing.event.TableModelEvent;
/**
* This is an implementation of <code>TableModel</code> that
* uses a <code>Vector</code> of <code>Vectors</code> to store the
* cell value objects.
* <p>
* <strong>Warning:</strong> <code>DefaultTableModel</code> returns a
* column class of <code>Object</code>. When
* <code>DefaultTableModel</code> is used with a
* <code>TableRowSorter</code> this will result in extensive use of
* <code>toString</code>, which for non-<code>String</code> data types
* is expensive. If you use <code>DefaultTableModel</code> with a
* <code>TableRowSorter</code> you are strongly encouraged to override
* <code>getColumnClass</code> to return the appropriate type.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Philip Milne
*
* @see TableModel
* @see #getDataVector
*/
public class DefaultTableModel extends AbstractTableModel implements Serializable {
//
// Instance Variables
//
/**
* The <code>Vector</code> of <code>Vectors</code> of
* <code>Object</code> values.
*/
protected Vector dataVector;
/** The <code>Vector</code> of column identifiers. */
protected Vector columnIdentifiers;
//
// Constructors
//
/**
* Constructs a default <code>DefaultTableModel</code>
* which is a table of zero columns and zero rows.
*/
public DefaultTableModel() {
this(0, 0);
}
private static Vector newVector(int size) {
Vector v = new Vector(size);
v.setSize(size);
return v;
}
/**
* Constructs a <code>DefaultTableModel</code> with
* <code>rowCount</code> and <code>columnCount</code> of
* <code>null</code> object values.
*
* @param rowCount the number of rows the table holds
* @param columnCount the number of columns the table holds
*
* @see #setValueAt
*/
public DefaultTableModel(int rowCount, int columnCount) {
this(newVector(columnCount), rowCount);
}
/**
* Constructs a <code>DefaultTableModel</code> with as many columns
* as there are elements in <code>columnNames</code>
* and <code>rowCount</code> of <code>null</code>
* object values. Each column's name will be taken from
* the <code>columnNames</code> vector.
*
* @param columnNames <code>vector</code> containing the names
* of the new columns; if this is
* <code>null</code> then the model has no columns
* @param rowCount the number of rows the table holds
* @see #setDataVector
* @see #setValueAt
*/
public DefaultTableModel(Vector columnNames, int rowCount) {
setDataVector(newVector(rowCount), columnNames);
}
/**
* Constructs a <code>DefaultTableModel</code> with as many
* columns as there are elements in <code>columnNames</code>
* and <code>rowCount</code> of <code>null</code>
* object values. Each column's name will be taken from
* the <code>columnNames</code> array.
*
* @param columnNames <code>array</code> containing the names
* of the new columns; if this is
* <code>null</code> then the model has no columns
* @param rowCount the number of rows the table holds
* @see #setDataVector
* @see #setValueAt
*/
public DefaultTableModel(Object[] columnNames, int rowCount) {
this(convertToVector(columnNames), rowCount);
}
/**
* Constructs a <code>DefaultTableModel</code> and initializes the table
* by passing <code>data</code> and <code>columnNames</code>
* to the <code>setDataVector</code> method.
*
* @param data the data of the table, a <code>Vector</code>
* of <code>Vector</code>s of <code>Object</code>
* values
* @param columnNames <code>vector</code> containing the names
* of the new columns
* @see #getDataVector
* @see #setDataVector
*/
public DefaultTableModel(Vector data, Vector columnNames) {
setDataVector(data, columnNames);
}
/**
* Constructs a <code>DefaultTableModel</code> and initializes the table
* by passing <code>data</code> and <code>columnNames</code>
* to the <code>setDataVector</code>
* method. The first index in the <code>Object[][]</code> array is
* the row index and the second is the column index.
*
* @param data the data of the table
* @param columnNames the names of the columns
* @see #getDataVector
* @see #setDataVector
*/
public DefaultTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
/**
* Returns the <code>Vector</code> of <code>Vectors</code>
* that contains the table's
* data values. The vectors contained in the outer vector are
* each a single row of values. In other words, to get to the cell
* at row 1, column 5: <p>
*
* <code>((Vector)getDataVector().elementAt(1)).elementAt(5);</code>
*
* @return the vector of vectors containing the tables data values
*
* @see #newDataAvailable
* @see #newRowsAdded
* @see #setDataVector
*/
public Vector getDataVector() {
return dataVector;
}
private static Vector nonNullVector(Vector v) {
return (v != null) ? v : new Vector();
}
/**
* Replaces the current <code>dataVector</code> instance variable
* with the new <code>Vector</code> of rows, <code>dataVector</code>.
* Each row is represented in <code>dataVector</code> as a
* <code>Vector</code> of <code>Object</code> values.
* <code>columnIdentifiers</code> are the names of the new
* columns. The first name in <code>columnIdentifiers</code> is
* mapped to column 0 in <code>dataVector</code>. Each row in
* <code>dataVector</code> is adjusted to match the number of
* columns in <code>columnIdentifiers</code>
* either by truncating the <code>Vector</code> if it is too long,
* or adding <code>null</code> values if it is too short.
* <p>Note that passing in a <code>null</code> value for
* <code>dataVector</code> results in unspecified behavior,
* an possibly an exception.
*
* @param dataVector the new data vector
* @param columnIdentifiers the names of the columns
* @see #getDataVector
*/
public void setDataVector(Vector dataVector, Vector columnIdentifiers) {
this.dataVector = nonNullVector(dataVector);
this.columnIdentifiers = nonNullVector(columnIdentifiers);
justifyRows(0, getRowCount());
fireTableStructureChanged();
}
/**
* Replaces the value in the <code>dataVector</code> instance
* variable with the values in the array <code>dataVector</code>.
* The first index in the <code>Object[][]</code>
* array is the row index and the second is the column index.
* <code>columnIdentifiers</code> are the names of the new columns.
*
* @param dataVector the new data vector
* @param columnIdentifiers the names of the columns
* @see #setDataVector(Vector, Vector)
*/
public void setDataVector(Object[][] dataVector, Object[] columnIdentifiers) {
setDataVector(convertToVector(dataVector), convertToVector(columnIdentifiers));
}
/**
* Equivalent to <code>fireTableChanged</code>.
*
* @param event the change event
*
*/
public void newDataAvailable(TableModelEvent event) {
fireTableChanged(event);
}
//
// Manipulating rows
//
private void justifyRows(int from, int to) {
// Sometimes the DefaultTableModel is subclassed
// instead of the AbstractTableModel by mistake.
// Set the number of rows for the case when getRowCount
// is overridden.
dataVector.setSize(getRowCount());
for (int i = from; i < to; i++) {
if (dataVector.elementAt(i) == null) {
dataVector.setElementAt(new Vector(), i);
}
((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
}
}
/**
* Ensures that the new rows have the correct number of columns.
* This is accomplished by using the <code>setSize</code> method in
* <code>Vector</code> which truncates vectors
* which are too long, and appends <code>null</code>s if they
* are too short.
* This method also sends out a <code>tableChanged</code>
* notification message to all the listeners.
*
* @param e this <code>TableModelEvent</code> describes
* where the rows were added.
* If <code>null</code> it assumes
* all the rows were newly added
* @see #getDataVector
*/
public void newRowsAdded(TableModelEvent e) {
justifyRows(e.getFirstRow(), e.getLastRow() + 1);
fireTableChanged(e);
}
/**
* Equivalent to <code>fireTableChanged</code>.
*
* @param event the change event
*
*/
public void rowsRemoved(TableModelEvent event) {
fireTableChanged(event);
}
/**
* Obsolete as of Java 2 platform v1.3. Please use <code>setRowCount</code> instead.
*/
/*
* Sets the number of rows in the model. If the new size is greater
* than the current size, new rows are added to the end of the model
* If the new size is less than the current size, all
* rows at index <code>rowCount</code> and greater are discarded.
*
* @param rowCount the new number of rows
* @see #setRowCount
*/
public void setNumRows(int rowCount) {
int old = getRowCount();
if (old == rowCount) {
return;
}
dataVector.setSize(rowCount);
if (rowCount <= old) {
fireTableRowsDeleted(rowCount, old-1);
}
else {
justifyRows(old, rowCount);
fireTableRowsInserted(old, rowCount-1);
}
}
/**
* Sets the number of rows in the model. If the new size is greater
* than the current size, new rows are added to the end of the model
* If the new size is less than the current size, all
* rows at index <code>rowCount</code> and greater are discarded.
*
* @see #setColumnCount
* @since 1.3
*/
public void setRowCount(int rowCount) {
setNumRows(rowCount);
}
/**
* Adds a row to the end of the model. The new row will contain
* <code>null</code> values unless <code>rowData</code> is specified.
* Notification of the row being added will be generated.
*
* @param rowData optional data of the row being added
*/
public void addRow(Vector rowData) {
insertRow(getRowCount(), rowData);
}
/**
* Adds a row to the end of the model. The new row will contain
* <code>null</code> values unless <code>rowData</code> is specified.
* Notification of the row being added will be generated.
*
* @param rowData optional data of the row being added
*/
public void addRow(Object[] rowData) {
addRow(convertToVector(rowData));
}
/**
* Inserts a row at <code>row</code> in the model. The new row
* will contain <code>null</code> values unless <code>rowData</code>
* is specified. Notification of the row being added will be generated.
*
* @param row the row index of the row to be inserted
* @param rowData optional data of the row being added
* @exception ArrayIndexOutOfBoundsException if the row was invalid
*/
public void insertRow(int row, Vector rowData) {
dataVector.insertElementAt(rowData, row);
justifyRows(row, row+1);
fireTableRowsInserted(row, row);
}
/**
* Inserts a row at <code>row</code> in the model. The new row
* will contain <code>null</code> values unless <code>rowData</code>
* is specified. Notification of the row being added will be generated.
*
* @param row the row index of the row to be inserted
* @param rowData optional data of the row being added
* @exception ArrayIndexOutOfBoundsException if the row was invalid
*/
public void insertRow(int row, Object[] rowData) {
insertRow(row, convertToVector(rowData));
}
private static int gcd(int i, int j) {
return (j == 0) ? i : gcd(j, i%j);
}
private static void rotate(Vector v, int a, int b, int shift) {
int size = b - a;
int r = size - shift;
int g = gcd(size, r);
for(int i = 0; i < g; i++) {
int to = i;
Object tmp = v.elementAt(a + to);
for(int from = (to + r) % size; from != i; from = (to + r) % size) {
v.setElementAt(v.elementAt(a + from), a + to);
to = from;
}
v.setElementAt(tmp, a + to);
}
}
/**
* Moves one or more rows from the inclusive range <code>start</code> to
* <code>end</code> to the <code>to</code> position in the model.
* After the move, the row that was at index <code>start</code>
* will be at index <code>to</code>.
* This method will send a <code>tableChanged</code> notification
message to all the listeners.
*
* <pre>
* Examples of moves:
*
* 1. moveRow(1,3,5);
* a|B|C|D|e|f|g|h|i|j|k - before
* a|e|f|g|h|B|C|D|i|j|k - after
*
* 2. moveRow(6,7,1);
* a|b|c|d|e|f|G|H|i|j|k - before
* a|G|H|b|c|d|e|f|i|j|k - after
* </pre>
*
* @param start the starting row index to be moved
* @param end the ending row index to be moved
* @param to the destination of the rows to be moved
* @exception ArrayIndexOutOfBoundsException if any of the elements
* would be moved out of the table's range
*
*/
public void moveRow(int start, int end, int to) {
int shift = to - start;
int first, last;
if (shift < 0) {
first = to;
last = end;
}
else {
first = start;
last = to + end - start;
}
rotate(dataVector, first, last + 1, shift);
fireTableRowsUpdated(first, last);
}
/**
* Removes the row at <code>row</code> from the model. Notification
* of the row being removed will be sent to all the listeners.
*
* @param row the row index of the row to be removed
* @exception ArrayIndexOutOfBoundsException if the row was invalid
*/
public void removeRow(int row) {
dataVector.removeElementAt(row);
fireTableRowsDeleted(row, row);
}
//
// Manipulating columns
//
/**
* Replaces the column identifiers in the model. If the number of
* <code>newIdentifier</code>s is greater than the current number
* of columns, new columns are added to the end of each row in the model.
* If the number of <code>newIdentifier</code>s is less than the current
* number of columns, all the extra columns at the end of a row are
* discarded.
*
* @param columnIdentifiers vector of column identifiers. If
* <code>null</code>, set the model
* to zero columns
* @see #setNumRows
*/
public void setColumnIdentifiers(Vector columnIdentifiers) {
setDataVector(dataVector, columnIdentifiers);
}
/**
* Replaces the column identifiers in the model. If the number of
* <code>newIdentifier</code>s is greater than the current number
* of columns, new columns are added to the end of each row in the model.
* If the number of <code>newIdentifier</code>s is less than the current
* number of columns, all the extra columns at the end of a row are
* discarded.
*
* @param newIdentifiers array of column identifiers.
* If <code>null</code>, set
* the model to zero columns
* @see #setNumRows
*/
public void setColumnIdentifiers(Object[] newIdentifiers) {
setColumnIdentifiers(convertToVector(newIdentifiers));
}
/**
* Sets the number of columns in the model. If the new size is greater
* than the current size, new columns are added to the end of the model
* with <code>null</code> cell values.
* If the new size is less than the current size, all columns at index
* <code>columnCount</code> and greater are discarded.
*
* @param columnCount the new number of columns in the model
*
* @see #setColumnCount
* @since 1.3
*/
public void setColumnCount(int columnCount) {
columnIdentifiers.setSize(columnCount);
justifyRows(0, getRowCount());
fireTableStructureChanged();
}
/**
* Adds a column to the model. The new column will have the
* identifier <code>columnName</code>, which may be null. This method
* will send a
* <code>tableChanged</code> notification message to all the listeners.
* This method is a cover for <code>addColumn(Object, Vector)</code> which
* uses <code>null</code> as the data vector.
*
* @param columnName the identifier of the column being added
*/
public void addColumn(Object columnName) {
addColumn(columnName, (Vector)null);
}
/**
* Adds a column to the model. The new column will have the
* identifier <code>columnName</code>, which may be null.
* <code>columnData</code> is the
* optional vector of data for the column. If it is <code>null</code>
* the column is filled with <code>null</code> values. Otherwise,
* the new data will be added to model starting with the first
* element going to row 0, etc. This method will send a
* <code>tableChanged</code> notification message to all the listeners.
*
* @param columnName the identifier of the column being added
* @param columnData optional data of the column being added
*/
public void addColumn(Object columnName, Vector columnData) {
columnIdentifiers.addElement(columnName);
if (columnData != null) {
int columnSize = columnData.size();
if (columnSize > getRowCount()) {
dataVector.setSize(columnSize);
}
justifyRows(0, getRowCount());
int newColumn = getColumnCount() - 1;
for(int i = 0; i < columnSize; i++) {
Vector row = (Vector)dataVector.elementAt(i);
row.setElementAt(columnData.elementAt(i), newColumn);
}
}
else {
justifyRows(0, getRowCount());
}
fireTableStructureChanged();
}
/**
* Adds a column to the model. The new column will have the
* identifier <code>columnName</code>. <code>columnData</code> is the
* optional array of data for the column. If it is <code>null</code>
* the column is filled with <code>null</code> values. Otherwise,
* the new data will be added to model starting with the first
* element going to row 0, etc. This method will send a
* <code>tableChanged</code> notification message to all the listeners.
*
* @see #addColumn(Object, Vector)
*/
public void addColumn(Object columnName, Object[] columnData) {
addColumn(columnName, convertToVector(columnData));
}
//
// Implementing the TableModel interface
//
/**
* Returns the number of rows in this data table.
* @return the number of rows in the model
*/
public int getRowCount() {
return dataVector.size();
}
/**
* Returns the number of columns in this data table.
* @return the number of columns in the model
*/
public int getColumnCount() {
return columnIdentifiers.size();
}
/**
* Returns the column name.
*
* @return a name for this column using the string value of the
* appropriate member in <code>columnIdentifiers</code>.
* If <code>columnIdentifiers</code> does not have an entry
* for this index, returns the default
* name provided by the superclass.
*/
public String getColumnName(int column) {
Object id = null;
// This test is to cover the case when
// getColumnCount has been subclassed by mistake ...
if (column < columnIdentifiers.size() && (column >= 0)) {
id = columnIdentifiers.elementAt(column);
}
return (id == null) ? super.getColumnName(column)
: id.toString();
}
/**
* Returns true regardless of parameter values.
*
* @param row the row whose value is to be queried
* @param column the column whose value is to be queried
* @return true
* @see #setValueAt
*/
public boolean isCellEditable(int row, int column) {
return true;
}
/**
* Returns an attribute value for the cell at <code>row</code>
* and <code>column</code>.
*
* @param row the row whose value is to be queried
* @param column the column whose value is to be queried
* @return the value Object at the specified cell
* @exception ArrayIndexOutOfBoundsException if an invalid row or
* column was given
*/
public Object getValueAt(int row, int column) {
Vector rowVector = (Vector)dataVector.elementAt(row);
return rowVector.elementAt(column);
}
/**
* Sets the object value for the cell at <code>column</code> and
* <code>row</code>. <code>aValue</code> is the new value. This method
* will generate a <code>tableChanged</code> notification.
*
* @param aValue the new value; this can be null
* @param row the row whose value is to be changed
* @param column the column whose value is to be changed
* @exception ArrayIndexOutOfBoundsException if an invalid row or
* column was given
*/
public void setValueAt(Object aValue, int row, int column) {
Vector rowVector = (Vector)dataVector.elementAt(row);
rowVector.setElementAt(aValue, column);
fireTableCellUpdated(row, column);
}
//
// Protected Methods
//
/**
* Returns a vector that contains the same objects as the array.
* @param anArray the array to be converted
* @return the new vector; if <code>anArray</code> is <code>null</code>,
* returns <code>null</code>
*/
protected static Vector convertToVector(Object[] anArray) {
if (anArray == null) {
return null;
}
Vector<Object> v = new Vector<Object>(anArray.length);
for (Object o : anArray) {
v.addElement(o);
}
return v;
}
/**
* Returns a vector of vectors that contains the same objects as the array.
* @param anArray the double array to be converted
* @return the new vector of vectors; if <code>anArray</code> is
* <code>null</code>, returns <code>null</code>
*/
protected static Vector convertToVector(Object[][] anArray) {
if (anArray == null) {
return null;
}
Vector<Vector> v = new Vector<Vector>(anArray.length);
for (Object[] o : anArray) {
v.addElement(convertToVector(o));
}
return v;
}
} // End of class DefaultTableModel

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.awt.Component;
import javax.swing.CellEditor;
import javax.swing.*;
/**
* This interface defines the method any object that would like to be
* an editor of values for components such as <code>JListBox</code>,
* <code>JComboBox</code>, <code>JTree</code>, or <code>JTable</code>
* needs to implement.
*
* @author Alan Chung
*/
public interface TableCellEditor extends CellEditor {
/**
* Sets an initial <code>value</code> for the editor. This will cause
* the editor to <code>stopEditing</code> and lose any partially
* edited value if the editor is editing when this method is called. <p>
*
* Returns the component that should be added to the client's
* <code>Component</code> hierarchy. Once installed in the client's
* hierarchy this component will then be able to draw and receive
* user input.
*
* @param table the <code>JTable</code> that is asking the
* editor to edit; can be <code>null</code>
* @param value the value of the cell to be edited; it is
* up to the specific editor to interpret
* and draw the value. For example, if value is
* the string "true", it could be rendered as a
* string or it could be rendered as a check
* box that is checked. <code>null</code>
* is a valid value
* @param isSelected true if the cell is to be rendered with
* highlighting
* @param row the row of the cell being edited
* @param column the column of the cell being edited
* @return the component for editing
*/
Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected,
int row, int column);
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.awt.Component;
import javax.swing.*;
/**
* This interface defines the method required by any object that
* would like to be a renderer for cells in a <code>JTable</code>.
*
* @author Alan Chung
*/
public interface TableCellRenderer {
/**
* Returns the component used for drawing the cell. This method is
* used to configure the renderer appropriately before drawing.
* <p>
* The <code>TableCellRenderer</code> is also responsible for rendering the
* the cell representing the table's current DnD drop location if
* it has one. If this renderer cares about rendering
* the DnD drop location, it should query the table directly to
* see if the given row and column represent the drop location:
* <pre>
* JTable.DropLocation dropLocation = table.getDropLocation();
* if (dropLocation != null
* &amp;&amp; !dropLocation.isInsertRow()
* &amp;&amp; !dropLocation.isInsertColumn()
* &amp;&amp; dropLocation.getRow() == row
* &amp;&amp; dropLocation.getColumn() == column) {
*
* // this cell represents the current drop location
* // so render it specially, perhaps with a different color
* }
* </pre>
* <p>
* During a printing operation, this method will be called with
* <code>isSelected</code> and <code>hasFocus</code> values of
* <code>false</code> to prevent selection and focus from appearing
* in the printed output. To do other customization based on whether
* or not the table is being printed, check the return value from
* {@link javax.swing.JComponent#isPaintingForPrint()}.
*
* @param table the <code>JTable</code> that is asking the
* renderer to draw; can be <code>null</code>
* @param value the value of the cell to be rendered. It is
* up to the specific renderer to interpret
* and draw the value. For example, if
* <code>value</code>
* is the string "true", it could be rendered as a
* string or it could be rendered as a check
* box that is checked. <code>null</code> is a
* valid value
* @param isSelected true if the cell is to be rendered with the
* selection highlighted; otherwise false
* @param hasFocus if true, render cell appropriately. For
* example, put a special border on the cell, if
* the cell can be edited, render in the color used
* to indicate editing
* @param row the row index of the cell being drawn. When
* drawing the header, the value of
* <code>row</code> is -1
* @param column the column index of the cell being drawn
* @see javax.swing.JComponent#isPaintingForPrint()
*/
Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column);
}

View File

@@ -0,0 +1,825 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.SwingPropertyChangeSupport;
import java.lang.Integer;
import java.awt.Color;
import java.awt.Component;
import java.io.Serializable;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* A <code>TableColumn</code> represents all the attributes of a column in a
* <code>JTable</code>, such as width, resizability, minimum and maximum width.
* In addition, the <code>TableColumn</code> provides slots for a renderer and
* an editor that can be used to display and edit the values in this column.
* <p>
* It is also possible to specify renderers and editors on a per type basis
* rather than a per column basis - see the
* <code>setDefaultRenderer</code> method in the <code>JTable</code> class.
* This default mechanism is only used when the renderer (or
* editor) in the <code>TableColumn</code> is <code>null</code>.
* <p>
* The <code>TableColumn</code> stores the link between the columns in the
* <code>JTable</code> and the columns in the <code>TableModel</code>.
* The <code>modelIndex</code> is the column in the
* <code>TableModel</code>, which will be queried for the data values for the
* cells in this column. As the column moves around in the view this
* <code>modelIndex</code> does not change.
* <p>
* <b>Note:</b> Some implementations may assume that all
* <code>TableColumnModel</code>s are unique, therefore we would
* recommend that the same <code>TableColumn</code> instance
* not be added more than once to a <code>TableColumnModel</code>.
* To show <code>TableColumn</code>s with the same column of
* data from the model, create a new instance with the same
* <code>modelIndex</code>.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans&trade;
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Alan Chung
* @author Philip Milne
* @see javax.swing.table.TableColumnModel
*
* @see javax.swing.table.DefaultTableColumnModel
* @see javax.swing.table.JTableHeader#getDefaultRenderer()
* @see JTable#getDefaultRenderer(Class)
* @see JTable#getDefaultEditor(Class)
* @see JTable#getCellRenderer(int, int)
* @see JTable#getCellEditor(int, int)
*/
public class TableColumn extends Object implements Serializable {
/**
* Obsolete as of Java 2 platform v1.3. Please use string literals to identify
* properties.
*/
/*
* Warning: The value of this constant, "columWidth" is wrong as the
* name of the property is "columnWidth".
*/
public final static String COLUMN_WIDTH_PROPERTY = "columWidth";
/**
* Obsolete as of Java 2 platform v1.3. Please use string literals to identify
* properties.
*/
public final static String HEADER_VALUE_PROPERTY = "headerValue";
/**
* Obsolete as of Java 2 platform v1.3. Please use string literals to identify
* properties.
*/
public final static String HEADER_RENDERER_PROPERTY = "headerRenderer";
/**
* Obsolete as of Java 2 platform v1.3. Please use string literals to identify
* properties.
*/
public final static String CELL_RENDERER_PROPERTY = "cellRenderer";
//
// Instance Variables
//
/**
* The index of the column in the model which is to be displayed by
* this <code>TableColumn</code>. As columns are moved around in the
* view <code>modelIndex</code> remains constant.
*/
protected int modelIndex;
/**
* This object is not used internally by the drawing machinery of
* the <code>JTable</code>; identifiers may be set in the
* <code>TableColumn</code> as as an
* optional way to tag and locate table columns. The table package does
* not modify or invoke any methods in these identifier objects other
* than the <code>equals</code> method which is used in the
* <code>getColumnIndex()</code> method in the
* <code>DefaultTableColumnModel</code>.
*/
protected Object identifier;
/** The width of the column. */
protected int width;
/** The minimum width of the column. */
protected int minWidth;
/** The preferred width of the column. */
private int preferredWidth;
/** The maximum width of the column. */
protected int maxWidth;
/** The renderer used to draw the header of the column. */
protected TableCellRenderer headerRenderer;
/** The header value of the column. */
protected Object headerValue;
/** The renderer used to draw the data cells of the column. */
protected TableCellRenderer cellRenderer;
/** The editor used to edit the data cells of the column. */
protected TableCellEditor cellEditor;
/** If true, the user is allowed to resize the column; the default is true. */
protected boolean isResizable;
/**
* This field was not used in previous releases and there are
* currently no plans to support it in the future.
*
* @deprecated as of Java 2 platform v1.3
*/
/*
* Counter used to disable posting of resizing notifications until the
* end of the resize.
*/
@Deprecated
transient protected int resizedPostingDisableCount;
/**
* If any <code>PropertyChangeListeners</code> have been registered, the
* <code>changeSupport</code> field describes them.
*/
private SwingPropertyChangeSupport changeSupport;
//
// Constructors
//
/**
* Cover method, using a default model index of 0,
* default width of 75, a <code>null</code> renderer and a
* <code>null</code> editor.
* This method is intended for serialization.
* @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
*/
public TableColumn() {
this(0);
}
/**
* Cover method, using a default width of 75, a <code>null</code>
* renderer and a <code>null</code> editor.
* @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
*/
public TableColumn(int modelIndex) {
this(modelIndex, 75, null, null);
}
/**
* Cover method, using a <code>null</code> renderer and a
* <code>null</code> editor.
* @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
*/
public TableColumn(int modelIndex, int width) {
this(modelIndex, width, null, null);
}
/**
* Creates and initializes an instance of
* <code>TableColumn</code> with the specified model index,
* width, cell renderer, and cell editor;
* all <code>TableColumn</code> constructors delegate to this one.
* The value of <code>width</code> is used
* for both the initial and preferred width;
* if <code>width</code> is negative,
* they're set to 0.
* The minimum width is set to 15 unless the initial width is less,
* in which case the minimum width is set to
* the initial width.
*
* <p>
* When the <code>cellRenderer</code>
* or <code>cellEditor</code> parameter is <code>null</code>,
* a default value provided by the <code>JTable</code>
* <code>getDefaultRenderer</code>
* or <code>getDefaultEditor</code> method, respectively,
* is used to
* provide defaults based on the type of the data in this column.
* This column-centric rendering strategy can be circumvented by overriding
* the <code>getCellRenderer</code> methods in <code>JTable</code>.
*
* @param modelIndex the index of the column
* in the model that supplies the data for this column in the table;
* the model index remains the same
* even when columns are reordered in the view
* @param width this column's preferred width and initial width
* @param cellRenderer the object used to render values in this column
* @param cellEditor the object used to edit values in this column
* @see #getMinWidth()
* @see JTable#getDefaultRenderer(Class)
* @see JTable#getDefaultEditor(Class)
* @see JTable#getCellRenderer(int, int)
* @see JTable#getCellEditor(int, int)
*/
public TableColumn(int modelIndex, int width,
TableCellRenderer cellRenderer,
TableCellEditor cellEditor) {
super();
this.modelIndex = modelIndex;
preferredWidth = this.width = Math.max(width, 0);
this.cellRenderer = cellRenderer;
this.cellEditor = cellEditor;
// Set other instance variables to default values.
minWidth = Math.min(15, this.width);
maxWidth = Integer.MAX_VALUE;
isResizable = true;
resizedPostingDisableCount = 0;
headerValue = null;
}
//
// Modifying and Querying attributes
//
private void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
if (changeSupport != null) {
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}
private void firePropertyChange(String propertyName, int oldValue, int newValue) {
if (oldValue != newValue) {
firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
}
}
private void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
if (oldValue != newValue) {
firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
}
}
/**
* Sets the model index for this column. The model index is the
* index of the column in the model that will be displayed by this
* <code>TableColumn</code>. As the <code>TableColumn</code>
* is moved around in the view the model index remains constant.
* @param modelIndex the new modelIndex
* @beaninfo
* bound: true
* description: The model index.
*/
public void setModelIndex(int modelIndex) {
int old = this.modelIndex;
this.modelIndex = modelIndex;
firePropertyChange("modelIndex", old, modelIndex);
}
/**
* Returns the model index for this column.
* @return the <code>modelIndex</code> property
*/
public int getModelIndex() {
return modelIndex;
}
/**
* Sets the <code>TableColumn</code>'s identifier to
* <code>anIdentifier</code>. <p>
* Note: identifiers are not used by the <code>JTable</code>,
* they are purely a
* convenience for the external tagging and location of columns.
*
* @param identifier an identifier for this column
* @see #getIdentifier
* @beaninfo
* bound: true
* description: A unique identifier for this column.
*/
public void setIdentifier(Object identifier) {
Object old = this.identifier;
this.identifier = identifier;
firePropertyChange("identifier", old, identifier);
}
/**
* Returns the <code>identifier</code> object for this column.
* Note identifiers are not used by <code>JTable</code>,
* they are purely a convenience for external use.
* If the <code>identifier</code> is <code>null</code>,
* <code>getIdentifier()</code> returns <code>getHeaderValue</code>
* as a default.
*
* @return the <code>identifier</code> property
* @see #setIdentifier
*/
public Object getIdentifier() {
return (identifier != null) ? identifier : getHeaderValue();
}
/**
* Sets the <code>Object</code> whose string representation will be
* used as the value for the <code>headerRenderer</code>. When the
* <code>TableColumn</code> is created, the default <code>headerValue</code>
* is <code>null</code>.
* @param headerValue the new headerValue
* @see #getHeaderValue
* @beaninfo
* bound: true
* description: The text to be used by the header renderer.
*/
public void setHeaderValue(Object headerValue) {
Object old = this.headerValue;
this.headerValue = headerValue;
firePropertyChange("headerValue", old, headerValue);
}
/**
* Returns the <code>Object</code> used as the value for the header
* renderer.
*
* @return the <code>headerValue</code> property
* @see #setHeaderValue
*/
public Object getHeaderValue() {
return headerValue;
}
//
// Renderers and Editors
//
/**
* Sets the <code>TableCellRenderer</code> used to draw the
* <code>TableColumn</code>'s header to <code>headerRenderer</code>.
* <p>
* It is the header renderers responsibility to render the sorting
* indicator. If you are using sorting and specify a renderer your
* renderer must render the sorting indication.
*
* @param headerRenderer the new headerRenderer
*
* @see #getHeaderRenderer
* @beaninfo
* bound: true
* description: The header renderer.
*/
public void setHeaderRenderer(TableCellRenderer headerRenderer) {
TableCellRenderer old = this.headerRenderer;
this.headerRenderer = headerRenderer;
firePropertyChange("headerRenderer", old, headerRenderer);
}
/**
* Returns the <code>TableCellRenderer</code> used to draw the header of the
* <code>TableColumn</code>. When the <code>headerRenderer</code> is
* <code>null</code>, the <code>JTableHeader</code>
* uses its <code>defaultRenderer</code>. The default value for a
* <code>headerRenderer</code> is <code>null</code>.
*
* @return the <code>headerRenderer</code> property
* @see #setHeaderRenderer
* @see #setHeaderValue
* @see javax.swing.table.JTableHeader#getDefaultRenderer()
*/
public TableCellRenderer getHeaderRenderer() {
return headerRenderer;
}
/**
* Sets the <code>TableCellRenderer</code> used by <code>JTable</code>
* to draw individual values for this column.
*
* @param cellRenderer the new cellRenderer
* @see #getCellRenderer
* @beaninfo
* bound: true
* description: The renderer to use for cell values.
*/
public void setCellRenderer(TableCellRenderer cellRenderer) {
TableCellRenderer old = this.cellRenderer;
this.cellRenderer = cellRenderer;
firePropertyChange("cellRenderer", old, cellRenderer);
}
/**
* Returns the <code>TableCellRenderer</code> used by the
* <code>JTable</code> to draw
* values for this column. The <code>cellRenderer</code> of the column
* not only controls the visual look for the column, but is also used to
* interpret the value object supplied by the <code>TableModel</code>.
* When the <code>cellRenderer</code> is <code>null</code>,
* the <code>JTable</code> uses a default renderer based on the
* class of the cells in that column. The default value for a
* <code>cellRenderer</code> is <code>null</code>.
*
* @return the <code>cellRenderer</code> property
* @see #setCellRenderer
* @see JTable#setDefaultRenderer
*/
public TableCellRenderer getCellRenderer() {
return cellRenderer;
}
/**
* Sets the editor to used by when a cell in this column is edited.
*
* @param cellEditor the new cellEditor
* @see #getCellEditor
* @beaninfo
* bound: true
* description: The editor to use for cell values.
*/
public void setCellEditor(TableCellEditor cellEditor){
TableCellEditor old = this.cellEditor;
this.cellEditor = cellEditor;
firePropertyChange("cellEditor", old, cellEditor);
}
/**
* Returns the <code>TableCellEditor</code> used by the
* <code>JTable</code> to edit values for this column. When the
* <code>cellEditor</code> is <code>null</code>, the <code>JTable</code>
* uses a default editor based on the
* class of the cells in that column. The default value for a
* <code>cellEditor</code> is <code>null</code>.
*
* @return the <code>cellEditor</code> property
* @see #setCellEditor
* @see JTable#setDefaultEditor
*/
public TableCellEditor getCellEditor() {
return cellEditor;
}
/**
* This method should not be used to set the widths of columns in the
* <code>JTable</code>, use <code>setPreferredWidth</code> instead.
* Like a layout manager in the
* AWT, the <code>JTable</code> adjusts a column's width automatically
* whenever the
* table itself changes size, or a column's preferred width is changed.
* Setting widths programmatically therefore has no long term effect.
* <p>
* This method sets this column's width to <code>width</code>.
* If <code>width</code> exceeds the minimum or maximum width,
* it is adjusted to the appropriate limiting value.
* @param width the new width
* @see #getWidth
* @see #setMinWidth
* @see #setMaxWidth
* @see #setPreferredWidth
* @see JTable#doLayout()
* @beaninfo
* bound: true
* description: The width of the column.
*/
public void setWidth(int width) {
int old = this.width;
this.width = Math.min(Math.max(width, minWidth), maxWidth);
firePropertyChange("width", old, this.width);
}
/**
* Returns the width of the <code>TableColumn</code>. The default width is
* 75.
*
* @return the <code>width</code> property
* @see #setWidth
*/
public int getWidth() {
return width;
}
/**
* Sets this column's preferred width to <code>preferredWidth</code>.
* If <code>preferredWidth</code> exceeds the minimum or maximum width,
* it is adjusted to the appropriate limiting value.
* <p>
* For details on how the widths of columns in the <code>JTable</code>
* (and <code>JTableHeader</code>) are calculated from the
* <code>preferredWidth</code>,
* see the <code>doLayout</code> method in <code>JTable</code>.
*
* @param preferredWidth the new preferred width
* @see #getPreferredWidth
* @see JTable#doLayout()
* @beaninfo
* bound: true
* description: The preferred width of the column.
*/
public void setPreferredWidth(int preferredWidth) {
int old = this.preferredWidth;
this.preferredWidth = Math.min(Math.max(preferredWidth, minWidth), maxWidth);
firePropertyChange("preferredWidth", old, this.preferredWidth);
}
/**
* Returns the preferred width of the <code>TableColumn</code>.
* The default preferred width is 75.
*
* @return the <code>preferredWidth</code> property
* @see #setPreferredWidth
*/
public int getPreferredWidth() {
return preferredWidth;
}
/**
* Sets the <code>TableColumn</code>'s minimum width to
* <code>minWidth</code>,
* adjusting the new minimum width if necessary to ensure that
* 0 &lt;= <code>minWidth</code> &lt;= <code>maxWidth</code>.
* For example, if the <code>minWidth</code> argument is negative,
* this method sets the <code>minWidth</code> property to 0.
*
* <p>
* If the value of the
* <code>width</code> or <code>preferredWidth</code> property
* is less than the new minimum width,
* this method sets that property to the new minimum width.
*
* @param minWidth the new minimum width
* @see #getMinWidth
* @see #setPreferredWidth
* @see #setMaxWidth
* @beaninfo
* bound: true
* description: The minimum width of the column.
*/
public void setMinWidth(int minWidth) {
int old = this.minWidth;
this.minWidth = Math.max(Math.min(minWidth, maxWidth), 0);
if (width < this.minWidth) {
setWidth(this.minWidth);
}
if (preferredWidth < this.minWidth) {
setPreferredWidth(this.minWidth);
}
firePropertyChange("minWidth", old, this.minWidth);
}
/**
* Returns the minimum width for the <code>TableColumn</code>. The
* <code>TableColumn</code>'s width can't be made less than this either
* by the user or programmatically.
*
* @return the <code>minWidth</code> property
* @see #setMinWidth
* @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
*/
public int getMinWidth() {
return minWidth;
}
/**
* Sets the <code>TableColumn</code>'s maximum width to
* <code>maxWidth</code> or,
* if <code>maxWidth</code> is less than the minimum width,
* to the minimum width.
*
* <p>
* If the value of the
* <code>width</code> or <code>preferredWidth</code> property
* is more than the new maximum width,
* this method sets that property to the new maximum width.
*
* @param maxWidth the new maximum width
* @see #getMaxWidth
* @see #setPreferredWidth
* @see #setMinWidth
* @beaninfo
* bound: true
* description: The maximum width of the column.
*/
public void setMaxWidth(int maxWidth) {
int old = this.maxWidth;
this.maxWidth = Math.max(minWidth, maxWidth);
if (width > this.maxWidth) {
setWidth(this.maxWidth);
}
if (preferredWidth > this.maxWidth) {
setPreferredWidth(this.maxWidth);
}
firePropertyChange("maxWidth", old, this.maxWidth);
}
/**
* Returns the maximum width for the <code>TableColumn</code>. The
* <code>TableColumn</code>'s width can't be made larger than this
* either by the user or programmatically. The default maxWidth
* is Integer.MAX_VALUE.
*
* @return the <code>maxWidth</code> property
* @see #setMaxWidth
*/
public int getMaxWidth() {
return maxWidth;
}
/**
* Sets whether this column can be resized.
*
* @param isResizable if true, resizing is allowed; otherwise false
* @see #getResizable
* @beaninfo
* bound: true
* description: Whether or not this column can be resized.
*/
public void setResizable(boolean isResizable) {
boolean old = this.isResizable;
this.isResizable = isResizable;
firePropertyChange("isResizable", old, this.isResizable);
}
/**
* Returns true if the user is allowed to resize the
* <code>TableColumn</code>'s
* width, false otherwise. You can change the width programmatically
* regardless of this setting. The default is true.
*
* @return the <code>isResizable</code> property
* @see #setResizable
*/
public boolean getResizable() {
return isResizable;
}
/**
* Resizes the <code>TableColumn</code> to fit the width of its header cell.
* This method does nothing if the header renderer is <code>null</code>
* (the default case). Otherwise, it sets the minimum, maximum and preferred
* widths of this column to the widths of the minimum, maximum and preferred
* sizes of the Component delivered by the header renderer.
* The transient "width" property of this TableColumn is also set to the
* preferred width. Note this method is not used internally by the table
* package.
*
* @see #setPreferredWidth
*/
public void sizeWidthToFit() {
if (headerRenderer == null) {
return;
}
Component c = headerRenderer.getTableCellRendererComponent(null,
getHeaderValue(), false, false, 0, 0);
setMinWidth(c.getMinimumSize().width);
setMaxWidth(c.getMaximumSize().width);
setPreferredWidth(c.getPreferredSize().width);
setWidth(getPreferredWidth());
}
/**
* This field was not used in previous releases and there are
* currently no plans to support it in the future.
*
* @deprecated as of Java 2 platform v1.3
*/
@Deprecated
public void disableResizedPosting() {
resizedPostingDisableCount++;
}
/**
* This field was not used in previous releases and there are
* currently no plans to support it in the future.
*
* @deprecated as of Java 2 platform v1.3
*/
@Deprecated
public void enableResizedPosting() {
resizedPostingDisableCount--;
}
//
// Property Change Support
//
/**
* Adds a <code>PropertyChangeListener</code> to the listener list.
* The listener is registered for all properties.
* <p>
* A <code>PropertyChangeEvent</code> will get fired in response to an
* explicit call to <code>setFont</code>, <code>setBackground</code>,
* or <code>setForeground</code> on the
* current component. Note that if the current component is
* inheriting its foreground, background, or font from its
* container, then no event will be fired in response to a
* change in the inherited property.
*
* @param listener the listener to be added
*
*/
public synchronized void addPropertyChangeListener(
PropertyChangeListener listener) {
if (changeSupport == null) {
changeSupport = new SwingPropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
/**
* Removes a <code>PropertyChangeListener</code> from the listener list.
* The <code>PropertyChangeListener</code> to be removed was registered
* for all properties.
*
* @param listener the listener to be removed
*
*/
public synchronized void removePropertyChangeListener(
PropertyChangeListener listener) {
if (changeSupport != null) {
changeSupport.removePropertyChangeListener(listener);
}
}
/**
* Returns an array of all the <code>PropertyChangeListener</code>s added
* to this TableColumn with addPropertyChangeListener().
*
* @return all of the <code>PropertyChangeListener</code>s added or an empty
* array if no listeners have been added
* @since 1.4
*/
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
return changeSupport.getPropertyChangeListeners();
}
//
// Protected Methods
//
/**
* As of Java 2 platform v1.3, this method is not called by the <code>TableColumn</code>
* constructor. Previously this method was used by the
* <code>TableColumn</code> to create a default header renderer.
* As of Java 2 platform v1.3, the default header renderer is <code>null</code>.
* <code>JTableHeader</code> now provides its own shared default
* renderer, just as the <code>JTable</code> does for its cell renderers.
*
* @return the default header renderer
* @see javax.swing.table.JTableHeader#createDefaultRenderer()
*/
protected TableCellRenderer createDefaultHeaderRenderer() {
DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
setText((value == null) ? "" : value.toString());
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
};
label.setHorizontalAlignment(JLabel.CENTER);
return label;
}
} // End of class TableColumn

View File

@@ -0,0 +1,241 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.util.Enumeration;
import javax.swing.event.ChangeEvent;
import javax.swing.event.*;
import javax.swing.*;
/**
* Defines the requirements for a table column model object suitable for
* use with <code>JTable</code>.
*
* @author Alan Chung
* @author Philip Milne
* @see DefaultTableColumnModel
*/
public interface TableColumnModel
{
//
// Modifying the model
//
/**
* Appends <code>aColumn</code> to the end of the
* <code>tableColumns</code> array.
* This method posts a <code>columnAdded</code>
* event to its listeners.
*
* @param aColumn the <code>TableColumn</code> to be added
* @see #removeColumn
*/
public void addColumn(TableColumn aColumn);
/**
* Deletes the <code>TableColumn</code> <code>column</code> from the
* <code>tableColumns</code> array. This method will do nothing if
* <code>column</code> is not in the table's column list.
* This method posts a <code>columnRemoved</code>
* event to its listeners.
*
* @param column the <code>TableColumn</code> to be removed
* @see #addColumn
*/
public void removeColumn(TableColumn column);
/**
* Moves the column and its header at <code>columnIndex</code> to
* <code>newIndex</code>. The old column at <code>columnIndex</code>
* will now be found at <code>newIndex</code>. The column that used
* to be at <code>newIndex</code> is shifted left or right
* to make room. This will not move any columns if
* <code>columnIndex</code> equals <code>newIndex</code>. This method
* posts a <code>columnMoved</code> event to its listeners.
*
* @param columnIndex the index of column to be moved
* @param newIndex index of the column's new location
* @exception IllegalArgumentException if <code>columnIndex</code> or
* <code>newIndex</code>
* are not in the valid range
*/
public void moveColumn(int columnIndex, int newIndex);
/**
* Sets the <code>TableColumn</code>'s column margin to
* <code>newMargin</code>. This method posts
* a <code>columnMarginChanged</code> event to its listeners.
*
* @param newMargin the width, in pixels, of the new column margins
* @see #getColumnMargin
*/
public void setColumnMargin(int newMargin);
//
// Querying the model
//
/**
* Returns the number of columns in the model.
* @return the number of columns in the model
*/
public int getColumnCount();
/**
* Returns an <code>Enumeration</code> of all the columns in the model.
* @return an <code>Enumeration</code> of all the columns in the model
*/
public Enumeration<TableColumn> getColumns();
/**
* Returns the index of the first column in the table
* whose identifier is equal to <code>identifier</code>,
* when compared using <code>equals</code>.
*
* @param columnIdentifier the identifier object
* @return the index of the first table column
* whose identifier is equal to <code>identifier</code>
* @exception IllegalArgumentException if <code>identifier</code>
* is <code>null</code>, or no
* <code>TableColumn</code> has this
* <code>identifier</code>
* @see #getColumn
*/
public int getColumnIndex(Object columnIdentifier);
/**
* Returns the <code>TableColumn</code> object for the column at
* <code>columnIndex</code>.
*
* @param columnIndex the index of the desired column
* @return the <code>TableColumn</code> object for
* the column at <code>columnIndex</code>
*/
public TableColumn getColumn(int columnIndex);
/**
* Returns the width between the cells in each column.
* @return the margin, in pixels, between the cells
*/
public int getColumnMargin();
/**
* Returns the index of the column that lies on the
* horizontal point, <code>xPosition</code>;
* or -1 if it lies outside the any of the column's bounds.
*
* In keeping with Swing's separable model architecture, a
* TableColumnModel does not know how the table columns actually appear on
* screen. The visual presentation of the columns is the responsibility
* of the view/controller object using this model (typically JTable). The
* view/controller need not display the columns sequentially from left to
* right. For example, columns could be displayed from right to left to
* accommodate a locale preference or some columns might be hidden at the
* request of the user. Because the model does not know how the columns
* are laid out on screen, the given <code>xPosition</code> should not be
* considered to be a coordinate in 2D graphics space. Instead, it should
* be considered to be a width from the start of the first column in the
* model. If the column index for a given X coordinate in 2D space is
* required, <code>JTable.columnAtPoint</code> can be used instead.
*
* @return the index of the column; or -1 if no column is found
* @see javax.swing.JTable#columnAtPoint
*/
public int getColumnIndexAtX(int xPosition);
/**
* Returns the total width of all the columns.
* @return the total computed width of all columns
*/
public int getTotalColumnWidth();
//
// Selection
//
/**
* Sets whether the columns in this model may be selected.
* @param flag true if columns may be selected; otherwise false
* @see #getColumnSelectionAllowed
*/
public void setColumnSelectionAllowed(boolean flag);
/**
* Returns true if columns may be selected.
* @return true if columns may be selected
* @see #setColumnSelectionAllowed
*/
public boolean getColumnSelectionAllowed();
/**
* Returns an array of indicies of all selected columns.
* @return an array of integers containing the indicies of all
* selected columns; or an empty array if nothing is selected
*/
public int[] getSelectedColumns();
/**
* Returns the number of selected columns.
*
* @return the number of selected columns; or 0 if no columns are selected
*/
public int getSelectedColumnCount();
/**
* Sets the selection model.
*
* @param newModel a <code>ListSelectionModel</code> object
* @see #getSelectionModel
*/
public void setSelectionModel(ListSelectionModel newModel);
/**
* Returns the current selection model.
*
* @return a <code>ListSelectionModel</code> object
* @see #setSelectionModel
*/
public ListSelectionModel getSelectionModel();
//
// Listener
//
/**
* Adds a listener for table column model events.
*
* @param x a <code>TableColumnModelListener</code> object
*/
public void addColumnModelListener(TableColumnModelListener x);
/**
* Removes a listener for table column model events.
*
* @param x a <code>TableColumnModelListener</code> object
*/
public void removeColumnModelListener(TableColumnModelListener x);
}

View File

@@ -0,0 +1,143 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import javax.swing.*;
import javax.swing.event.*;
/**
* The <code>TableModel</code> interface specifies the methods the
* <code>JTable</code> will use to interrogate a tabular data model. <p>
*
* The <code>JTable</code> can be set up to display any data
* model which implements the
* <code>TableModel</code> interface with a couple of lines of code:
* <pre>
* TableModel myData = new MyTableModel();
* JTable table = new JTable(myData);
* </pre><p>
*
* For further documentation, see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data">Creating a Table Model</a>
* in <em>The Java Tutorial</em>.
*
* @author Philip Milne
* @see JTable
*/
public interface TableModel
{
/**
* Returns the number of rows in the model. A
* <code>JTable</code> uses this method to determine how many rows it
* should display. This method should be quick, as it
* is called frequently during rendering.
*
* @return the number of rows in the model
* @see #getColumnCount
*/
public int getRowCount();
/**
* Returns the number of columns in the model. A
* <code>JTable</code> uses this method to determine how many columns it
* should create and display by default.
*
* @return the number of columns in the model
* @see #getRowCount
*/
public int getColumnCount();
/**
* Returns the name of the column at <code>columnIndex</code>. This is used
* to initialize the table's column header name. Note: this name does
* not need to be unique; two columns in a table can have the same name.
*
* @param columnIndex the index of the column
* @return the name of the column
*/
public String getColumnName(int columnIndex);
/**
* Returns the most specific superclass for all the cell values
* in the column. This is used by the <code>JTable</code> to set up a
* default renderer and editor for the column.
*
* @param columnIndex the index of the column
* @return the common ancestor class of the object values in the model.
*/
public Class<?> getColumnClass(int columnIndex);
/**
* Returns true if the cell at <code>rowIndex</code> and
* <code>columnIndex</code>
* is editable. Otherwise, <code>setValueAt</code> on the cell will not
* change the value of that cell.
*
* @param rowIndex the row whose value to be queried
* @param columnIndex the column whose value to be queried
* @return true if the cell is editable
* @see #setValueAt
*/
public boolean isCellEditable(int rowIndex, int columnIndex);
/**
* Returns the value for the cell at <code>columnIndex</code> and
* <code>rowIndex</code>.
*
* @param rowIndex the row whose value is to be queried
* @param columnIndex the column whose value is to be queried
* @return the value Object at the specified cell
*/
public Object getValueAt(int rowIndex, int columnIndex);
/**
* Sets the value in the cell at <code>columnIndex</code> and
* <code>rowIndex</code> to <code>aValue</code>.
*
* @param aValue the new value
* @param rowIndex the row whose value is to be changed
* @param columnIndex the column whose value is to be changed
* @see #getValueAt
* @see #isCellEditable
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex);
/**
* Adds a listener to the list that is notified each time a change
* to the data model occurs.
*
* @param l the TableModelListener
*/
public void addTableModelListener(TableModelListener l);
/**
* Removes a listener from the list that is notified each time a
* change to the data model occurs.
*
* @param l the TableModelListener
*/
public void removeTableModelListener(TableModelListener l);
}

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.text.Collator;
import java.util.*;
import javax.swing.DefaultRowSorter;
import javax.swing.RowFilter;
import javax.swing.SortOrder;
/**
* An implementation of <code>RowSorter</code> that provides sorting
* and filtering using a <code>TableModel</code>.
* The following example shows adding sorting to a <code>JTable</code>:
* <pre>
* TableModel myModel = createMyTableModel();
* JTable table = new JTable(myModel);
* table.setRowSorter(new TableRowSorter(myModel));
* </pre>
* This will do all the wiring such that when the user does the appropriate
* gesture, such as clicking on the column header, the table will
* visually sort.
* <p>
* <code>JTable</code>'s row-based methods and <code>JTable</code>'s
* selection model refer to the view and not the underlying
* model. Therefore, it is necessary to convert between the two. For
* example, to get the selection in terms of <code>myModel</code>
* you need to convert the indices:
* <pre>
* int[] selection = table.getSelectedRows();
* for (int i = 0; i &lt; selection.length; i++) {
* selection[i] = table.convertRowIndexToModel(selection[i]);
* }
* </pre>
* Similarly to select a row in <code>JTable</code> based on
* a coordinate from the underlying model do the inverse:
* <pre>
* table.setRowSelectionInterval(table.convertRowIndexToView(row),
* table.convertRowIndexToView(row));
* </pre>
* <p>
* The previous example assumes you have not enabled filtering. If you
* have enabled filtering <code>convertRowIndexToView</code> will return
* -1 for locations that are not visible in the view.
* <p>
* <code>TableRowSorter</code> uses <code>Comparator</code>s for doing
* comparisons. The following defines how a <code>Comparator</code> is
* chosen for a column:
* <ol>
* <li>If a <code>Comparator</code> has been specified for the column by the
* <code>setComparator</code> method, use it.
* <li>If the column class as returned by <code>getColumnClass</code> is
* <code>String</code>, use the <code>Comparator</code> returned by
* <code>Collator.getInstance()</code>.
* <li>If the column class implements <code>Comparable</code>, use a
* <code>Comparator</code> that invokes the <code>compareTo</code>
* method.
* <li>If a <code>TableStringConverter</code> has been specified, use it
* to convert the values to <code>String</code>s and then use the
* <code>Comparator</code> returned by <code>Collator.getInstance()</code>.
* <li>Otherwise use the <code>Comparator</code> returned by
* <code>Collator.getInstance()</code> on the results from
* calling <code>toString</code> on the objects.
* </ol>
* <p>
* In addition to sorting <code>TableRowSorter</code> provides the ability
* to filter. A filter is specified using the <code>setFilter</code>
* method. The following example will only show rows containing the string
* "foo":
* <pre>
* TableModel myModel = createMyTableModel();
* TableRowSorter sorter = new TableRowSorter(myModel);
* sorter.setRowFilter(RowFilter.regexFilter(".*foo.*"));
* JTable table = new JTable(myModel);
* table.setRowSorter(sorter);
* </pre>
* <p>
* If the underlying model structure changes (the
* <code>modelStructureChanged</code> method is invoked) the following
* are reset to their default values: <code>Comparator</code>s by
* column, current sort order, and whether each column is sortable. The default
* sort order is natural (the same as the model), and columns are
* sortable by default.
* <p>
* <code>TableRowSorter</code> has one formal type parameter: the type
* of the model. Passing in a type that corresponds exactly to your
* model allows you to filter based on your model without casting.
* Refer to the documentation of <code>RowFilter</code> for an example
* of this.
* <p>
* <b>WARNING:</b> <code>DefaultTableModel</code> returns a column
* class of <code>Object</code>. As such all comparisons will
* be done using <code>toString</code>. This may be unnecessarily
* expensive. If the column only contains one type of value, such as
* an <code>Integer</code>, you should override <code>getColumnClass</code> and
* return the appropriate <code>Class</code>. This will dramatically
* increase the performance of this class.
*
* @param <M> the type of the model, which must be an implementation of
* <code>TableModel</code>
* @see javax.swing.JTable
* @see javax.swing.RowFilter
* @see javax.swing.table.DefaultTableModel
* @see java.text.Collator
* @see java.util.Comparator
* @since 1.6
*/
public class TableRowSorter<M extends TableModel> extends DefaultRowSorter<M, Integer> {
/**
* Comparator that uses compareTo on the contents.
*/
private static final Comparator COMPARABLE_COMPARATOR =
new ComparableComparator();
/**
* Underlying model.
*/
private M tableModel;
/**
* For toString conversions.
*/
private TableStringConverter stringConverter;
/**
* Creates a <code>TableRowSorter</code> with an empty model.
*/
public TableRowSorter() {
this(null);
}
/**
* Creates a <code>TableRowSorter</code> using <code>model</code>
* as the underlying <code>TableModel</code>.
*
* @param model the underlying <code>TableModel</code> to use,
* <code>null</code> is treated as an empty model
*/
public TableRowSorter(M model) {
setModel(model);
}
/**
* Sets the <code>TableModel</code> to use as the underlying model
* for this <code>TableRowSorter</code>. A value of <code>null</code>
* can be used to set an empty model.
*
* @param model the underlying model to use, or <code>null</code>
*/
public void setModel(M model) {
tableModel = model;
setModelWrapper(new TableRowSorterModelWrapper());
}
/**
* Sets the object responsible for converting values from the
* model to strings. If non-<code>null</code> this
* is used to convert any object values, that do not have a
* registered <code>Comparator</code>, to strings.
*
* @param stringConverter the object responsible for converting values
* from the model to strings
*/
public void setStringConverter(TableStringConverter stringConverter) {
this.stringConverter = stringConverter;
}
/**
* Returns the object responsible for converting values from the
* model to strings.
*
* @return object responsible for converting values to strings.
*/
public TableStringConverter getStringConverter() {
return stringConverter;
}
/**
* Returns the <code>Comparator</code> for the specified
* column. If a <code>Comparator</code> has not been specified using
* the <code>setComparator</code> method a <code>Comparator</code>
* will be returned based on the column class
* (<code>TableModel.getColumnClass</code>) of the specified column.
* If the column class is <code>String</code>,
* <code>Collator.getInstance</code> is returned. If the
* column class implements <code>Comparable</code> a private
* <code>Comparator</code> is returned that invokes the
* <code>compareTo</code> method. Otherwise
* <code>Collator.getInstance</code> is returned.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public Comparator<?> getComparator(int column) {
Comparator comparator = super.getComparator(column);
if (comparator != null) {
return comparator;
}
Class columnClass = getModel().getColumnClass(column);
if (columnClass == String.class) {
return Collator.getInstance();
}
if (Comparable.class.isAssignableFrom(columnClass)) {
return COMPARABLE_COMPARATOR;
}
return Collator.getInstance();
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
protected boolean useToString(int column) {
Comparator comparator = super.getComparator(column);
if (comparator != null) {
return false;
}
Class columnClass = getModel().getColumnClass(column);
if (columnClass == String.class) {
return false;
}
if (Comparable.class.isAssignableFrom(columnClass)) {
return false;
}
return true;
}
/**
* Implementation of DefaultRowSorter.ModelWrapper that delegates to a
* TableModel.
*/
private class TableRowSorterModelWrapper extends ModelWrapper<M,Integer> {
public M getModel() {
return tableModel;
}
public int getColumnCount() {
return (tableModel == null) ? 0 : tableModel.getColumnCount();
}
public int getRowCount() {
return (tableModel == null) ? 0 : tableModel.getRowCount();
}
public Object getValueAt(int row, int column) {
return tableModel.getValueAt(row, column);
}
public String getStringValueAt(int row, int column) {
TableStringConverter converter = getStringConverter();
if (converter != null) {
// Use the converter
String value = converter.toString(
tableModel, row, column);
if (value != null) {
return value;
}
return "";
}
// No converter, use getValueAt followed by toString
Object o = getValueAt(row, column);
if (o == null) {
return "";
}
String string = o.toString();
if (string == null) {
return "";
}
return string;
}
public Integer getIdentifier(int index) {
return index;
}
}
private static class ComparableComparator implements Comparator {
@SuppressWarnings("unchecked")
public int compare(Object o1, Object o2) {
return ((Comparable)o1).compareTo(o2);
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
/**
* TableStringConverter is used to convert objects from the model into
* strings. This is useful in filtering and searching when the model returns
* objects that do not have meaningful <code>toString</code> implementations.
*
* @since 1.6
*/
public abstract class TableStringConverter {
/**
* Returns the string representation of the value at the specified
* location.
*
* @param model the <code>TableModel</code> to fetch the value from
* @param row the row the string is being requested for
* @param column the column the string is being requested for
* @return the string representation. This should never return null.
* @throws NullPointerException if <code>model</code> is null
* @throws IndexOutOfBoundsException if the arguments are outside the
* bounds of the model
*/
public abstract String toString(TableModel model, int row, int column);
}