0N/A/*
6321N/A * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.swing.table;
0N/A
0N/Aimport sun.swing.table.DefaultTableCellHeaderRenderer;
0N/A
0N/Aimport java.util.*;
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/A
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.event.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport javax.accessibility.*;
0N/A
0N/Aimport java.beans.PropertyChangeListener;
0N/Aimport java.beans.Transient;
0N/A
0N/Aimport java.io.ObjectOutputStream;
0N/Aimport java.io.ObjectInputStream;
0N/Aimport java.io.IOException;
0N/A
0N/A
0N/A/**
0N/A * This is the object which manages the header of the <code>JTable</code>.
0N/A * <p>
0N/A * <strong>Warning:</strong>
0N/A * Serialized objects of this class will not be compatible with
0N/A * future Swing releases. The current serialization support is
0N/A * appropriate for short term storage or RMI between applications running
0N/A * the same version of Swing. As of 1.4, support for long term storage
0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup>
0N/A * has been added to the <code>java.beans</code> package.
6321N/A * Please see {@link java.beans.XMLEncoder}.
0N/A *
0N/A * @author Alan Chung
0N/A * @author Philip Milne
0N/A * @see javax.swing.JTable
0N/A */
0N/Apublic class JTableHeader extends JComponent implements TableColumnModelListener, Accessible
0N/A{
0N/A /**
0N/A * @see #getUIClassID
0N/A * @see #readObject
0N/A */
0N/A private static final String uiClassID = "TableHeaderUI";
0N/A
0N/A//
0N/A// Instance Variables
0N/A//
0N/A /**
0N/A * The table for which this object is the header;
0N/A * the default is <code>null</code>.
0N/A */
0N/A protected JTable table;
0N/A
0N/A /**
0N/A * The <code>TableColumnModel</code> of the table header.
0N/A */
0N/A protected TableColumnModel columnModel;
0N/A
0N/A /**
0N/A * If true, reordering of columns are allowed by the user;
0N/A * the default is true.
0N/A */
0N/A protected boolean reorderingAllowed;
0N/A
0N/A /**
0N/A * If true, resizing of columns are allowed by the user;
0N/A * the default is true.
0N/A */
0N/A protected boolean resizingAllowed;
0N/A
0N/A /**
0N/A * Obsolete as of Java 2 platform v1.3. Real time repaints, in response
0N/A * to column dragging or resizing, are now unconditional.
0N/A */
0N/A /*
0N/A * If this flag is true, then the header will repaint the table as
0N/A * a column is dragged or resized; the default is true.
0N/A */
0N/A protected boolean updateTableInRealTime;
0N/A
0N/A /** The index of the column being resized. <code>null</code> if not resizing. */
0N/A transient protected TableColumn resizingColumn;
0N/A
0N/A /** The index of the column being dragged. <code>null</code> if not dragging. */
0N/A transient protected TableColumn draggedColumn;
0N/A
0N/A /** The distance from its original position the column has been dragged. */
0N/A transient protected int draggedDistance;
0N/A
0N/A /**
0N/A * The default renderer to be used when a <code>TableColumn</code>
0N/A * does not define a <code>headerRenderer</code>.
0N/A */
0N/A private TableCellRenderer defaultRenderer;
0N/A
0N/A//
0N/A// Constructors
0N/A//
0N/A
0N/A /**
0N/A * Constructs a <code>JTableHeader</code> with a default
0N/A * <code>TableColumnModel</code>.
0N/A *
0N/A * @see #createDefaultColumnModel
0N/A */
0N/A public JTableHeader() {
0N/A this(null);
0N/A }
0N/A
0N/A /**
0N/A * Constructs a <code>JTableHeader</code> which is initialized with
0N/A * <code>cm</code> as the column model. If <code>cm</code> is
0N/A * <code>null</code> this method will initialize the table header
0N/A * with a default <code>TableColumnModel</code>.
0N/A *
0N/A * @param cm the column model for the table
0N/A * @see #createDefaultColumnModel
0N/A */
0N/A public JTableHeader(TableColumnModel cm) {
0N/A super();
0N/A
0N/A //setFocusable(false); // for strict win/mac compatibility mode,
0N/A // this method should be invoked
0N/A
0N/A if (cm == null)
0N/A cm = createDefaultColumnModel();
0N/A setColumnModel(cm);
0N/A
0N/A // Initialize local ivars
0N/A initializeLocalVars();
0N/A
0N/A // Get UI going
0N/A updateUI();
0N/A }
0N/A
0N/A//
0N/A// Local behavior attributes
0N/A//
0N/A
0N/A /**
0N/A * Sets the table associated with this header.
0N/A * @param table the new table
0N/A * @beaninfo
0N/A * bound: true
0N/A * description: The table associated with this header.
0N/A */
0N/A public void setTable(JTable table) {
0N/A JTable old = this.table;
0N/A this.table = table;
0N/A firePropertyChange("table", old, table);
0N/A }
0N/A
0N/A /**
0N/A * Returns the table associated with this header.
0N/A * @return the <code>table</code> property
0N/A */
0N/A public JTable getTable() {
0N/A return table;
0N/A }
0N/A
0N/A /**
0N/A * Sets whether the user can drag column headers to reorder columns.
0N/A *
0N/A * @param reorderingAllowed true if the table view should allow
0N/A * reordering; otherwise false
0N/A * @see #getReorderingAllowed
0N/A * @beaninfo
0N/A * bound: true
0N/A * description: Whether the user can drag column headers to reorder columns.
0N/A */
0N/A public void setReorderingAllowed(boolean reorderingAllowed) {
0N/A boolean old = this.reorderingAllowed;
0N/A this.reorderingAllowed = reorderingAllowed;
0N/A firePropertyChange("reorderingAllowed", old, reorderingAllowed);
0N/A }
0N/A
0N/A /**
0N/A * Returns true if the user is allowed to rearrange columns by
0N/A * dragging their headers, false otherwise. The default is true. You can
0N/A * rearrange columns programmatically regardless of this setting.
0N/A *
0N/A * @return the <code>reorderingAllowed</code> property
0N/A * @see #setReorderingAllowed
0N/A */
0N/A public boolean getReorderingAllowed() {
0N/A return reorderingAllowed;
0N/A }
0N/A
0N/A /**
0N/A * Sets whether the user can resize columns by dragging between headers.
0N/A *
0N/A * @param resizingAllowed true if table view should allow
0N/A * resizing
0N/A * @see #getResizingAllowed
0N/A * @beaninfo
0N/A * bound: true
0N/A * description: Whether the user can resize columns by dragging between headers.
0N/A */
0N/A public void setResizingAllowed(boolean resizingAllowed) {
0N/A boolean old = this.resizingAllowed;
0N/A this.resizingAllowed = resizingAllowed;
0N/A firePropertyChange("resizingAllowed", old, resizingAllowed);
0N/A }
0N/A
0N/A /**
0N/A * Returns true if the user is allowed to resize columns by dragging
0N/A * between their headers, false otherwise. The default is true. You can
0N/A * resize columns programmatically regardless of this setting.
0N/A *
0N/A * @return the <code>resizingAllowed</code> property
0N/A * @see #setResizingAllowed
0N/A */
0N/A public boolean getResizingAllowed() {
0N/A return resizingAllowed;
0N/A }
0N/A
0N/A /**
0N/A * Returns the the dragged column, if and only if, a drag is in
0N/A * process, otherwise returns <code>null</code>.
0N/A *
0N/A * @return the dragged column, if a drag is in
0N/A * process, otherwise returns <code>null</code>
0N/A * @see #getDraggedDistance
0N/A */
0N/A public TableColumn getDraggedColumn() {
0N/A return draggedColumn;
0N/A }
0N/A
0N/A /**
0N/A * Returns the column's horizontal distance from its original
0N/A * position, if and only if, a drag is in process. Otherwise, the
0N/A * the return value is meaningless.
0N/A *
0N/A * @return the column's horizontal distance from its original
0N/A * position, if a drag is in process, otherwise the return
0N/A * value is meaningless
0N/A * @see #getDraggedColumn
0N/A */
0N/A public int getDraggedDistance() {
0N/A return draggedDistance;
0N/A }
0N/A
0N/A /**
0N/A * Returns the resizing column. If no column is being
0N/A * resized this method returns <code>null</code>.
0N/A *
0N/A * @return the resizing column, if a resize is in process, otherwise
0N/A * returns <code>null</code>
0N/A */
0N/A public TableColumn getResizingColumn() {
0N/A return resizingColumn;
0N/A }
0N/A
0N/A /**
0N/A * Obsolete as of Java 2 platform v1.3. Real time repaints, in response to
0N/A * column dragging or resizing, are now unconditional.
0N/A */
0N/A /*
0N/A * Sets whether the body of the table updates in real time when
0N/A * a column is resized or dragged.
0N/A *
0N/A * @param flag true if tableView should update
0N/A * the body of the table in real time
0N/A * @see #getUpdateTableInRealTime
0N/A */
0N/A public void setUpdateTableInRealTime(boolean flag) {
0N/A updateTableInRealTime = flag;
0N/A }
0N/A
0N/A /**
0N/A * Obsolete as of Java 2 platform v1.3. Real time repaints, in response to
0N/A * column dragging or resizing, are now unconditional.
0N/A */
0N/A /*
0N/A * Returns true if the body of the table view updates in real
0N/A * time when a column is resized or dragged. User can set this flag to
0N/A * false to speed up the table's response to user resize or drag actions.
0N/A * The default is true.
0N/A *
0N/A * @return true if the table updates in real time
0N/A * @see #setUpdateTableInRealTime
0N/A */
0N/A public boolean getUpdateTableInRealTime() {
0N/A return updateTableInRealTime;
0N/A }
0N/A
0N/A /**
0N/A * Sets the default renderer to be used when no <code>headerRenderer</code>
0N/A * is defined by a <code>TableColumn</code>.
0N/A * @param defaultRenderer the default renderer
0N/A * @since 1.3
0N/A */
0N/A public void setDefaultRenderer(TableCellRenderer defaultRenderer) {
0N/A this.defaultRenderer = defaultRenderer;
0N/A }
0N/A
0N/A /**
0N/A * Returns the default renderer used when no <code>headerRenderer</code>
0N/A * is defined by a <code>TableColumn</code>.
0N/A * @return the default renderer
0N/A * @since 1.3
0N/A */
0N/A @Transient
0N/A public TableCellRenderer getDefaultRenderer() {
0N/A return defaultRenderer;
0N/A }
0N/A
0N/A /**
0N/A * Returns the index of the column that <code>point</code> lies in, or -1 if it
0N/A * lies out of bounds.
0N/A *
0N/A * @return the index of the column that <code>point</code> lies in, or -1 if it
0N/A * lies out of bounds
0N/A */
0N/A public int columnAtPoint(Point point) {
0N/A int x = point.x;
0N/A if (!getComponentOrientation().isLeftToRight()) {
0N/A x = getWidthInRightToLeft() - x - 1;
0N/A }
0N/A return getColumnModel().getColumnIndexAtX(x);
0N/A }
0N/A
0N/A /**
0N/A * Returns the rectangle containing the header tile at <code>column</code>.
0N/A * When the <code>column</code> parameter is out of bounds this method uses the
0N/A * same conventions as the <code>JTable</code> method <code>getCellRect</code>.
0N/A *
0N/A * @return the rectangle containing the header tile at <code>column</code>
0N/A * @see JTable#getCellRect
0N/A */
0N/A public Rectangle getHeaderRect(int column) {
0N/A Rectangle r = new Rectangle();
0N/A TableColumnModel cm = getColumnModel();
0N/A
0N/A r.height = getHeight();
0N/A
0N/A if (column < 0) {
0N/A // x = width = 0;
0N/A if( !getComponentOrientation().isLeftToRight() ) {
0N/A r.x = getWidthInRightToLeft();
0N/A }
0N/A }
0N/A else if (column >= cm.getColumnCount()) {
0N/A if( getComponentOrientation().isLeftToRight() ) {
0N/A r.x = getWidth();
0N/A }
0N/A }
0N/A else {
0N/A for(int i = 0; i < column; i++) {
0N/A r.x += cm.getColumn(i).getWidth();
0N/A }
0N/A if( !getComponentOrientation().isLeftToRight() ) {
0N/A r.x = getWidthInRightToLeft() - r.x - cm.getColumn(column).getWidth();
0N/A }
0N/A
0N/A r.width = cm.getColumn(column).getWidth();
0N/A }
0N/A return r;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Allows the renderer's tips to be used if there is text set.
0N/A * @param event the location of the event identifies the proper
0N/A * renderer and, therefore, the proper tip
0N/A * @return the tool tip for this component
0N/A */
0N/A public String getToolTipText(MouseEvent event) {
0N/A String tip = null;
0N/A Point p = event.getPoint();
0N/A int column;
0N/A
0N/A // Locate the renderer under the event location
0N/A if ((column = columnAtPoint(p)) != -1) {
0N/A TableColumn aColumn = columnModel.getColumn(column);
0N/A TableCellRenderer renderer = aColumn.getHeaderRenderer();
6321N/A if (renderer == null) {
0N/A renderer = defaultRenderer;
6321N/A }
6321N/A Component component = renderer.getTableCellRendererComponent(
6321N/A getTable(), aColumn.getHeaderValue(), false, false,
0N/A -1, column);
0N/A
0N/A // Now have to see if the component is a JComponent before
0N/A // getting the tip
0N/A if (component instanceof JComponent) {
0N/A // Convert the event to the renderer's coordinate system
0N/A MouseEvent newEvent;
0N/A Rectangle cellRect = getHeaderRect(column);
0N/A
0N/A p.translate(-cellRect.x, -cellRect.y);
0N/A newEvent = new MouseEvent(component, event.getID(),
0N/A event.getWhen(), event.getModifiers(),
0N/A p.x, p.y, event.getXOnScreen(), event.getYOnScreen(),
0N/A event.getClickCount(),
0N/A event.isPopupTrigger(), MouseEvent.NOBUTTON);
0N/A
0N/A tip = ((JComponent)component).getToolTipText(newEvent);
0N/A }
}
// No tip from the renderer get our own tip
if (tip == null)
tip = getToolTipText();
return tip;
}
//
// Managing TableHeaderUI
//
/**
* Returns the look and feel (L&F) object that renders this component.
*
* @return the <code>TableHeaderUI</code> object that renders this component
*/
public TableHeaderUI getUI() {
return (TableHeaderUI)ui;
}
/**
* Sets the look and feel (L&F) object that renders this component.
*
* @param ui the <code>TableHeaderUI</code> L&F object
* @see UIDefaults#getUI
*/
public void setUI(TableHeaderUI ui){
if (this.ui != ui) {
super.setUI(ui);
repaint();
}
}
/**
* Notification from the <code>UIManager</code> that the look and feel
* (L&F) has changed.
* Replaces the current UI object with the latest version from the
* <code>UIManager</code>.
*
* @see JComponent#updateUI
*/
public void updateUI(){
setUI((TableHeaderUI)UIManager.getUI(this));
TableCellRenderer renderer = getDefaultRenderer();
if (renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
}
/**
* Returns the suffix used to construct the name of the look and feel
* (L&F) class used to render this component.
* @return the string "TableHeaderUI"
*
* @return "TableHeaderUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return uiClassID;
}
//
// Managing models
//
/**
* Sets the column model for this table to <code>newModel</code> and registers
* for listener notifications from the new column model.
*
* @param columnModel the new data source for this table
* @exception IllegalArgumentException
* if <code>newModel</code> is <code>null</code>
* @see #getColumnModel
* @beaninfo
* bound: true
* description: The object governing the way columns appear in the view.
*/
public void setColumnModel(TableColumnModel columnModel) {
if (columnModel == null) {
throw new IllegalArgumentException("Cannot set a null ColumnModel");
}
TableColumnModel old = this.columnModel;
if (columnModel != old) {
if (old != null) {
old.removeColumnModelListener(this);
}
this.columnModel = columnModel;
columnModel.addColumnModelListener(this);
firePropertyChange("columnModel", old, columnModel);
resizeAndRepaint();
}
}
/**
* Returns the <code>TableColumnModel</code> that contains all column information
* of this table header.
*
* @return the <code>columnModel</code> property
* @see #setColumnModel
*/
public TableColumnModel getColumnModel() {
return columnModel;
}
//
// Implementing TableColumnModelListener interface
//
/**
* Invoked when a column is added to the table column model.
* <p>
* Application code will not use these methods explicitly, they
* are used internally by <code>JTable</code>.
*
* @param e the event received
* @see TableColumnModelListener
*/
public void columnAdded(TableColumnModelEvent e) { resizeAndRepaint(); }
/**
* Invoked when a column is removed from the table column model.
* <p>
* Application code will not use these methods explicitly, they
* are used internally by <code>JTable</code>.
*
* @param e the event received
* @see TableColumnModelListener
*/
public void columnRemoved(TableColumnModelEvent e) { resizeAndRepaint(); }
/**
* Invoked when a column is repositioned.
* <p>
* Application code will not use these methods explicitly, they
* are used internally by <code>JTable</code>.
*
* @param e the event received
* @see TableColumnModelListener
*/
public void columnMoved(TableColumnModelEvent e) { repaint(); }
/**
* Invoked when a column is moved due to a margin change.
* <p>
* Application code will not use these methods explicitly, they
* are used internally by <code>JTable</code>.
*
* @param e the event received
* @see TableColumnModelListener
*/
public void columnMarginChanged(ChangeEvent e) { resizeAndRepaint(); }
// --Redrawing the header is slow in cell selection mode.
// --Since header selection is ugly and it is always clear from the
// --view which columns are selected, don't redraw the header.
/**
* Invoked when the selection model of the <code>TableColumnModel</code>
* is changed. This method currently has no effect (the header is not
* redrawn).
* <p>
* Application code will not use these methods explicitly, they
* are used internally by <code>JTable</code>.
*
* @param e the event received
* @see TableColumnModelListener
*/
public void columnSelectionChanged(ListSelectionEvent e) { } // repaint(); }
//
// Package Methods
//
/**
* Returns the default column model object which is
* a <code>DefaultTableColumnModel</code>. A subclass can override this
* method to return a different column model object
*
* @return the default column model object
*/
protected TableColumnModel createDefaultColumnModel() {
return new DefaultTableColumnModel();
}
/**
* Returns a default renderer to be used when no header renderer
* is defined by a <code>TableColumn</code>.
*
* @return the default table column renderer
* @since 1.3
*/
protected TableCellRenderer createDefaultRenderer() {
return new DefaultTableCellHeaderRenderer();
}
/**
* Initializes the local variables and properties with default values.
* Used by the constructor methods.
*/
protected void initializeLocalVars() {
setOpaque(true);
table = null;
reorderingAllowed = true;
resizingAllowed = true;
draggedColumn = null;
draggedDistance = 0;
resizingColumn = null;
updateTableInRealTime = true;
// I'm registered to do tool tips so we can draw tips for the
// renderers
ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.registerComponent(this);
setDefaultRenderer(createDefaultRenderer());
}
/**
* Sizes the header and marks it as needing display. Equivalent
* to <code>revalidate</code> followed by <code>repaint</code>.
*/
public void resizeAndRepaint() {
revalidate();
repaint();
}
/**
* Sets the header's <code>draggedColumn</code> to <code>aColumn</code>.
* <p>
* Application code will not use this method explicitly, it is used
* internally by the column dragging mechanism.
*
* @param aColumn the column being dragged, or <code>null</code> if
* no column is being dragged
*/
public void setDraggedColumn(TableColumn aColumn) {
draggedColumn = aColumn;
}
/**
* Sets the header's <code>draggedDistance</code> to <code>distance</code>.
* @param distance the distance dragged
*/
public void setDraggedDistance(int distance) {
draggedDistance = distance;
}
/**
* Sets the header's <code>resizingColumn</code> to <code>aColumn</code>.
* <p>
* Application code will not use this method explicitly, it
* is used internally by the column sizing mechanism.
*
* @param aColumn the column being resized, or <code>null</code> if
* no column is being resized
*/
public void setResizingColumn(TableColumn aColumn) {
resizingColumn = aColumn;
}
/**
* See <code>readObject</code> and <code>writeObject</code> in
* <code>JComponent</code> for more
* information about serialization in Swing.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if ((ui != null) && (getUIClassID().equals(uiClassID))) {
ui.installUI(this);
}
}
private int getWidthInRightToLeft() {
if ((table != null) &&
(table.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF)) {
return table.getWidth();
}
return super.getWidth();
}
/**
* Returns a string representation of this <code>JTableHeader</code>. This method
* is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not
* be <code>null</code>.
* <P>
* Overriding <code>paramString</code> to provide information about the
* specific new aspects of the JFC components.
*
* @return a string representation of this <code>JTableHeader</code>
*/
protected String paramString() {
String reorderingAllowedString = (reorderingAllowed ?
"true" : "false");
String resizingAllowedString = (resizingAllowed ?
"true" : "false");
String updateTableInRealTimeString = (updateTableInRealTime ?
"true" : "false");
return super.paramString() +
",draggedDistance=" + draggedDistance +
",reorderingAllowed=" + reorderingAllowedString +
",resizingAllowed=" + resizingAllowedString +
",updateTableInRealTime=" + updateTableInRealTimeString;
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this JTableHeader.
* For JTableHeaders, the AccessibleContext takes the form of an
* AccessibleJTableHeader.
* A new AccessibleJTableHeader instance is created if necessary.
*
* @return an AccessibleJTableHeader that serves as the
* AccessibleContext of this JTableHeader
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJTableHeader();
}
return accessibleContext;
}
//
// *** should also implement AccessibleSelection?
// *** and what's up with keyboard navigation/manipulation?
//
/**
* This class implements accessibility support for the
* <code>JTableHeader</code> class. It provides an implementation of the
* Java Accessibility API appropriate to table header user-interface
* elements.
* <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<sup><font size="-2">TM</font></sup>
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*/
protected class AccessibleJTableHeader extends AccessibleJComponent {
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.PANEL;
}
/**
* Returns the Accessible child, if one exists, contained at the local
* coordinate Point.
*
* @param p The point defining the top-left corner of the Accessible,
* given in the coordinate space of the object's parent.
* @return the Accessible, if it exists, at the specified location;
* else null
*/
public Accessible getAccessibleAt(Point p) {
int column;
// Locate the renderer under the Point
if ((column = JTableHeader.this.columnAtPoint(p)) != -1) {
TableColumn aColumn = JTableHeader.this.columnModel.getColumn(column);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
if (defaultRenderer != null) {
renderer = defaultRenderer;
} else {
return null;
}
}
Component component = renderer.getTableCellRendererComponent(
JTableHeader.this.getTable(),
aColumn.getHeaderValue(), false, false,
-1, column);
return new AccessibleJTableHeaderEntry(column, JTableHeader.this, JTableHeader.this.table);
} else {
return null;
}
}
/**
* Returns the number of accessible children in the object. If all
* of the children of this object implement Accessible, than this
* method should return the number of children of this object.
*
* @return the number of accessible children in the object.
*/
public int getAccessibleChildrenCount() {
return JTableHeader.this.columnModel.getColumnCount();
}
/**
* Return the nth Accessible child of the object.
*
* @param i zero-based index of child
* @return the nth Accessible child of the object
*/
public Accessible getAccessibleChild(int i) {
if (i < 0 || i >= getAccessibleChildrenCount()) {
return null;
} else {
TableColumn aColumn = JTableHeader.this.columnModel.getColumn(i)
;
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
if (defaultRenderer != null) {
renderer = defaultRenderer;
} else {
return null;
}
}
Component component = renderer.getTableCellRendererComponent(
JTableHeader.this.getTable(),
aColumn.getHeaderValue(), false, false,
-1, i);
return new AccessibleJTableHeaderEntry(i, JTableHeader.this, JTableHeader.this.table);
}
}
/**
* This class provides an implementation of the Java Accessibility
* API appropropriate for JTableHeader entries.
*/
protected class AccessibleJTableHeaderEntry extends AccessibleContext
implements Accessible, AccessibleComponent {
private JTableHeader parent;
private int column;
private JTable table;
/**
* Constructs an AccessiblJTableHeaaderEntry
* @since 1.4
*/
public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t) {
parent = p;
column = c;
table = t;
this.setAccessibleParent(parent);
}
/**
* Get the AccessibleContext associated with this object.
* In the implementation of the Java Accessibility API
* for this class, returns this object, which serves as
* its own AccessibleContext.
*
* @return this object
*/
public AccessibleContext getAccessibleContext() {
return this;
}
private AccessibleContext getCurrentAccessibleContext() {
TableColumnModel tcm = table.getColumnModel();
if (tcm != null) {
// Fixes 4772355 - ArrayOutOfBoundsException in
// JTableHeader
if (column < 0 || column >= tcm.getColumnCount()) {
return null;
}
TableColumn aColumn = tcm.getColumn(column);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
if (defaultRenderer != null) {
renderer = defaultRenderer;
} else {
return null;
}
}
Component c = renderer.getTableCellRendererComponent(
JTableHeader.this.getTable(),
aColumn.getHeaderValue(), false, false,
-1, column);
if (c instanceof Accessible) {
return ((Accessible) c).getAccessibleContext();
}
}
return null;
}
private Component getCurrentComponent() {
TableColumnModel tcm = table.getColumnModel();
if (tcm != null) {
// Fixes 4772355 - ArrayOutOfBoundsException in
// JTableHeader
if (column < 0 || column >= tcm.getColumnCount()) {
return null;
}
TableColumn aColumn = tcm.getColumn(column);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
if (defaultRenderer != null) {
renderer = defaultRenderer;
} else {
return null;
}
}
return renderer.getTableCellRendererComponent(
JTableHeader.this.getTable(),
aColumn.getHeaderValue(), false, false,
-1, column);
} else {
return null;
}
}
// AccessibleContext methods
public String getAccessibleName() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
String name = ac.getAccessibleName();
if ((name != null) && (name != "")) {
// return the cell renderer's AccessibleName
return name;
}
}
if ((accessibleName != null) && (accessibleName != "")) {
return accessibleName;
} else {
// fall back to the client property
String name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
if (name != null) {
return name;
} else {
return table.getColumnName(column);
}
}
}
public void setAccessibleName(String s) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.setAccessibleName(s);
} else {
super.setAccessibleName(s);
}
}
//
// *** should check toolTip text for desc. (needs MouseEvent)
//
public String getAccessibleDescription() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleDescription();
} else {
return super.getAccessibleDescription();
}
}
public void setAccessibleDescription(String s) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.setAccessibleDescription(s);
} else {
super.setAccessibleDescription(s);
}
}
public AccessibleRole getAccessibleRole() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleRole();
} else {
return AccessibleRole.COLUMN_HEADER;
}
}
public AccessibleStateSet getAccessibleStateSet() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
AccessibleStateSet states = ac.getAccessibleStateSet();
if (isShowing()) {
states.add(AccessibleState.SHOWING);
}
return states;
} else {
return new AccessibleStateSet(); // must be non null?
}
}
public int getAccessibleIndexInParent() {
return column;
}
public int getAccessibleChildrenCount() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleChildrenCount();
} else {
return 0;
}
}
public Accessible getAccessibleChild(int i) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
Accessible accessibleChild = ac.getAccessibleChild(i);
ac.setAccessibleParent(this);
return accessibleChild;
} else {
return null;
}
}
public Locale getLocale() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getLocale();
} else {
return null;
}
}
public void addPropertyChangeListener(PropertyChangeListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.addPropertyChangeListener(l);
} else {
super.addPropertyChangeListener(l);
}
}
public void removePropertyChangeListener(PropertyChangeListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.removePropertyChangeListener(l);
} else {
super.removePropertyChangeListener(l);
}
}
public AccessibleAction getAccessibleAction() {
return getCurrentAccessibleContext().getAccessibleAction();
}
/**
* Get the AccessibleComponent associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleComponent interface on behalf of itself.
*
* @return this object
*/
public AccessibleComponent getAccessibleComponent() {
return this; // to override getBounds()
}
public AccessibleSelection getAccessibleSelection() {
return getCurrentAccessibleContext().getAccessibleSelection();
}
public AccessibleText getAccessibleText() {
return getCurrentAccessibleContext().getAccessibleText();
}
public AccessibleValue getAccessibleValue() {
return getCurrentAccessibleContext().getAccessibleValue();
}
// AccessibleComponent methods
public Color getBackground() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getBackground();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getBackground();
} else {
return null;
}
}
}
public void setBackground(Color c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setBackground(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setBackground(c);
}
}
}
public Color getForeground() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getForeground();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getForeground();
} else {
return null;
}
}
}
public void setForeground(Color c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setForeground(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setForeground(c);
}
}
}
public Cursor getCursor() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getCursor();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getCursor();
} else {
Accessible ap = getAccessibleParent();
if (ap instanceof AccessibleComponent) {
return ((AccessibleComponent) ap).getCursor();
} else {
return null;
}
}
}
}
public void setCursor(Cursor c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setCursor(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setCursor(c);
}
}
}
public Font getFont() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getFont();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getFont();
} else {
return null;
}
}
}
public void setFont(Font f) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setFont(f);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setFont(f);
}
}
}
public FontMetrics getFontMetrics(Font f) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getFontMetrics(f);
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getFontMetrics(f);
} else {
return null;
}
}
}
public boolean isEnabled() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).isEnabled();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.isEnabled();
} else {
return false;
}
}
}
public void setEnabled(boolean b) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setEnabled(b);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setEnabled(b);
}
}
}
public boolean isVisible() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).isVisible();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.isVisible();
} else {
return false;
}
}
}
public void setVisible(boolean b) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setVisible(b);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setVisible(b);
}
}
}
public boolean isShowing() {
if (isVisible() && JTableHeader.this.isShowing()) {
return true;
} else {
return false;
}
}
public boolean contains(Point p) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
Rectangle r = ((AccessibleComponent) ac).getBounds();
return r.contains(p);
} else {
Component c = getCurrentComponent();
if (c != null) {
Rectangle r = c.getBounds();
return r.contains(p);
} else {
return getBounds().contains(p);
}
}
}
public Point getLocationOnScreen() {
if (parent != null) {
Point parentLocation = parent.getLocationOnScreen();
Point componentLocation = getLocation();
componentLocation.translate(parentLocation.x, parentLocation.y);
return componentLocation;
} else {
return null;
}
}
public Point getLocation() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
Rectangle r = ((AccessibleComponent) ac).getBounds();
return r.getLocation();
} else {
Component c = getCurrentComponent();
if (c != null) {
Rectangle r = c.getBounds();
return r.getLocation();
} else {
return getBounds().getLocation();
}
}
}
public void setLocation(Point p) {
// if ((parent != null) && (parent.contains(p))) {
// ensureIndexIsVisible(indexInParent);
// }
}
public Rectangle getBounds() {
Rectangle r = table.getCellRect(-1, column, false);
r.y = 0;
return r;
// AccessibleContext ac = getCurrentAccessibleContext();
// if (ac instanceof AccessibleComponent) {
// return ((AccessibleComponent) ac).getBounds();
// } else {
// Component c = getCurrentComponent();
// if (c != null) {
// return c.getBounds();
// } else {
// Rectangle r = table.getCellRect(-1, column, false);
// r.y = 0;
// return r;
// }
// }
}
public void setBounds(Rectangle r) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setBounds(r);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setBounds(r);
}
}
}
public Dimension getSize() {
return getBounds().getSize();
// AccessibleContext ac = getCurrentAccessibleContext();
// if (ac instanceof AccessibleComponent) {
// Rectangle r = ((AccessibleComponent) ac).getBounds();
// return r.getSize();
// } else {
// Component c = getCurrentComponent();
// if (c != null) {
// Rectangle r = c.getBounds();
// return r.getSize();
// } else {
// return getBounds().getSize();
// }
// }
}
public void setSize (Dimension d) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setSize(d);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setSize(d);
}
}
}
public Accessible getAccessibleAt(Point p) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getAccessibleAt(p);
} else {
return null;
}
}
public boolean isFocusTraversable() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).isFocusTraversable();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.isFocusTraversable();
} else {
return false;
}
}
}
public void requestFocus() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).requestFocus();
} else {
Component c = getCurrentComponent();
if (c != null) {
c.requestFocus();
}
}
}
public void addFocusListener(FocusListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).addFocusListener(l);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.addFocusListener(l);
}
}
}
public void removeFocusListener(FocusListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).removeFocusListener(l);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.removeFocusListener(l);
}
}
}
} // inner class AccessibleJTableHeaderElement
} // inner class AccessibleJTableHeader
} // End of Class JTableHeader