/*
 * Copyright (c) 1997, 2008, 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 sun.swing.table.DefaultTableCellHeaderRenderer;

import java.util.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.accessibility.*;

import java.beans.PropertyChangeListener;
import java.beans.Transient;

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;


/**
 * This is the object which manages the header of the <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<sup><font size="-2">TM</font></sup>
 * 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.JTable
 */
public class JTableHeader extends JComponent implements TableColumnModelListener, Accessible
{
    /**
     * @see #getUIClassID
     * @see #readObject
     */
    private static final String uiClassID = "TableHeaderUI";

//
// Instance Variables
//
    /**
     * The table for which this object is the header;
     * the default is <code>null</code>.
     */
    protected JTable table;

    /**
     * The <code>TableColumnModel</code> of the table header.
     */
    protected TableColumnModel  columnModel;

    /**
     * If true, reordering of columns are allowed by the user;
     * the default is true.
     */
    protected boolean   reorderingAllowed;

    /**
     * If true, resizing of columns are allowed by the user;
     * the default is true.
     */
    protected boolean   resizingAllowed;

    /**
     * Obsolete as of Java 2 platform v1.3.  Real time repaints, in response
     * to column dragging or resizing, are now unconditional.
     */
    /*
     * If this flag is true, then the header will repaint the table as
     * a column is dragged or resized; the default is true.
     */
    protected boolean   updateTableInRealTime;

    /** The index of the column being resized. <code>null</code> if not resizing. */
    transient protected TableColumn     resizingColumn;

    /** The index of the column being dragged. <code>null</code> if not dragging. */
    transient protected TableColumn     draggedColumn;

    /** The distance from its original position the column has been dragged. */
    transient protected int     draggedDistance;

    /**
      *  The default renderer to be used when a <code>TableColumn</code>
      *  does not define a <code>headerRenderer</code>.
      */
    private TableCellRenderer defaultRenderer;

//
// Constructors
//

    /**
     *  Constructs a <code>JTableHeader</code> with a default
     *  <code>TableColumnModel</code>.
     *
     * @see #createDefaultColumnModel
     */
    public JTableHeader() {
        this(null);
    }

    /**
     *  Constructs a <code>JTableHeader</code> which is initialized with
     *  <code>cm</code> as the column model.  If <code>cm</code> is
     *  <code>null</code> this method will initialize the table header
     *  with a default <code>TableColumnModel</code>.
     *
     * @param cm        the column model for the table
     * @see #createDefaultColumnModel
     */
    public JTableHeader(TableColumnModel cm) {
        super();

        //setFocusable(false); // for strict win/mac compatibility mode,
                               // this method should be invoked

        if (cm == null)
            cm = createDefaultColumnModel();
        setColumnModel(cm);

        // Initialize local ivars
        initializeLocalVars();

        // Get UI going
        updateUI();
    }

//
// Local behavior attributes
//

    /**
     *  Sets the table associated with this header.
     *  @param  table   the new table
     *  @beaninfo
     *   bound: true
     *   description: The table associated with this header.
     */
    public void setTable(JTable table) {
        JTable old = this.table;
        this.table = table;
        firePropertyChange("table", old, table);
    }

    /**
      *  Returns the table associated with this header.
      *  @return  the <code>table</code> property
      */
    public JTable getTable() {
        return table;
    }

    /**
     *  Sets whether the user can drag column headers to reorder columns.
     *
     * @param   reorderingAllowed       true if the table view should allow
     *                                  reordering; otherwise false
     * @see     #getReorderingAllowed
     * @beaninfo
     *  bound: true
     *  description: Whether the user can drag column headers to reorder columns.
     */
    public void setReorderingAllowed(boolean reorderingAllowed) {
        boolean old = this.reorderingAllowed;
        this.reorderingAllowed = reorderingAllowed;
        firePropertyChange("reorderingAllowed", old, reorderingAllowed);
    }

    /**
     * Returns true if the user is allowed to rearrange columns by
     * dragging their headers, false otherwise. The default is true. You can
     * rearrange columns programmatically regardless of this setting.
     *
     * @return  the <code>reorderingAllowed</code> property
     * @see     #setReorderingAllowed
     */
    public boolean getReorderingAllowed() {
        return reorderingAllowed;
    }

    /**
     *  Sets whether the user can resize columns by dragging between headers.
     *
     * @param   resizingAllowed         true if table view should allow
     *                                  resizing
     * @see     #getResizingAllowed
     * @beaninfo
     *  bound: true
     *  description: Whether the user can resize columns by dragging between headers.
     */
    public void setResizingAllowed(boolean resizingAllowed) {
        boolean old = this.resizingAllowed;
        this.resizingAllowed = resizingAllowed;
        firePropertyChange("resizingAllowed", old, resizingAllowed);
    }

    /**
     * Returns true if the user is allowed to resize columns by dragging
     * between their headers, false otherwise. The default is true. You can
     * resize columns programmatically regardless of this setting.
     *
     * @return  the <code>resizingAllowed</code> property
     * @see     #setResizingAllowed
     */
    public boolean getResizingAllowed() {
        return resizingAllowed;
    }

    /**
     * Returns the the dragged column, if and only if, a drag is in
     * process, otherwise returns <code>null</code>.
     *
     * @return  the dragged column, if a drag is in
     *          process, otherwise returns <code>null</code>
     * @see     #getDraggedDistance
     */
    public TableColumn getDraggedColumn() {
        return draggedColumn;
    }

