1. /*
  2. * @(#)JTableHeader.java 1.37 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.table;
  8. import java.util.*;
  9. import java.awt.*;
  10. import java.awt.event.*;
  11. import javax.swing.*;
  12. import javax.swing.event.*;
  13. import javax.swing.plaf.*;
  14. import javax.accessibility.*;
  15. import java.beans.PropertyChangeListener;
  16. import java.io.ObjectOutputStream;
  17. import java.io.ObjectInputStream;
  18. import java.io.IOException;
  19. /**
  20. * This is the column header part of a JTable. I allow the user to
  21. * change column widths and column ordering. I share the same
  22. * TableColumnModel with a JTable.
  23. * <p>
  24. * <strong>Warning:</strong>
  25. * Serialized objects of this class will not be compatible with
  26. * future Swing releases. The current serialization support is appropriate
  27. * for short term storage or RMI between applications running the same
  28. * version of Swing. A future release of Swing will provide support for
  29. * long term persistence.
  30. *
  31. * @version 1.37 11/29/01
  32. * @author Alan Chung
  33. * @author Philip Milne
  34. * @see javax.swing.JTable
  35. */
  36. public class JTableHeader extends JComponent implements TableColumnModelListener, Accessible
  37. {
  38. /**
  39. * @see #getUIClassID
  40. * @see #readObject
  41. */
  42. private static final String uiClassID = "TableHeaderUI";
  43. //
  44. // Instance Variables
  45. //
  46. protected JTable table;
  47. /** The TableColumnModel of the table header*/
  48. protected TableColumnModel columnModel;
  49. /** Reordering of columns are allowed by the user */
  50. protected boolean reorderingAllowed;
  51. /** Resizing of columns are allowed by the user */
  52. protected boolean resizingAllowed;
  53. /**
  54. * If this flag is true, then the header will repaint the table as
  55. * a column is dragged or resized.
  56. */
  57. protected boolean updateTableInRealTime;
  58. /** The index of the column being resized. 0 if not resizing */
  59. transient protected TableColumn resizingColumn;
  60. /** The index of the column being dragged. 0 if not dragging */
  61. transient protected TableColumn draggedColumn;
  62. /** The distance from its original position the column has been dragged */
  63. transient protected int draggedDistance;
  64. //
  65. // Constructors
  66. //
  67. /**
  68. * Constructs a JTableHeader with a default TableColumnModel
  69. *
  70. * @see #createDefaultColumnModel()
  71. */
  72. public JTableHeader() {
  73. this(null);
  74. }
  75. /**
  76. * Constructs a JTableHeader which is initialized with
  77. * <i>cm</i> as the column model. If <i>cm</i> is
  78. * <b>null</b> this method will initialize the table header
  79. * with a default TableColumnModel.
  80. *
  81. * @param cm The column model for the table
  82. * @see #createDefaultColumnModel()
  83. */
  84. public JTableHeader(TableColumnModel cm) {
  85. super();
  86. if (cm == null)
  87. cm = createDefaultColumnModel();
  88. setColumnModel(cm);
  89. // Initalize local ivars
  90. initializeLocalVars();
  91. // Get UI going
  92. updateUI();
  93. }
  94. //
  95. // Local behavior attributes
  96. //
  97. /** Sets the header's partner table to <I>aTable</I> */
  98. public void setTable(JTable aTable) {
  99. table = aTable;
  100. }
  101. /** Returns the header's partner table */
  102. public JTable getTable() {
  103. return table;
  104. }
  105. /**
  106. * Sets whether the user can drag column headers to reorder columns.
  107. *
  108. * @param flag true if the table view should allow
  109. * reordering
  110. * @see #getReorderingAllowed
  111. */
  112. public void setReorderingAllowed(boolean b) {
  113. reorderingAllowed = b;
  114. }
  115. /**
  116. * Returns true if the receiver allows the user to rearrange columns by
  117. * dragging their headers, false otherwise. The default is true. You can
  118. * rearrange columns programmatically regardless of this setting.
  119. *
  120. * @return true if the receiver allows the user to rearrange columns by
  121. * dragging their headers, false otherwise
  122. * @see #setReorderingAllowed
  123. */
  124. public boolean getReorderingAllowed() {
  125. return reorderingAllowed;
  126. }
  127. /**
  128. * Sets whether the user can resize columns by dragging between headers.
  129. *
  130. * @param flag true if table view should allow
  131. * resizing
  132. * @see #getResizingAllowed
  133. */
  134. public void setResizingAllowed(boolean b) {
  135. resizingAllowed = b;
  136. }
  137. /**
  138. * Returns true if the receiver allows the user to resize columns by dragging
  139. * between their headers, false otherwise. The default is true. You can
  140. * resize columns programmatically regardless of this setting.
  141. *
  142. * @return true if the receiver allows the user to resize columns by
  143. * dragging between their headers, false otherwise.
  144. * @see #setResizingAllowed
  145. */
  146. public boolean getResizingAllowed() {
  147. return resizingAllowed;
  148. }
  149. /**
  150. * Returns the the dragged column, if and only if a drag is in
  151. * process.
  152. *
  153. * @return the the dragged column, if and only if a drag is in
  154. * process, otherwise returns null.
  155. * @see #getDraggedDistance
  156. */
  157. public TableColumn getDraggedColumn() {
  158. return draggedColumn;
  159. }
  160. /**
  161. * Returns the column's horizontal distance from its original
  162. * position, if and only if a drag is in process. Otherwise, the
  163. * the return value is meaningless.
  164. *
  165. * @return the column's horizontal distance from its original
  166. * position, if and only if a drag is in process
  167. * @see #getDraggedColumn
  168. */
  169. public int getDraggedDistance() {
  170. return draggedDistance;
  171. }
  172. /**
  173. * Returns the resizing column. If no column is being
  174. * resized this method returns null.
  175. *
  176. * @return the resizing column
  177. */
  178. public TableColumn getResizingColumn() {
  179. return resizingColumn;
  180. }
  181. /**
  182. * Sets whether the body of the table updates in real time when
  183. * a column is resized or dragged.
  184. *
  185. * @param flag true if tableView should update
  186. * the body of the table in real time
  187. * @see #getUpdateTableInRealTime
  188. */
  189. public void setUpdateTableInRealTime(boolean flag) {
  190. updateTableInRealTime = flag;
  191. }
  192. /**
  193. * Returns true if the receiver updates the body of the table view in real
  194. * time when a column is resized or dragged. User can set this flag to
  195. * false to speed up the table's response to user resize or drag actions.
  196. * The default is true.
  197. *
  198. * @return true if the table updates in real time
  199. * @see #setUpdateTableInRealTime
  200. */
  201. public boolean getUpdateTableInRealTime() {
  202. return updateTableInRealTime;
  203. }
  204. /**
  205. * Returns the index of the column that <I>point</I> lies in, or -1 if it
  206. * lies outside the receiver's bounds.
  207. *
  208. * @return the index of the column that <I>point</I> lies in, or -1 if it
  209. * lies outside the receiver's bounds
  210. */
  211. public int columnAtPoint(Point point) {
  212. return getColumnModel().getColumnIndexAtX(point.x);
  213. }
  214. /**
  215. * Returns the rectangle containing the header tile at <I>columnIndex</I>.
  216. *
  217. * @return the rectangle containing the header tile at <I>columnIndex</I>
  218. * @exception IllegalArgumentException If <I>columnIndex</I> is out
  219. * of range
  220. */
  221. public Rectangle getHeaderRect(int columnIndex) {
  222. // PENDING(philiip) The implementation should be delegated to the UI.
  223. TableColumnModel columnModel = getColumnModel();
  224. if ((columnIndex < 0) || (columnIndex >= columnModel.getColumnCount())) {
  225. throw new IllegalArgumentException("Column index out of range");
  226. }
  227. int rectX = 0;
  228. int column = 0;
  229. int columnMargin = getColumnModel().getColumnMargin();
  230. Enumeration enumeration = getColumnModel().getColumns();
  231. while (enumeration.hasMoreElements()) {
  232. TableColumn aColumn = (TableColumn)enumeration.nextElement();
  233. if (column == columnIndex) {
  234. return new Rectangle(rectX, 0,
  235. aColumn.getWidth() + columnMargin,
  236. getSize().height);
  237. }
  238. rectX += aColumn.getWidth() + columnMargin;
  239. column++;
  240. }
  241. return new Rectangle();
  242. }
  243. /**
  244. * Overriding to allow renderer's tips to be used if it has
  245. * text set.
  246. */
  247. public String getToolTipText(MouseEvent event) {
  248. String tip = null;
  249. Point p = event.getPoint();
  250. int column;
  251. // Locate the renderer under the event location
  252. if ((column = columnModel.getColumnIndexAtX(p.x)) != -1) {
  253. TableColumn aColumn = columnModel.getColumn(column);
  254. TableCellRenderer renderer = aColumn.getHeaderRenderer();
  255. Component component = renderer.getTableCellRendererComponent(
  256. getTable(), aColumn.getHeaderValue(), false, false,
  257. -1, column);
  258. // Now have to see if the component is a JComponent before
  259. // getting the tip
  260. if (component instanceof JComponent) {
  261. // Convert the event to the renderer's coordinate system
  262. MouseEvent newEvent;
  263. Rectangle cellRect = getHeaderRect(column);
  264. p.translate(-cellRect.x, -cellRect.y);
  265. newEvent = new MouseEvent(component, event.getID(),
  266. event.getWhen(), event.getModifiers(),
  267. p.x, p.y, event.getClickCount(),
  268. event.isPopupTrigger());
  269. tip = ((JComponent)component).getToolTipText(newEvent);
  270. }
  271. }
  272. // No tip from the renderer get our own tip
  273. if (tip == null)
  274. tip = getToolTipText();
  275. return tip;
  276. }
  277. //
  278. // Managing TableHeaderUI
  279. //
  280. /**
  281. * Returns the L&F object that renders this component.
  282. *
  283. * @return the TableHeaderUI object that renders this component
  284. */
  285. public TableHeaderUI getUI() {
  286. return (TableHeaderUI)ui;
  287. }
  288. /**
  289. * Sets the L&F object that renders this component.
  290. *
  291. * @param ui the TableHeaderUI L&F object
  292. * @see UIDefaults#getUI
  293. */
  294. public void setUI(TableHeaderUI ui){
  295. if (this.ui != ui) {
  296. super.setUI(ui);
  297. repaint();
  298. }
  299. }
  300. /**
  301. * Notification from the UIManager that the L&F has changed.
  302. * Replaces the current UI object with the latest version from the
  303. * UIManager.
  304. *
  305. * @see JComponent#updateUI
  306. */
  307. public void updateUI(){
  308. setUI((TableHeaderUI)UIManager.getUI(this));
  309. resizeAndRepaint();
  310. invalidate();//PENDING
  311. }
  312. /**
  313. * Returns the name of the L&F class that renders this component.
  314. *
  315. * @return "TableHeaderUI"
  316. * @see JComponent#getUIClassID
  317. * @see UIDefaults#getUI
  318. */
  319. public String getUIClassID() {
  320. return uiClassID;
  321. }
  322. //
  323. // Managing models
  324. //
  325. /**
  326. * Sets the column model for this table to <I>newModel</I> and registers
  327. * with for listner notifications from the new column model.
  328. *
  329. * @param newModel the new data source for this table
  330. * @exception IllegalArgumentException if <I>newModel</I> is null
  331. * @see #getColumnModel()
  332. */
  333. public void setColumnModel(TableColumnModel newModel) {
  334. if (newModel == null) {
  335. throw new IllegalArgumentException("Cannot set a null ColumnModel");
  336. }
  337. TableColumnModel oldModel = columnModel;
  338. if (newModel != oldModel) {
  339. if (oldModel != null)
  340. oldModel.removeColumnModelListener(this);
  341. columnModel = newModel;
  342. newModel.addColumnModelListener(this);
  343. resizeAndRepaint();
  344. }
  345. }
  346. /**
  347. * Returns the <B>TableColumnModel</B> that contains all column inforamtion
  348. * of this table header.
  349. *
  350. * @return the object that provides the column state of the table
  351. * @see #setColumnModel()
  352. */
  353. public TableColumnModel getColumnModel() {
  354. return columnModel;
  355. }
  356. //
  357. // Implementing TableColumnModelListener interface
  358. //
  359. // implements javax.swing.event.TableColumnModelListener
  360. public void columnAdded(TableColumnModelEvent e) { resizeAndRepaint(); }
  361. // implements javax.swing.event.TableColumnModelListener
  362. public void columnRemoved(TableColumnModelEvent e) { resizeAndRepaint(); }
  363. // implements javax.swing.event.TableColumnModelListener
  364. public void columnMoved(TableColumnModelEvent e) { repaint(); }
  365. // implements javax.swing.event.TableColumnModelListener
  366. public void columnMarginChanged(ChangeEvent e) { resizeAndRepaint(); }
  367. // implements javax.swing.event.TableColumnModelListener
  368. // --Redrawing the header is slow in cell selection mode.
  369. // --Since header selection is ugly and it is always cler from the
  370. // --view which columns are selected, don't redraw the header.
  371. public void columnSelectionChanged(ListSelectionEvent e) { } // repaint(); }
  372. //
  373. // Package Methods
  374. //
  375. /**
  376. * Returns the default column model object which is
  377. * a DefaultTableColumnModel. Subclass can override this
  378. * method to return a different column model object
  379. *
  380. * @return the default column model object
  381. */
  382. protected TableColumnModel createDefaultColumnModel() {
  383. return new DefaultTableColumnModel();
  384. }
  385. protected void initializeLocalVars() {
  386. setOpaque(true);
  387. table = null;
  388. reorderingAllowed = true;
  389. resizingAllowed = true;
  390. draggedColumn = null;
  391. draggedDistance = 0;
  392. resizingColumn = null;
  393. updateTableInRealTime = true;
  394. // I'm registered to do tool tips so we can draw tips for the
  395. // renderers
  396. ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
  397. toolTipManager.registerComponent(this);
  398. }
  399. /**
  400. * Properly sizes the receiver and its header view, and marks it as
  401. * needing display. Also resets cursor rectangles for the header view
  402. * and line scroll amounts for the <B>JScrollPane</B>.
  403. */
  404. public void resizeAndRepaint() {
  405. revalidate();
  406. repaint();
  407. }
  408. /** Sets the header's draggedColumn to <I>aColumn</I> */
  409. public void setDraggedColumn(TableColumn aColumn) {
  410. draggedColumn = aColumn;
  411. }
  412. /** Sets the header's draggedDistance to <I>distance</I> */
  413. public void setDraggedDistance(int distance) {
  414. draggedDistance = distance;
  415. }
  416. /** Sets the header's resizingColumn to <I>aColumn</I> */
  417. public void setResizingColumn(TableColumn aColumn) {
  418. resizingColumn = aColumn;
  419. }
  420. /**
  421. * See readObject() and writeObject() in JComponent for more
  422. * information about serialization in Swing.
  423. */
  424. private void writeObject(ObjectOutputStream s) throws IOException {
  425. s.defaultWriteObject();
  426. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  427. ui.installUI(this);
  428. }
  429. }
  430. /**
  431. * Returns a string representation of this JTableHeader. This method
  432. * is intended to be used only for debugging purposes, and the
  433. * content and format of the returned string may vary between
  434. * implementations. The returned string may be empty but may not
  435. * be <code>null</code>.
  436. * <P>
  437. * Overriding paramString() to provide information about the
  438. * specific new aspects of the JFC components.
  439. *
  440. * @return a string representation of this JTableHeader.
  441. */
  442. protected String paramString() {
  443. String reorderingAllowedString = (reorderingAllowed ?
  444. "true" : "false");
  445. String resizingAllowedString = (resizingAllowed ?
  446. "true" : "false");
  447. String updateTableInRealTimeString = (updateTableInRealTime ?
  448. "true" : "false");
  449. return super.paramString() +
  450. ",draggedDistance=" + draggedDistance +
  451. ",reorderingAllowed=" + reorderingAllowedString +
  452. ",resizingAllowed=" + resizingAllowedString +
  453. ",updateTableInRealTime=" + updateTableInRealTimeString;
  454. }
  455. /////////////////
  456. // Accessibility support
  457. ////////////////
  458. /**
  459. * Get the AccessibleContext associated with this JComponent
  460. *
  461. * @return the AccessibleContext of this JComponent
  462. */
  463. public AccessibleContext getAccessibleContext() {
  464. if (accessibleContext == null) {
  465. accessibleContext = new AccessibleJTableHeader();
  466. }
  467. return accessibleContext;
  468. }
  469. //
  470. // *** should also implement AccessibleSelction?
  471. // *** and what's up with keyboard navigation/manipulation?
  472. //
  473. /**
  474. * The class used to obtain the accessible role for this object.
  475. * <p>
  476. * <strong>Warning:</strong>
  477. * Serialized objects of this class will not be compatible with
  478. * future Swing releases. The current serialization support is appropriate
  479. * for short term storage or RMI between applications running the same
  480. * version of Swing. A future release of Swing will provide support for
  481. * long term persistence.
  482. */
  483. protected class AccessibleJTableHeader extends AccessibleJComponent {
  484. /**
  485. * Get the role of this object.
  486. *
  487. * @return an instance of AccessibleRole describing the role of the
  488. * object
  489. * @see AccessibleRole
  490. */
  491. public AccessibleRole getAccessibleRole() {
  492. return AccessibleRole.PANEL;
  493. }
  494. /**
  495. * Returns the Accessible child, if one exists, contained at the local
  496. * coordinate Point.
  497. *
  498. * @param p The point defining the top-left corner of the Accessible,
  499. * given in the coordinate space of the object's parent.
  500. * @return the Accessible, if it exists, at the specified location;
  501. * else null
  502. */
  503. public Accessible getAccessibleAt(Point p) {
  504. int column;
  505. // Locate the renderer under the Point
  506. if ((column = JTableHeader.this.columnAtPoint(p)) != -1) {
  507. TableColumn aColumn = JTableHeader.this.columnModel.getColumn(column);
  508. TableCellRenderer renderer = aColumn.getHeaderRenderer();
  509. Component component = renderer.getTableCellRendererComponent(
  510. JTableHeader.this.getTable(),
  511. aColumn.getHeaderValue(), false, false,
  512. -1, column);
  513. return new AccessibleJTableHeaderEntry(column, JTableHeader.this, JTableHeader.this.table);
  514. } else {
  515. return null;
  516. }
  517. }
  518. /**
  519. * Returns the number of accessible children in the object. If all
  520. * of the children of this object implement Accessible, than this
  521. * method should return the number of children of this object.
  522. *
  523. * @return the number of accessible children in the object.
  524. */
  525. public int getAccessibleChildrenCount() {
  526. return JTableHeader.this.columnModel.getColumnCount();
  527. }
  528. /**
  529. * Return the nth Accessible child of the object.
  530. *
  531. * @param i zero-based index of child
  532. * @return the nth Accessible child of the object
  533. */
  534. public Accessible getAccessibleChild(int i) {
  535. if (i < 0 || i >= getAccessibleChildrenCount()) {
  536. return null;
  537. } else {
  538. TableColumn aColumn = JTableHeader.this.columnModel.getColumn(i)
  539. ;
  540. TableCellRenderer renderer = aColumn.getHeaderRenderer();
  541. Component component = renderer.getTableCellRendererComponent(
  542. JTableHeader.this.getTable(),
  543. aColumn.getHeaderValue(), false, false,
  544. -1, i);
  545. return new AccessibleJTableHeaderEntry(i, JTableHeader.this, JTableHeader.this.table);
  546. }
  547. }
  548. protected class AccessibleJTableHeaderEntry extends AccessibleContext
  549. implements Accessible, AccessibleComponent {
  550. private JTableHeader parent;
  551. private int column;
  552. private JTable table;
  553. /**
  554. * Constructs an AccessiblJTableHeaaderEntry
  555. */
  556. public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t) {
  557. parent = p;
  558. column = c;
  559. table = t;
  560. this.setAccessibleParent(parent);
  561. }
  562. /**
  563. * Get the AccessibleContext associated with this
  564. *
  565. * @return the AccessibleContext of this JComponent
  566. */
  567. public AccessibleContext getAccessibleContext() {
  568. return this;
  569. }
  570. private AccessibleContext getCurrentAccessibleContext() {
  571. TableColumnModel tcm = table.getColumnModel();
  572. if (tcm != null) {
  573. TableColumn aColumn = tcm.getColumn(column);
  574. TableCellRenderer renderer = aColumn.getHeaderRenderer();
  575. Component c = renderer.getTableCellRendererComponent(
  576. JTableHeader.this.getTable(),
  577. aColumn.getHeaderValue(), false, false,
  578. -1, column);
  579. if (c instanceof Accessible) {
  580. return ((Accessible) c).getAccessibleContext();
  581. }
  582. }
  583. return null;
  584. }
  585. private Component getCurrentComponent() {
  586. TableColumnModel tcm = table.getColumnModel();
  587. if (tcm != null) {
  588. TableColumn aColumn = tcm.getColumn(column);
  589. TableCellRenderer renderer = aColumn.getHeaderRenderer();
  590. return renderer.getTableCellRendererComponent(
  591. JTableHeader.this.getTable(),
  592. aColumn.getHeaderValue(), false, false,
  593. -1, column);
  594. } else {
  595. return null;
  596. }
  597. }
  598. // AccessibleContext methods
  599. public String getAccessibleName() {
  600. AccessibleContext ac = getCurrentAccessibleContext();
  601. if (ac != null) {
  602. String name = ac.getAccessibleName();
  603. if ((name != null) && (name != "")) {
  604. return ac.getAccessibleName();
  605. }
  606. }
  607. if ((accessibleName != null) && (accessibleName != "")) {
  608. return accessibleName;
  609. } else {
  610. return table.getColumnName(column);
  611. }
  612. }
  613. public void setAccessibleName(String s) {
  614. AccessibleContext ac = getCurrentAccessibleContext();
  615. if (ac != null) {
  616. ac.setAccessibleName(s);
  617. } else {
  618. super.setAccessibleName(s);
  619. }
  620. }
  621. //
  622. // *** should check toolip text for desc. (needs MouseEvent)
  623. //
  624. public String getAccessibleDescription() {
  625. AccessibleContext ac = getCurrentAccessibleContext();
  626. if (ac != null) {
  627. return ac.getAccessibleDescription();
  628. } else {
  629. return super.getAccessibleDescription();
  630. }
  631. }
  632. public void setAccessibleDescription(String s) {
  633. AccessibleContext ac = getCurrentAccessibleContext();
  634. if (ac != null) {
  635. ac.setAccessibleDescription(s);
  636. } else {
  637. super.setAccessibleDescription(s);
  638. }
  639. }
  640. public AccessibleRole getAccessibleRole() {
  641. AccessibleContext ac = getCurrentAccessibleContext();
  642. if (ac != null) {
  643. return ac.getAccessibleRole();
  644. } else {
  645. return AccessibleRole.COLUMN_HEADER;
  646. }
  647. }
  648. public AccessibleStateSet getAccessibleStateSet() {
  649. AccessibleContext ac = getCurrentAccessibleContext();
  650. if (ac != null) {
  651. AccessibleStateSet states = ac.getAccessibleStateSet();
  652. if (isShowing()) {
  653. states.add(AccessibleState.SHOWING);
  654. }
  655. return states;
  656. } else {
  657. return new AccessibleStateSet(); // must be non null?
  658. }
  659. }
  660. public int getAccessibleIndexInParent() {
  661. return column;
  662. }
  663. public int getAccessibleChildrenCount() {
  664. AccessibleContext ac = getCurrentAccessibleContext();
  665. if (ac != null) {
  666. return ac.getAccessibleChildrenCount();
  667. } else {
  668. return 0;
  669. }
  670. }
  671. public Accessible getAccessibleChild(int i) {
  672. AccessibleContext ac = getCurrentAccessibleContext();
  673. if (ac != null) {
  674. Accessible accessibleChild = ac.getAccessibleChild(i);
  675. ac.setAccessibleParent(this);
  676. return accessibleChild;
  677. } else {
  678. return null;
  679. }
  680. }
  681. public Locale getLocale() {
  682. AccessibleContext ac = getCurrentAccessibleContext();
  683. if (ac != null) {
  684. return ac.getLocale();
  685. } else {
  686. return null;
  687. }
  688. }
  689. public void addPropertyChangeListener(PropertyChangeListener l) {
  690. AccessibleContext ac = getCurrentAccessibleContext();
  691. if (ac != null) {
  692. ac.addPropertyChangeListener(l);
  693. } else {
  694. super.addPropertyChangeListener(l);
  695. }
  696. }
  697. public void removePropertyChangeListener(PropertyChangeListener l) {
  698. AccessibleContext ac = getCurrentAccessibleContext();
  699. if (ac != null) {
  700. ac.removePropertyChangeListener(l);
  701. } else {
  702. super.removePropertyChangeListener(l);
  703. }
  704. }
  705. public AccessibleAction getAccessibleAction() {
  706. return getCurrentAccessibleContext().getAccessibleAction();
  707. }
  708. public AccessibleComponent getAccessibleComponent() {
  709. return this; // to override getBounds()
  710. }
  711. public AccessibleSelection getAccessibleSelection() {
  712. return getCurrentAccessibleContext().getAccessibleSelection();
  713. }
  714. public AccessibleText getAccessibleText() {
  715. return getCurrentAccessibleContext().getAccessibleText();
  716. }
  717. public AccessibleValue getAccessibleValue() {
  718. return getCurrentAccessibleContext().getAccessibleValue();
  719. }
  720. // AccessibleComponent methods
  721. public Color getBackground() {
  722. AccessibleContext ac = getCurrentAccessibleContext();
  723. if (ac instanceof AccessibleComponent) {
  724. return ((AccessibleComponent) ac).getBackground();
  725. } else {
  726. Component c = getCurrentComponent();
  727. if (c != null) {
  728. return c.getBackground();
  729. } else {
  730. return null;
  731. }
  732. }
  733. }
  734. public void setBackground(Color c) {
  735. AccessibleContext ac = getCurrentAccessibleContext();
  736. if (ac instanceof AccessibleComponent) {
  737. ((AccessibleComponent) ac).setBackground(c);
  738. } else {
  739. Component cp = getCurrentComponent();
  740. if (cp != null) {
  741. cp.setBackground(c);
  742. }
  743. }
  744. }
  745. public Color getForeground() {
  746. AccessibleContext ac = getCurrentAccessibleContext();
  747. if (ac instanceof AccessibleComponent) {
  748. return ((AccessibleComponent) ac).getForeground();
  749. } else {
  750. Component c = getCurrentComponent();
  751. if (c != null) {
  752. return c.getForeground();
  753. } else {
  754. return null;
  755. }
  756. }
  757. }
  758. public void setForeground(Color c) {
  759. AccessibleContext ac = getCurrentAccessibleContext();
  760. if (ac instanceof AccessibleComponent) {
  761. ((AccessibleComponent) ac).setForeground(c);
  762. } else {
  763. Component cp = getCurrentComponent();
  764. if (cp != null) {
  765. cp.setForeground(c);
  766. }
  767. }
  768. }
  769. public Cursor getCursor() {
  770. AccessibleContext ac = getCurrentAccessibleContext();
  771. if (ac instanceof AccessibleComponent) {
  772. return ((AccessibleComponent) ac).getCursor();
  773. } else {
  774. Component c = getCurrentComponent();
  775. if (c != null) {
  776. return c.getCursor();
  777. } else {
  778. Accessible ap = getAccessibleParent();
  779. if (ap instanceof AccessibleComponent) {
  780. return ((AccessibleComponent) ap).getCursor();
  781. } else {
  782. return null;
  783. }
  784. }
  785. }
  786. }
  787. public void setCursor(Cursor c) {
  788. AccessibleContext ac = getCurrentAccessibleContext();
  789. if (ac instanceof AccessibleComponent) {
  790. ((AccessibleComponent) ac).setCursor(c);
  791. } else {
  792. Component cp = getCurrentComponent();
  793. if (cp != null) {
  794. cp.setCursor(c);
  795. }
  796. }
  797. }
  798. public Font getFont() {
  799. AccessibleContext ac = getCurrentAccessibleContext();
  800. if (ac instanceof AccessibleComponent) {
  801. return ((AccessibleComponent) ac).getFont();
  802. } else {
  803. Component c = getCurrentComponent();
  804. if (c != null) {
  805. return c.getFont();
  806. } else {
  807. return null;
  808. }
  809. }
  810. }
  811. public void setFont(Font f) {
  812. AccessibleContext ac = getCurrentAccessibleContext();
  813. if (ac instanceof AccessibleComponent) {
  814. ((AccessibleComponent) ac).setFont(f);
  815. } else {
  816. Component c = getCurrentComponent();
  817. if (c != null) {
  818. c.setFont(f);
  819. }
  820. }
  821. }
  822. public FontMetrics getFontMetrics(Font f) {
  823. AccessibleContext ac = getCurrentAccessibleContext();
  824. if (ac instanceof AccessibleComponent) {
  825. return ((AccessibleComponent) ac).getFontMetrics(f);
  826. } else {
  827. Component c = getCurrentComponent();
  828. if (c != null) {
  829. return c.getFontMetrics(f);
  830. } else {
  831. return null;
  832. }
  833. }
  834. }
  835. public boolean isEnabled() {
  836. AccessibleContext ac = getCurrentAccessibleContext();
  837. if (ac instanceof AccessibleComponent) {
  838. return ((AccessibleComponent) ac).isEnabled();
  839. } else {
  840. Component c = getCurrentComponent();
  841. if (c != null) {
  842. return c.isEnabled();
  843. } else {
  844. return false;
  845. }
  846. }
  847. }
  848. public void setEnabled(boolean b) {
  849. AccessibleContext ac = getCurrentAccessibleContext();
  850. if (ac instanceof AccessibleComponent) {
  851. ((AccessibleComponent) ac).setEnabled(b);
  852. } else {
  853. Component c = getCurrentComponent();
  854. if (c != null) {
  855. c.setEnabled(b);
  856. }
  857. }
  858. }
  859. public boolean isVisible() {
  860. AccessibleContext ac = getCurrentAccessibleContext();
  861. if (ac instanceof AccessibleComponent) {
  862. return ((AccessibleComponent) ac).isVisible();
  863. } else {
  864. Component c = getCurrentComponent();
  865. if (c != null) {
  866. return c.isVisible();
  867. } else {
  868. return false;
  869. }
  870. }
  871. }
  872. public void setVisible(boolean b) {
  873. AccessibleContext ac = getCurrentAccessibleContext();
  874. if (ac instanceof AccessibleComponent) {
  875. ((AccessibleComponent) ac).setVisible(b);
  876. } else {
  877. Component c = getCurrentComponent();
  878. if (c != null) {
  879. c.setVisible(b);
  880. }
  881. }
  882. }
  883. public boolean isShowing() {
  884. if (isVisible() && JTableHeader.this.isShowing()) {
  885. return true;
  886. } else {
  887. return false;
  888. }
  889. }
  890. public boolean contains(Point p) {
  891. AccessibleContext ac = getCurrentAccessibleContext();
  892. if (ac instanceof AccessibleComponent) {
  893. Rectangle r = ((AccessibleComponent) ac).getBounds();
  894. return r.contains(p);
  895. } else {
  896. Component c = getCurrentComponent();
  897. if (c != null) {
  898. Rectangle r = c.getBounds();
  899. return r.contains(p);
  900. } else {
  901. return getBounds().contains(p);
  902. }
  903. }
  904. }
  905. public Point getLocationOnScreen() {
  906. if (parent != null) {
  907. Point parentLocation = parent.getLocationOnScreen();
  908. Point componentLocation = getLocation();
  909. componentLocation.translate(parentLocation.x, parentLocation.y);
  910. return componentLocation;
  911. } else {
  912. return null;
  913. }
  914. }
  915. public Point getLocation() {
  916. AccessibleContext ac = getCurrentAccessibleContext();
  917. if (ac instanceof AccessibleComponent) {
  918. Rectangle r = ((AccessibleComponent) ac).getBounds();
  919. return r.getLocation();
  920. } else {
  921. Component c = getCurrentComponent();
  922. if (c != null) {
  923. Rectangle r = c.getBounds();
  924. return r.getLocation();
  925. } else {
  926. return getBounds().getLocation();
  927. }
  928. }
  929. }
  930. public void setLocation(Point p) {
  931. // if ((parent != null) && (parent.contains(p))) {
  932. // ensureIndexIsVisible(indexInParent);
  933. // }
  934. }
  935. public Rectangle getBounds() {
  936. Rectangle r = table.getCellRect(-1, column, false);
  937. r.y = 0;
  938. return r;
  939. // AccessibleContext ac = getCurrentAccessibleContext();
  940. // if (ac instanceof AccessibleComponent) {
  941. // return ((AccessibleComponent) ac).getBounds();
  942. // } else {
  943. // Component c = getCurrentComponent();
  944. // if (c != null) {
  945. // return c.getBounds();
  946. // } else {
  947. // Rectangle r = table.getCellRect(-1, column, false);
  948. // r.y = 0;
  949. // return r;
  950. // }
  951. // }
  952. }
  953. public void setBounds(Rectangle r) {
  954. AccessibleContext ac = getCurrentAccessibleContext();
  955. if (ac instanceof AccessibleComponent) {
  956. ((AccessibleComponent) ac).setBounds(r);
  957. } else {
  958. Component c = getCurrentComponent();
  959. if (c != null) {
  960. c.setBounds(r);
  961. }
  962. }
  963. }
  964. public Dimension getSize() {
  965. return getBounds().getSize();
  966. // AccessibleContext ac = getCurrentAccessibleContext();
  967. // if (ac instanceof AccessibleComponent) {
  968. // Rectangle r = ((AccessibleComponent) ac).getBounds();
  969. // return r.getSize();
  970. // } else {
  971. // Component c = getCurrentComponent();
  972. // if (c != null) {
  973. // Rectangle r = c.getBounds();
  974. // return r.getSize();
  975. // } else {
  976. // return getBounds().getSize();
  977. // }
  978. // }
  979. }
  980. public void setSize (Dimension d) {
  981. AccessibleContext ac = getCurrentAccessibleContext();
  982. if (ac instanceof AccessibleComponent) {
  983. ((AccessibleComponent) ac).setSize(d);
  984. } else {
  985. Component c = getCurrentComponent();
  986. if (c != null) {
  987. c.setSize(d);
  988. }
  989. }
  990. }
  991. public Accessible getAccessibleAt(Point p) {
  992. AccessibleContext ac = getCurrentAccessibleContext();
  993. if (ac instanceof AccessibleComponent) {
  994. return ((AccessibleComponent) ac).getAccessibleAt(p);
  995. } else {
  996. return null;
  997. }
  998. }
  999. public boolean isFocusTraversable() {
  1000. AccessibleContext ac = getCurrentAccessibleContext();
  1001. if (ac instanceof AccessibleComponent) {
  1002. return ((AccessibleComponent) ac).isFocusTraversable();
  1003. } else {
  1004. Component c = getCurrentComponent();
  1005. if (c != null) {
  1006. return c.isFocusTraversable();
  1007. } else {
  1008. return false;
  1009. }
  1010. }
  1011. }
  1012. public void requestFocus() {
  1013. AccessibleContext ac = getCurrentAccessibleContext();
  1014. if (ac instanceof AccessibleComponent) {
  1015. ((AccessibleComponent) ac).requestFocus();
  1016. } else {
  1017. Component c = getCurrentComponent();
  1018. if (c != null) {
  1019. c.requestFocus();
  1020. }
  1021. }
  1022. }
  1023. public void addFocusListener(FocusListener l) {
  1024. AccessibleContext ac = getCurrentAccessibleContext();
  1025. if (ac instanceof AccessibleComponent) {
  1026. ((AccessibleComponent) ac).addFocusListener(l);
  1027. } else {
  1028. Component c = getCurrentComponent();
  1029. if (c != null) {
  1030. c.addFocusListener(l);
  1031. }
  1032. }
  1033. }
  1034. public void removeFocusListener(FocusListener l) {
  1035. AccessibleContext ac = getCurrentAccessibleContext();
  1036. if (ac instanceof AccessibleComponent) {
  1037. ((AccessibleComponent) ac).removeFocusListener(l);
  1038. } else {
  1039. Component c = getCurrentComponent();
  1040. if (c != null) {
  1041. c.removeFocusListener(l);
  1042. }
  1043. }
  1044. }
  1045. } // inner class AccessibleJTableHeaderElement
  1046. } // inner class AccessibleJTableHeader
  1047. } // End of Class JTableHeader