home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
TableColumn.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
20KB
|
647 lines
/*
* @(#)TableColumn.java 1.24 98/02/02
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.table;
import com.sun.java.swing.*;
import com.sun.java.swing.border.*;
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 <B>TableColumn</B> represents all the attributes of a column in a
* <B>JTable</B>, such as width, resizibility, minimum and maximum width.
* In addition, the <B>TableColumn</B> also helps to determine how the JTable
* interprets and displays the value objects from the TableModel in
* the column. This is done using the cellRenderer of the column. For
* example, the TableModel can give the table Boolean objects
* for a column. If the column's cellRenderer is a <B>JCheckBox</B>
* component then the table will be able
* to show the Boolean value as a checkbox. If the column's
* cellEditor is set similarly the user will then be able to modify the cell
* value using a <B>JCheckBox</B>. This pairing of source's value object with
* cell renders and editors gives the table a great deal of power and flexibility.
* Because the table does not need to know anything about the data being
* displayed, the user is free to customize it.
* <p>
* The TableColumn stores the link between the columns in the <B>JTable</B>
* and the columns in the <B>TableModel</B>. This, the <I>modelIndex</I>, is the
* column in the TableModel which will be queried for the data values for the
* cells in this column. As the column moves around in the view this
* <I>modelIndex</I> does not change.
* <p>
* It is also possible to specify renderers and editors on a per type basis
* rather than a per column basis - see the <I>setDefaultRenderer()</I> method
* in the <B>JTable</B>. This default mechanism is only used when the renderer (or
* editor) in the <B>TableColumn</B> is <I>null</I>.
* <p>
* 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 Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.24 02/02/98
* @author Alan Chung
* @author Philip Milne
* @see TableColumnModel
* @see DefaultTableColumnModel
*/
public class TableColumn extends Object implements Serializable {
//
// Static Constants
//
/** Bound property name. */
public final static String COLUMN_WIDTH_PROPERTY = "columWidth";
/** Bound property name. */
public final static String HEADER_VALUE_PROPERTY = "headerValue";
/** Bound property name. */
public final static String HEADER_RENDERER_PROPERTY = "headerRenderer";
/** Bound property name. */
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 TableColumn. As columns are moved around in the view the
* model index remains constant.
*/
protected int modelIndex;
/**
* This object is not used internally by the drawing machinery of
* the JTable. Identifiers may be set in the TableColumn as as an
* optional way to tag and locate TableColumns. The table package does
* not modify or invoke any methods in these identifer objects other
* than the <I>equals</I> method which is used in the
* <I>getColumnIndex()</I> method in the <B>DefaultTableColumnModel</B>.
*/
protected Object identifier;
/** The width of the column */
protected int width;
/** The minimum width of the column */
protected int minWidth;
/** 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;
/** Resizable flag */
protected boolean isResizable;
/**
* Counter used to disable posting of resizing notifications until the
* end of the resize
*/
transient protected int resizedPostingDisableCount;
/**
* If any PropertyChangeListeners have been registered, the
* changeSupport field describes them.
*/
private java.beans.PropertyChangeSupport changeSupport;
//
// Constructors
//
/**
* Creates an empty <B>TableColumn</B>. This is intended for the use
* of the serialization code. <p>
*
*/
public TableColumn() {
this(0);
}
/**
* Creates and initializes an instance of <B>TableColumn</B> with
* <I>modelIndex</I>.
* The <I>modelIndex</I> is the index of the column in the model which
* will supply the data for this column in the table. This, like the
* <I>columnIdentifier</I> in previous releases, does not change as the
* columns are moved in the view.
* <p>
*
* @param modelIndex the column in the model which provides the values for this column
* @see #setHeaderValue()
*/
public TableColumn(int modelIndex) {
this(modelIndex, 75, null, null);
}
public TableColumn(int modelIndex, int width) {
this(modelIndex, width, null, null);
}
public TableColumn(int modelIndex, int width,
TableCellRenderer cellRenderer,
TableCellEditor cellEditor) {
super();
this.modelIndex = modelIndex;
this.width = width;
this.cellRenderer = cellRenderer;
this.cellEditor = cellEditor;
// Set other instance variables to default values.
minWidth = 15;
maxWidth = Integer.MAX_VALUE;
isResizable = true;
resizedPostingDisableCount = 0;
setHeaderRenderer(createDefaultHeaderRenderer());
headerValue = null;
}
//
// Modifying and Querying attributes
//
/**
* 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
* TableColumn. As the TableColumn is moved around in the view
* the model index remains constant.
*/
public void setModelIndex(int anIndex)
{
modelIndex = anIndex;
}
/**
* Gets the model index for this column.
*/
public int getModelIndex()
{
return modelIndex;
}
/**
* Sets the <B>TableColumn</B>'s identifier to <I>anIdentifier</I>.
* Note identifiers are not used by the JTable, they are purely a
* convenience for the external tagging and location of columns.
*
* @param anIdentifier an identifier for this column
* @see #getIdentifier()
*/
public void setIdentifier(Object anIdentifier)
{
identifier = anIdentifier;
}
/**
* Returns the identifier object for this column. Note identifiers are not
* used by the JTable, they are purely a convenience for external use.
* If the identifier is <I>null</I> <I>getIdentifier()</I> returns
* <code>getHeaderValue()</code> as a default.
*
* @return the idenitifer object for this column
* @see #setIdentifier()
*/
public Object getIdentifier()
{
return (identifier != null) ? identifier : getHeaderValue();
}
/**
* Sets the <B>TableCellRenderer</B> used to draw the <B>TableColumn's</B>
* header to <I>aRenderer</I>. Posts a bound property change notification
* with the name HEADER_RENDERER_PROPERTY.
*
* @exception IllegalArgumentException if <I>aRenderer</I> is null.
* @param aRenderer the new header renderer
* @see #getHeaderRenderer()
*/
public void setHeaderRenderer(TableCellRenderer aRenderer)
{
TableCellRenderer oldRenderer = headerRenderer;
if (aRenderer == null) {
throw new IllegalArgumentException("Object is null");
}
headerRenderer = aRenderer;
// Post header renderer changed event notification
if (changeSupport != null) {
changeSupport.firePropertyChange(HEADER_RENDERER_PROPERTY,
oldRenderer, headerRenderer);
}
}
/**
* Returns the <B>TableCellRenderer</B> used to draw the header of the
* <B>TableColumn</B>. The default header renderer is a
* <B>JCellRenderer</B> initialized with a <B>JLabel</B>.
*
* @return the <B>TableCellRenderer</B> used to draw the header
* @see #setHeaderRenderer()
* @see #setHeaderValue()
*/
public TableCellRenderer getHeaderRenderer()
{
return headerRenderer;
}
/**
* Sets the <B>Object</B> used as the value for the headerRenderer
* Posts a bound property change notification with the name
* HEADER_VALUE_PROPERTY.
*
* @param aValue the new header value
* @see #getHeaderValue()
*/
public void setHeaderValue(Object aValue)
{
Object oldValue = headerValue;
headerValue = aValue;
// Post header value changed event notification
if (changeSupport != null) {
changeSupport.firePropertyChange(HEADER_VALUE_PROPERTY,
oldValue, headerValue);
}
}
/**
* Returns the <B>Object</B> used as the value for the header renderer.
*
* @return the <B>Object</B> used as the value for the header renderer
* @see #setHeaderValue()
*/
public Object getHeaderValue() {
return headerValue;
}
/**
* Sets the <B>TableCellRenderer</B> used by <B>JTable</B> to draw
* individual values for this column to <I>aRenderer</I>. Posts a
* bound property change notification with the name CELL_RENDERER_PROPERTY.
*
* @param aRenderer the new data cell renderer
* @see #getCellRenderer()
*/
public void setCellRenderer(TableCellRenderer aRenderer)
{
TableCellRenderer oldRenderer = cellRenderer;
cellRenderer = aRenderer;
// Post cell renderer changed event notification
if (changeSupport != null) {
changeSupport.firePropertyChange(CELL_RENDERER_PROPERTY,
oldRenderer, cellRenderer);
}
}
/**
* Returns the <B>TableCellRenderer</B> used by the <B>JTable</B> to draw
* values for this column. The <I>cellRenderer</I> of the column not
* only controls the visual look for the column, but is also used to
* interpret the value object supplied by the TableModel. The
* default <I>cellRenderer</I> is a <B>JCellRenderer</B>
* initialized with a <B>JLabel</B>.
*
* @return the <B>TableCellRenderer</B> used by the <B>JTable</B> to
* draw values for this column
* @see #setCellRenderer()
*/
public TableCellRenderer getCellRenderer()
{
return cellRenderer;
}
/**
* Sets the <B>TableCellEditor</B> used by <B>JTable</B> to draw individual
* values for this column to <I>anEditor</I>. A <B>null</B> editor
* means the column is not editable.
*
* @param anEditor the new data cell editor
* @see #getCellEditor()
*/
public void setCellEditor(TableCellEditor anEditor)
{
cellEditor = anEditor;
}
/**
* Returns the <B>TableCellEditor</B> used by the <B>JTable</B> to draw
* values for this column. The <I>cellEditor</I> of the column not
* only controls the visual look for the column, but is also used to
* interpret the value object supplied by the TableModel. The
* default <I>cellEditor</I> is null.
*
* @return the <B>TableCellEditor</B> used by the <B>JTable</B> to
* draw values for this column
* @see #setCellEditor()
*/
public TableCellEditor getCellEditor()
{
return cellEditor;
}
/**
* Sets this column's width to <I>newWidth</I>. If <I>newWidth</I>
* exceeds the minimum or maximum width, it's adjusted to the
* appropriate limiting value. Posts a bound property
* change notification with the name COLUMN_WIDTH_PROPERTY.
*
* @param newWidth The new width value
* @see #getWidth()
* @see #getMinWidth()
* @see #setMinWidth()
* @see #getMaxWidth()
* @see #setMaxWidth()
*/
public void setWidth(int newWidth)
{
int oldWidth = width;
// Do a quick check
if (width == newWidth)
return;
// Set the width, and check min & max
width = newWidth;
if (width < minWidth)
width = minWidth;
else if (width > maxWidth)
width = maxWidth;
// Post resize event notification
if (changeSupport != null) {
changeSupport.firePropertyChange(COLUMN_WIDTH_PROPERTY,
new Integer(oldWidth), new Integer(width));
}
}
/**
* Returns the width of the <B>TableColumn</B>. The default width is
* 75.
*
* @return the width of the <B>TableColumn</B>
* @see #setWidth()
* @see #getMinWidth()
* @see #setMinWidth()
* @see #getMaxWidth()
* @see #setMaxWidth()
*/
public int getWidth()
{
return width;
}
/**
* Sets the <B>TableColumn's</B> minimum width to <I>newMinWidth</I>,
* also adjusting the current width if it's less than this value.
*
* @param newMinWidth the new minimum width value
* @see #getWidth()
* @see #setWidth()
* @see #getMinWidth()
* @see #getMaxWidth()
* @see #setMaxWidth()
*/
public void setMinWidth(int newMinWidth)
{
minWidth = newMinWidth;
if (minWidth < 0)
minWidth = 0;
if (width < minWidth)
this.setWidth(minWidth);
}
/**
* Returns the minimum width for the <B>TableColumn</B>. The
* <B>TableColumn's</B> width can't be made less than this either
* by the user or programmatically. The default minWidth is 15.
*
* @return the minimum width for the <B>TableColumn</B>
* @see #getWidth()
* @see #setWidth()
* @see #setMinWidth()
* @see #getMaxWidth()
* @see #setMaxWidth()
*/
public int getMinWidth()
{
return minWidth;
}
/**
* Sets the <B>TableColumn's</B> maximum width to <I>newMaxWidth</I>,
* also adjusting the current width if it's greater than this value.
*
* @param newMaxWidth the new maximum width value
* @see #getWidth()
* @see #setWidth()
* @see #getMinWidth()
* @see #setMinWidth()
* @see #getMaxWidth()
*/
public void setMaxWidth(int newMaxWidth)
{
maxWidth = newMaxWidth;
if (maxWidth < 0)
maxWidth = 0;
else if (maxWidth < minWidth)
maxWidth = minWidth;
if (width > maxWidth)
this.setWidth(maxWidth);
}
/**
* Returns the maximum width for the <B>TableColumn</B>. The
* <B>TableColumn's</B> width can't be made larger than this
* either by the user or programmatically. The default maxWidth
* is 2000.
*
* @return the maximum width for the <B>TableColumn</B>.
* @see #getWidth()
* @see #setWidth()
* @see #getMinWidth()
* @see #setMinWidth()
* @see #setMaxWidth()
*/
public int getMaxWidth()
{
return maxWidth;
}
/**
* Sets whether the user can resize the receiver in its
* <B>JTableView</B>.
*
* @param flag true if the column isResizable
* @see #getResizable()
*/
public void setResizable(boolean flag)
{
isResizable = flag;
}
/**
* Returns true if the user is allowed to resize the <B>TableColumn</B>
* width, false otherwise. You can change the width programmatically
* regardless of this setting. The default is true.
*
* @return true if the user is allowed to resize the <B>TableColumn</B>
* width, false otherwise.
* @see #setResizable()
*/
public boolean getResizable()
{
return isResizable;
}
/**
* Resizes the <B>TableColumn</B> to fit the width of its header cell.
* If the maximum width is less than the width of the header, the
* maximum is increased to the header's width. Similarly, if the
* minimum width is greater than the width of the header, the minimum
* is reduced to the header's width.
*
* @see #setWidth()
* @see #setMinWidth()
* @see #setMaxWidth()
*/
public void sizeWidthToFit() {
// Get the preferred width of the header
Component comp;
comp = this.getHeaderRenderer().getTableCellRendererComponent(null,
getHeaderValue(), false, false, 0, 0);
int headerWidth = comp.getPreferredSize().width;
// Have to adjust the max or min before setting the width
if (headerWidth > this.getMaxWidth())
this.setMaxWidth(headerWidth);
if (headerWidth < this.getMinWidth())
this.setMinWidth(headerWidth);
// Set the width
this.setWidth(headerWidth);
}
public void disableResizedPosting() {
resizedPostingDisableCount++;
}
public void enableResizedPosting() {
resizedPostingDisableCount--;
}
//
// Property Change Support
//
/**
* Add a PropertyChangeListener to the listener list.
* The listener is registered for all properties.
* <p>
* A PropertyChangeEvent will get fired in response to an
* explicit setFont, setBackground, or SetForeground 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 PropertyChangeListener to be added
*/
public synchronized void addPropertyChangeListener(
PropertyChangeListener listener) {
if (changeSupport == null) {
changeSupport = new java.beans.PropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
/**
* Remove a PropertyChangeListener from the listener list.
* This removes a PropertyChangeListener that was registered
* for all properties.
*
* @param listener The PropertyChangeListener to be removed
*/
public synchronized void removePropertyChangeListener(
PropertyChangeListener listener) {
if (changeSupport != null) {
changeSupport.removePropertyChangeListener(listener);
}
}
//
// Protected Methods
//
protected TableCellRenderer createDefaultHeaderRenderer() {
DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JTableHeader header = table.getTableHeader();
if (isSelected) {
setBackground(table.getSelectionBackground());
setForeground(table.getSelectionForeground());
}
else {
setBackground(header.getBackground());
setForeground(header.getForeground());
}
setFont(header.getFont());
setText((value == null) ? "" : value.toString());
return this;
}
};
label.setHorizontalAlignment(JLabel.CENTER);
label.setBorder(BorderFactory.createRaisedBevelBorder());
return label;
}
} // End of class TableColumn