    /**
     * Returns the column's horizontal distance from its original
     * position, if and only if, a drag is in process. Otherwise, the
     * the return value is meaningless.
     *
     * @return  the column's horizontal distance from its original
     *          position, if a drag is in process, otherwise the return
     *          value is meaningless
     * @see     #getDraggedColumn
     */
    public int getDraggedDistance() {
        return draggedDistance;
    }

    /**
     * Returns the resizing column.  If no column is being
     * resized this method returns <code>null</code>.
     *
     * @return  the resizing column, if a resize is in process, otherwise
     *          returns <code>null</code>
     */
    public TableColumn getResizingColumn() {
        return resizingColumn;
    }

    /**
     * Obsolete as of Java 2 platform v1.3.  Real time repaints, in response to
     * column dragging or resizing, are now unconditional.
     */
    /*
     *  Sets whether the body of the table updates in real time when
     *  a column is resized or dragged.
     *
     * @param   flag                    true if tableView should update
     *                                  the body of the table in real time
     * @see #getUpdateTableInRealTime
     */
    public void setUpdateTableInRealTime(boolean flag) {
        updateTableInRealTime = flag;
    }

    /**
     * Obsolete as of Java 2 platform v1.3.  Real time repaints, in response to
     * column dragging or resizing, are now unconditional.
     */
    /*
     * Returns true if the body of the table view updates in real
     * time when a column is resized or dragged.  User can set this flag to
     * false to speed up the table's response to user resize or drag actions.
     * The default is true.
     *
     * @return  true if the table updates in real time
     * @see #setUpdateTableInRealTime
     */
    public boolean getUpdateTableInRealTime() {
        return updateTableInRealTime;
    }

    /**
     * Sets the default renderer to be used when no <code>headerRenderer</code>
     * is defined by a <code>TableColumn</code>.
     * @param  defaultRenderer  the default renderer
     * @since 1.3
     */
    public void setDefaultRenderer(TableCellRenderer defaultRenderer) {
        this.defaultRenderer = defaultRenderer;
    }

    /**
     * Returns the default renderer used when no <code>headerRenderer</code>
     * is defined by a <code>TableColumn</code>.
     * @return the default renderer
     * @since 1.3
     */
    @Transient
    public TableCellRenderer getDefaultRenderer() {
        return defaultRenderer;
    }

    /**
     * Returns the index of the column that <code>point</code> lies in, or -1 if it
     * lies out of bounds.
     *
     * @return  the index of the column that <code>point</code> lies in, or -1 if it
     *          lies out of bounds
     */
    public int columnAtPoint(Point point) {
        int x = point.x;
        if (!getComponentOrientation().isLeftToRight()) {
            x = getWidthInRightToLeft() - x - 1;
        }
        return getColumnModel().getColumnIndexAtX(x);
    }

    /**
     * Returns the rectangle containing the header tile at <code>column</code>.
     * When the <code>column</code> parameter is out of bounds this method uses the
     * same conventions as the <code>JTable</code> method <code>getCellRect</code>.
     *
     * @return  the rectangle containing the header tile at <code>column</code>
     * @see JTable#getCellRect
     */
    public Rectangle getHeaderRect(int column) {
        Rectangle r = new Rectangle();
        TableColumnModel cm = getColumnModel();

        r.height = getHeight();

        if (column < 0) {
            // x = width = 0;
            if( !getComponentOrientation().isLeftToRight() ) {
                r.x = getWidthInRightToLeft();
            }
        }
        else if (column >= cm.getColumnCount()) {
            if( getComponentOrientation().isLeftToRight() ) {
                r.x = getWidth();
            }
        }
        else {
            for(int i = 0; i < column; i++) {
                r.x += cm.getColumn(i).getWidth();
            }
            if( !getComponentOrientation().isLeftToRight() ) {
                r.x = getWidthInRightToLeft() - r.x - cm.getColumn(column).getWidth();
            }

            r.width = cm.getColumn(column).getWidth();
        }
        return r;
    }


    /**
     * Allows the renderer's tips to be used if there is text set.
     * @param  event  the location of the event identifies the proper
     *                          renderer and, therefore, the proper tip
     * @return the tool tip for this component
     */
    public String getToolTipText(MouseEvent event) {
        String tip = null;
        Point p = event.getPoint();
        int column;

        // Locate the renderer under the event location
        if ((column = columnAtPoint(p)) != -1) {
            TableColumn aColumn = columnModel.getColumn(column);
            TableCellRenderer renderer = aColumn.getHeaderRenderer();
            if (renderer == null) {
                renderer = defaultRenderer;
            }
            Component component = renderer.getTableCellRendererComponent(
                              getTable(), aColumn.getHeaderValue(), false, false,
                              -1, column);

            // Now have to see if the component is a JComponent before
            // getting the tip
            if (component instanceof JComponent) {
                // Convert the event to the renderer's coordinate system
                MouseEvent newEvent;
                Rectangle cellRect = getHeaderRect(column);

                p.translate(-cellRect.x, -cellRect.y);
                newEvent = new MouseEvent(component, event.getID(),
                                          event.getWhen(), event.getModifiers(),
                                          p.x, p.y, event.getXOnScreen(), event.getYOnScreen(),
                                          event.getClickCount(),
                                          event.isPopupTrigger(), MouseEvent.NOBUTTON);

                tip = ((JComponent)component).getToolTipText(newEvent);
            }
        }

        // 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
