|
Java example source code file (DefaultTableColumnModel.java)
This example Java source code file (DefaultTableColumnModel.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The DefaultTableColumnModel.java Java example source code
/*
* 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.
* <p>
* <strong>Warning:
* 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™
* has been added to the <code>java.beans 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 to the end of the
* <code>tableColumns array.
* This method also posts the <code>columnAdded
* event to its listeners.
*
* @param aColumn the <code>TableColumn to be added
* @exception IllegalArgumentException if <code>aColumn is
* <code>null
* @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 from the
* <code>tableColumns array. This method will do nothing if
* <code>column is not in the table's columns list.
* <code>tile is called
* to resize both the header and table views.
* This method also posts a <code>columnRemoved
* event to its listeners.
*
* @param column the <code>TableColumn 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 to
* <code>newIndex. The old column at columnIndex
* will now be found at <code>newIndex. The column
* that used to be at <code>newIndex is shifted
* left or right to make room. This will not move any columns if
* <code>columnIndex equals newIndex . This method
* also posts a <code>columnMoved 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 or
* <code>newIndex
* 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. This method
* also posts a <code>columnMarginChanged 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 array.
*
* @return the number of columns in the <code>tableColumns array
* @see #getColumns
*/
public int getColumnCount() {
return tableColumns.size();
}
/**
* Returns an <code>Enumeration of all the columns in the model.
* @return an <code>Enumeration of the columns in the model
*/
public Enumeration<TableColumn> getColumns() {
return tableColumns.elements();
}
/**
* Returns the index of the first column in the <code>tableColumns
* array whose identifier is equal to <code>identifier,
* when compared using <code>equals.
*
* @param identifier the identifier object
* @return the index of the first column in the
* <code>tableColumns array whose identifier
* is equal to <code>identifier
* @exception IllegalArgumentException if <code>identifier
* is <code>null, or if no
* <code>TableColumn has this
* <code>identifier
* @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 object for the column
* at <code>columnIndex.
*
* @param columnIndex the index of the column desired
* @return the <code>TableColumn object for the column
* at <code>columnIndex
*/
public TableColumn getColumn(int columnIndex) {
return tableColumns.elementAt(columnIndex);
}
/**
* Returns the width margin for <code>TableColumn.
* The default <code>columnMargin is 1.
*
* @return the maximum width for the <code>TableColumn
* @see #setColumnMargin
*/
public int getColumnMargin() {
return columnMargin;
}
/**
* Returns the index of the column that lies at position <code>x,
* 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 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 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 property
*/
public int getTotalColumnWidth() {
if (totalColumnWidth == -1) {
recalcWidthCache();
}
return totalColumnWidth;
}
//
// Selection model
//
/**
* Sets the selection model for this <code>TableColumnModel
* to <code>newModel
* and registers for listener notifications from the new selection
* model. If <code>newModel is null ,
* an exception is thrown.
*
* @param newModel the new selection model
* @exception IllegalArgumentException if <code>newModel
* is <code>null
* @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 that is used to
* maintain column selection state.
*
* @return the object that provides column selection state. Or
* <code>null 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 property
*/
public boolean getColumnSelectionAllowed() {
return columnSelectionAllowed;
}
// implements javax.swing.table.TableColumnModel
/**
* Returns an array of selected columns. If <code>selectionModel
* is <code>null, returns an empty array.
* @return an array of selected columns or an empty array if nothing
* is selected or the <code>selectionModel is
* <code>null
*/
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 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 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>ColumnModelListeners
* 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>FooListeners
* upon this model.
* <code>FooListeners are registered using the
* <code>addFooListener method.
*
* <p>
*
* You can specify the <code>listenerType argument
* with a class literal,
* such as
* <code>FooListener.class.
* For example, you can query a
* <code>DefaultTableColumnModel m
* for its column model listeners with the following code:
*
* <pre>ColumnModelListener[] cmls = (ColumnModelListener[])(m.getListeners(ColumnModelListener.class));
*
* 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
* @return an array of all objects registered as
* <code> FooListeners on this model,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType
* doesn't specify a class or interface that implements
* <code>java.util.EventListener
*
* @see #getColumnModelListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class 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
*/
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 that forwards
* <code>ListSelectionEvents 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 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
Other Java examples (source code examples)
Here is a short list of links related to this Java DefaultTableColumnModel.java source code file:
|