/* * Copyright (c) 1997, 2016, 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.BeanProperty; import java.beans.PropertyChangeListener; import java.beans.Transient; import java.io.ObjectOutputStream; import java.io.IOException; import sun.awt.AWTAccessor; import sun.awt.AWTAccessor.MouseEventAccessor; /** * This is the object which manages the header of the JTable. *

* Warning: * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans™ * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. * * @author Alan Chung * @author Philip Milne * @see javax.swing.JTable */ @SuppressWarnings("serial") // Same-version serialization only 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 null. */ protected JTable table; /** * The TableColumnModel 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. null if not resizing. */ protected transient TableColumn resizingColumn; /** The index of the column being dragged. null if not dragging. */ protected transient TableColumn draggedColumn; /** The distance from its original position the column has been dragged. */ protected transient int draggedDistance; /** * The default renderer to be used when a TableColumn * does not define a headerRenderer. */ private TableCellRenderer defaultRenderer; /** * Flag to indicate UI update is in progress */ private transient boolean updateInProgress; // // Constructors // /** * Constructs a JTableHeader with a default * TableColumnModel. * * @see #createDefaultColumnModel */ public JTableHeader() { this(null); } /** * Constructs a JTableHeader which is initialized with * cm as the column model. If cm is * null this method will initialize the table header * with a default TableColumnModel. * * @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 */ @BeanProperty(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 table 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 */ @BeanProperty(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 reorderingAllowed 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 */ @BeanProperty(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 resizingAllowed property * @see #setResizingAllowed */ public boolean getResizingAllowed() { return resizingAllowed; } /** * Returns the dragged column, if and only if, a drag is in * process, otherwise returns null. * * @return the dragged column, if a drag is in * process, otherwise returns null * @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 null. * * @return the resizing column, if a resize is in process, otherwise * returns null */ 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. * @param flag true if tableView should update the body of the * table in real time */ 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. * @return true if the table updates in real time */ public boolean getUpdateTableInRealTime() { return updateTableInRealTime; } /** * Sets the default renderer to be used when no headerRenderer * is defined by a TableColumn. * @param defaultRenderer the default renderer * @since 1.3 */ public void setDefaultRenderer(TableCellRenderer defaultRenderer) { this.defaultRenderer = defaultRenderer; } /** * Returns the default renderer used when no headerRenderer * is defined by a TableColumn. * @return the default renderer * @since 1.3 */ @Transient public TableCellRenderer getDefaultRenderer() { return defaultRenderer; } /** * Returns the index of the column that point lies in, or -1 if it * lies out of bounds. * * @param point if this point lies within a column, the index of * that column will be returned; otherwise it is out of bounds * and -1 is returned * * @return the index of the column that point 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 column. * When the column parameter is out of bounds this method uses the * same conventions as the JTable method getCellRect. * * @param column index of the column * * @return the rectangle containing the header tile at column * @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 */ @SuppressWarnings("deprecation") 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); MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor(); meAccessor.setCausedByTouchEvent(newEvent, meAccessor.isCausedByTouchEvent(event)); tip = ((JComponent)component).getToolTipText(newEvent); } } // No tip from the renderer get our own tip if (tip == null) tip = getToolTipText(); return tip; } /** * Returns the preferred size of the table header. * This is the size required to display the header and requested for * the viewport. * The returned {@code Dimension} {@code width} will always be calculated by * the underlying TableHeaderUI, regardless of any width specified by * {@link JComponent#setPreferredSize(java.awt.Dimension)} * * @return the size */ @Override public Dimension getPreferredSize() { Dimension preferredSize = super.getPreferredSize(); if (isPreferredSizeSet() && ui != null) { Dimension size = ui.getPreferredSize(this); if (size != null) preferredSize.width = size.width; } return preferredSize; } // // Managing TableHeaderUI // /** * Returns the look and feel (L&F) object that renders this component. * * @return the TableHeaderUI 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 TableHeaderUI L&F object * @see UIDefaults#getUI */ public void setUI(TableHeaderUI ui){ if (this.ui != ui) { super.setUI(ui); repaint(); } } /** * Notification from the UIManager that the look and feel * (L&F) has changed. * Replaces the current UI object with the latest version from the * UIManager. * * @see JComponent#updateUI */ public void updateUI(){ if (!updateInProgress) { updateInProgress = true; try { setUI((TableHeaderUI)UIManager.getUI(this)); TableCellRenderer renderer = getDefaultRenderer(); if (renderer instanceof Component) { SwingUtilities.updateComponentTreeUI((Component)renderer); } } finally { updateInProgress = false; } } } /** * 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 newModel and registers * for listener notifications from the new column model. * * @param columnModel the new data source for this table * @exception IllegalArgumentException * if newModel is null * @see #getColumnModel */ @BeanProperty(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 TableColumnModel that contains all column information * of this table header. * * @return the columnModel property * @see #setColumnModel */ public TableColumnModel getColumnModel() { return columnModel; } // // Implementing TableColumnModelListener interface // /** * Invoked when a column is added to the table column model. *

* Application code will not use these methods explicitly, they * are used internally by JTable. * * @param e the event received * @see TableColumnModelListener */ public void columnAdded(TableColumnModelEvent e) { resizeAndRepaint(); } /** * Invoked when a column is removed from the table column model. *

* Application code will not use these methods explicitly, they * are used internally by JTable. * * @param e the event received * @see TableColumnModelListener */ public void columnRemoved(TableColumnModelEvent e) { resizeAndRepaint(); } /** * Invoked when a column is repositioned. *

* Application code will not use these methods explicitly, they * are used internally by JTable. * * @param e the event received * @see TableColumnModelListener */ public void columnMoved(TableColumnModelEvent e) { repaint(); } /** * Invoked when a column is moved due to a margin change. *

* Application code will not use these methods explicitly, they * are used internally by JTable. * * @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 TableColumnModel * is changed. This method currently has no effect (the header is not * redrawn). *

* Application code will not use these methods explicitly, they * are used internally by JTable. * * @param e the event received * @see TableColumnModelListener */ public void columnSelectionChanged(ListSelectionEvent e) { } // repaint(); } // // Package Methods // /** * Returns the default column model object which is * a DefaultTableColumnModel. 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 TableColumn. * * @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 revalidate followed by repaint. */ public void resizeAndRepaint() { revalidate(); repaint(); } /** * Sets the header's draggedColumn to aColumn. *

* Application code will not use this method explicitly, it is used * internally by the column dragging mechanism. * * @param aColumn the column being dragged, or null if * no column is being dragged */ public void setDraggedColumn(TableColumn aColumn) { draggedColumn = aColumn; } /** * Sets the header's draggedDistance to distance. * @param distance the distance dragged */ public void setDraggedDistance(int distance) { draggedDistance = distance; } /** * Sets the header's resizingColumn to aColumn. *

* Application code will not use this method explicitly, it * is used internally by the column sizing mechanism. * * @param aColumn the column being resized, or null if * no column is being resized */ public void setResizingColumn(TableColumn aColumn) { resizingColumn = aColumn; } /** * See readObject and writeObject in * JComponent 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 JTableHeader. 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 null. *

* Overriding paramString to provide information about the * specific new aspects of the JFC components. * * @return a string representation of this JTableHeader */ 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 * JTableHeader class. It provides an implementation of the * Java Accessibility API appropriate to table header user-interface * elements. *

* Warning: * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans™ * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. */ @SuppressWarnings("serial") // Same-version serialization only 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 appropriate 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 * * @param c the column index * @param p the parent JTableHeader * @param t the table JTable */ 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; } } @SuppressWarnings("deprecation") 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