1. /*
  2. * @(#)TableColumn.java 1.60 04/05/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.table;
  8. import javax.swing.*;
  9. import javax.swing.border.*;
  10. import javax.swing.event.SwingPropertyChangeSupport;
  11. import java.lang.Integer;
  12. import java.awt.Color;
  13. import java.awt.Component;
  14. import java.io.Serializable;
  15. import java.beans.PropertyChangeEvent;
  16. import java.beans.PropertyChangeListener;
  17. /**
  18. * A <code>TableColumn</code> represents all the attributes of a column in a
  19. * <code>JTable</code>, such as width, resizibility, minimum and maximum width.
  20. * In addition, the <code>TableColumn</code> provides slots for a renderer and
  21. * an editor that can be used to display and edit the values in this column.
  22. * <p>
  23. * It is also possible to specify renderers and editors on a per type basis
  24. * rather than a per column basis - see the
  25. * <code>setDefaultRenderer</code> method in the <code>JTable</code> class.
  26. * This default mechanism is only used when the renderer (or
  27. * editor) in the <code>TableColumn</code> is <code>null</code>.
  28. * <p>
  29. * The <code>TableColumn</code> stores the link between the columns in the
  30. * <code>JTable</code> and the columns in the <code>TableModel</code>.
  31. * The <code>modelIndex</code> is the column in the
  32. * <code>TableModel</code>, which will be queried for the data values for the
  33. * cells in this column. As the column moves around in the view this
  34. * <code>modelIndex</code> does not change.
  35. * <p>
  36. * <b>Note:</b> Some implementations may assume that all
  37. * <code>TableColumnModel</code>s are unique, therefore we would
  38. * recommend that the same <code>TableColumn</code> instance
  39. * not be added more than once to a <code>TableColumnModel</code>.
  40. * To show <code>TableColumn</code>s with the same column of
  41. * data from the model, create a new instance with the same
  42. * <code>modelIndex</code>.
  43. * <p>
  44. * <strong>Warning:</strong>
  45. * Serialized objects of this class will not be compatible with
  46. * future Swing releases. The current serialization support is
  47. * appropriate for short term storage or RMI between applications running
  48. * the same version of Swing. As of 1.4, support for long term storage
  49. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  50. * has been added to the <code>java.beans</code> package.
  51. * Please see {@link java.beans.XMLEncoder}.
  52. *
  53. * @version 1.60 05/18/04
  54. * @author Alan Chung
  55. * @author Philip Milne
  56. * @see javax.swing.table.TableColumnModel
  57. *
  58. * @see javax.swing.table.DefaultTableColumnModel
  59. * @see javax.swing.table.JTableHeader#getDefaultRenderer()
  60. * @see JTable#getDefaultRenderer(Class)
  61. * @see JTable#getDefaultEditor(Class)
  62. * @see JTable#getCellRenderer(int, int)
  63. * @see JTable#getCellEditor(int, int)
  64. */
  65. public class TableColumn extends Object implements Serializable {
  66. /**
  67. * Obsolete as of Java 2 platform v1.3. Please use string literals to identify
  68. * properties.
  69. */
  70. /*
  71. * Warning: The value of this constant, "columWidth" is wrong as the
  72. * name of the property is "columnWidth".
  73. */
  74. public final static String COLUMN_WIDTH_PROPERTY = "columWidth";
  75. /**
  76. * Obsolete as of Java 2 platform v1.3. Please use string literals to identify
  77. * properties.
  78. */
  79. public final static String HEADER_VALUE_PROPERTY = "headerValue";
  80. /**
  81. * Obsolete as of Java 2 platform v1.3. Please use string literals to identify
  82. * properties.
  83. */
  84. public final static String HEADER_RENDERER_PROPERTY = "headerRenderer";
  85. /**
  86. * Obsolete as of Java 2 platform v1.3. Please use string literals to identify
  87. * properties.
  88. */
  89. public final static String CELL_RENDERER_PROPERTY = "cellRenderer";
  90. //
  91. // Instance Variables
  92. //
  93. /**
  94. * The index of the column in the model which is to be displayed by
  95. * this <code>TableColumn</code>. As columns are moved around in the
  96. * view <code>modelIndex</code> remains constant.
  97. */
  98. protected int modelIndex;
  99. /**
  100. * This object is not used internally by the drawing machinery of
  101. * the <code>JTable</code> identifiers may be set in the
  102. * <code>TableColumn</code> as as an
  103. * optional way to tag and locate table columns. The table package does
  104. * not modify or invoke any methods in these identifier objects other
  105. * than the <code>equals</code> method which is used in the
  106. * <code>getColumnIndex()</code> method in the
  107. * <code>DefaultTableColumnModel</code>.
  108. */
  109. protected Object identifier;
  110. /** The width of the column. */
  111. protected int width;
  112. /** The minimum width of the column. */
  113. protected int minWidth;
  114. /** The preferred width of the column. */
  115. private int preferredWidth;
  116. /** The maximum width of the column. */
  117. protected int maxWidth;
  118. /** The renderer used to draw the header of the column. */
  119. protected TableCellRenderer headerRenderer;
  120. /** The header value of the column. */
  121. protected Object headerValue;
  122. /** The renderer used to draw the data cells of the column. */
  123. protected TableCellRenderer cellRenderer;
  124. /** The editor used to edit the data cells of the column. */
  125. protected TableCellEditor cellEditor;
  126. /** If true, the user is allowed to resize the column; the default is true. */
  127. protected boolean isResizable;
  128. /**
  129. * This field was not used in previous releases and there are
  130. * currently no plans to support it in the future.
  131. *
  132. * @deprecated as of Java 2 platform v1.3
  133. */
  134. /*
  135. * Counter used to disable posting of resizing notifications until the
  136. * end of the resize.
  137. */
  138. @Deprecated
  139. transient protected int resizedPostingDisableCount;
  140. /**
  141. * If any <code>PropertyChangeListeners</code> have been registered, the
  142. * <code>changeSupport</code> field describes them.
  143. */
  144. private SwingPropertyChangeSupport changeSupport;
  145. //
  146. // Constructors
  147. //
  148. /**
  149. * Cover method, using a default model index of 0,
  150. * default width of 75, a <code>null</code> renderer and a
  151. * <code>null</code> editor.
  152. * This method is intended for serialization.
  153. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  154. */
  155. public TableColumn() {
  156. this(0);
  157. }
  158. /**
  159. * Cover method, using a default width of 75, a <code>null</code>
  160. * renderer and a <code>null</code> editor.
  161. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  162. */
  163. public TableColumn(int modelIndex) {
  164. this(modelIndex, 75, null, null);
  165. }
  166. /**
  167. * Cover method, using a <code>null</code> renderer and a
  168. * <code>null</code> editor.
  169. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  170. */
  171. public TableColumn(int modelIndex, int width) {
  172. this(modelIndex, width, null, null);
  173. }
  174. /**
  175. * Creates and initializes an instance of
  176. * <code>TableColumn</code> with <code>modelIndex</code>.
  177. * All <code>TableColumn</code> constructors delegate to this one.
  178. * The <code>modelIndex</code> is the index of the column
  179. * in the model which will supply the data for this column in the table.
  180. * The <code>modelIndex</code> does not change as the columns are reordered
  181. * in the view. The width parameter is used to set both the
  182. * <code>preferredWidth</code> for this
  183. * column and the initial width. The renderer and editor are the objects
  184. * used respectively to render and edit values in this column. When
  185. * these are <code>null</code>, default values, provided by the
  186. * <code>getDefaultRenderer</code>
  187. * and <code>getDefaultEditor</code> methods in the
  188. * <code>JTable</code> class are used to
  189. * provide defaults based on the type of the data in this column.
  190. * This column-centric rendering strategy can be circumvented by overriding
  191. * the <code>getCellRenderer</code> methods in the <code>JTable</code>.
  192. * <p>
  193. *
  194. * @see JTable#getDefaultRenderer(Class)
  195. * @see JTable#getDefaultEditor(Class)
  196. * @see JTable#getCellRenderer(int, int)
  197. * @see JTable#getCellEditor(int, int)
  198. */
  199. public TableColumn(int modelIndex, int width,
  200. TableCellRenderer cellRenderer,
  201. TableCellEditor cellEditor) {
  202. super();
  203. this.modelIndex = modelIndex;
  204. this.width = width;
  205. this.preferredWidth = width;
  206. this.cellRenderer = cellRenderer;
  207. this.cellEditor = cellEditor;
  208. // Set other instance variables to default values.
  209. minWidth = 15;
  210. maxWidth = Integer.MAX_VALUE;
  211. isResizable = true;
  212. resizedPostingDisableCount = 0;
  213. headerValue = null;
  214. }
  215. //
  216. // Modifying and Querying attributes
  217. //
  218. private void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
  219. if (changeSupport != null) {
  220. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  221. }
  222. }
  223. private void firePropertyChange(String propertyName, int oldValue, int newValue) {
  224. if (oldValue != newValue) {
  225. firePropertyChange(propertyName, new Integer(oldValue), new Integer(newValue));
  226. }
  227. }
  228. private void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
  229. if (oldValue != newValue) {
  230. firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
  231. }
  232. }
  233. /**
  234. * Sets the model index for this column. The model index is the
  235. * index of the column in the model that will be displayed by this
  236. * <code>TableColumn</code>. As the <code>TableColumn</code>
  237. * is moved around in the view the model index remains constant.
  238. * @param modelIndex the new modelIndex
  239. * @beaninfo
  240. * bound: true
  241. * description: The model index.
  242. */
  243. public void setModelIndex(int modelIndex) {
  244. int old = this.modelIndex;
  245. this.modelIndex = modelIndex;
  246. firePropertyChange("modelIndex", old, modelIndex);
  247. }
  248. /**
  249. * Returns the model index for this column.
  250. * @return the <code>modelIndex</code> property
  251. */
  252. public int getModelIndex() {
  253. return modelIndex;
  254. }
  255. /**
  256. * Sets the <code>TableColumn</code>'s identifier to
  257. * <code>anIdentifier</code>. <p>
  258. * Note: identifiers are not used by the <code>JTable</code>,
  259. * they are purely a
  260. * convenience for the external tagging and location of columns.
  261. *
  262. * @param identifier an identifier for this column
  263. * @see #getIdentifier
  264. * @beaninfo
  265. * bound: true
  266. * description: A unique identifier for this column.
  267. */
  268. public void setIdentifier(Object identifier) {
  269. Object old = this.identifier;
  270. this.identifier = identifier;
  271. firePropertyChange("identifier", old, identifier);
  272. }
  273. /**
  274. * Returns the <code>identifier</code> object for this column.
  275. * Note identifiers are not used by <code>JTable</code>,
  276. * they are purely a convenience for external use.
  277. * If the <code>identifier</code> is <code>null</code>,
  278. * <code>getIdentifier()</code> returns <code>getHeaderValue</code>
  279. * as a default.
  280. *
  281. * @return the <code>identifier</code> property
  282. * @see #setIdentifier
  283. */
  284. public Object getIdentifier() {
  285. return (identifier != null) ? identifier : getHeaderValue();
  286. }
  287. /**
  288. * Sets the <code>Object</code> whose string representation will be
  289. * used as the value for the <code>headerRenderer</code>. When the
  290. * <code>TableColumn</code> is created, the default <code>headerValue</code>
  291. * is <code>null</code>.
  292. * @param headerValue the new headerValue
  293. * @see #getHeaderValue
  294. * @beaninfo
  295. * bound: true
  296. * description: The text to be used by the header renderer.
  297. */
  298. public void setHeaderValue(Object headerValue) {
  299. Object old = this.headerValue;
  300. this.headerValue = headerValue;
  301. firePropertyChange("headerValue", old, headerValue);
  302. }
  303. /**
  304. * Returns the <code>Object</code> used as the value for the header
  305. * renderer.
  306. *
  307. * @return the <code>headerValue</code> property
  308. * @see #setHeaderValue
  309. */
  310. public Object getHeaderValue() {
  311. return headerValue;
  312. }
  313. //
  314. // Renderers and Editors
  315. //
  316. /**
  317. * Sets the <code>TableCellRenderer</code> used to draw the
  318. * <code>TableColumn</code>'s header to <code>headerRenderer</code>.
  319. *
  320. * @param headerRenderer the new headerRenderer
  321. *
  322. * @see #getHeaderRenderer
  323. * @beaninfo
  324. * bound: true
  325. * description: The header renderer.
  326. */
  327. public void setHeaderRenderer(TableCellRenderer headerRenderer) {
  328. TableCellRenderer old = this.headerRenderer;
  329. this.headerRenderer = headerRenderer;
  330. firePropertyChange("headerRenderer", old, headerRenderer);
  331. }
  332. /**
  333. * Returns the <code>TableCellRenderer</code> used to draw the header of the
  334. * <code>TableColumn</code>. When the <code>headerRenderer</code> is
  335. * <code>null</code>, the <code>JTableHeader</code>
  336. * uses its <code>defaultRenderer</code>. The default value for a
  337. * <code>headerRenderer</code> is <code>null</code>.
  338. *
  339. * @return the <code>headerRenderer</code> property
  340. * @see #setHeaderRenderer
  341. * @see #setHeaderValue
  342. * @see javax.swing.table.JTableHeader#getDefaultRenderer()
  343. */
  344. public TableCellRenderer getHeaderRenderer() {
  345. return headerRenderer;
  346. }
  347. /**
  348. * Sets the <code>TableCellRenderer</code> used by <code>JTable</code>
  349. * to draw individual values for this column.
  350. *
  351. * @param cellRenderer the new cellRenderer
  352. * @see #getCellRenderer
  353. * @beaninfo
  354. * bound: true
  355. * description: The renderer to use for cell values.
  356. */
  357. public void setCellRenderer(TableCellRenderer cellRenderer) {
  358. TableCellRenderer old = this.cellRenderer;
  359. this.cellRenderer = cellRenderer;
  360. firePropertyChange("cellRenderer", old, cellRenderer);
  361. }
  362. /**
  363. * Returns the <code>TableCellRenderer</code> used by the
  364. * <code>JTable</code> to draw
  365. * values for this column. The <code>cellRenderer</code> of the column
  366. * not only controls the visual look for the column, but is also used to
  367. * interpret the value object supplied by the <code>TableModel</code>.
  368. * When the <code>cellRenderer</code> is <code>null</code>,
  369. * the <code>JTable</code> uses a default renderer based on the
  370. * class of the cells in that column. The default value for a
  371. * <code>cellRenderer</code> is <code>null</code>.
  372. *
  373. * @return the <code>cellRenderer</code> property
  374. * @see #setCellRenderer
  375. * @see JTable#setDefaultRenderer
  376. */
  377. public TableCellRenderer getCellRenderer() {
  378. return cellRenderer;
  379. }
  380. /**
  381. * Sets the editor to used by when a cell in this column is edited.
  382. *
  383. * @param cellEditor the new cellEditor
  384. * @see #getCellEditor
  385. * @beaninfo
  386. * bound: true
  387. * description: The editor to use for cell values.
  388. */
  389. public void setCellEditor(TableCellEditor cellEditor){
  390. TableCellEditor old = this.cellEditor;
  391. this.cellEditor = cellEditor;
  392. firePropertyChange("cellEditor", old, cellEditor);
  393. }
  394. /**
  395. * Returns the <code>TableCellEditor</code> used by the
  396. * <code>JTable</code> to edit values for this column. When the
  397. * <code>cellEditor</code> is <code>null</code>, the <code>JTable</code>
  398. * uses a default editor based on the
  399. * class of the cells in that column. The default value for a
  400. * <code>cellEditor</code> is <code>null</code>.
  401. *
  402. * @return the <code>cellEditor</code> property
  403. * @see #setCellEditor
  404. * @see JTable#setDefaultEditor
  405. */
  406. public TableCellEditor getCellEditor() {
  407. return cellEditor;
  408. }
  409. /**
  410. * This method should not be used to set the widths of columns in the
  411. * <code>JTable</code>, use <code>setPreferredWidth</code> instead.
  412. * Like a layout manager in the
  413. * AWT, the <code>JTable</code> adjusts a column's width automatically
  414. * whenever the
  415. * table itself changes size, or a column's preferred width is changed.
  416. * Setting widths programmatically therefore has no long term effect.
  417. * <p>
  418. * This method sets this column's width to <code>width</code>.
  419. * If <code>width</code> exceeds the minimum or maximum width,
  420. * it is adjusted to the appropriate limiting value.
  421. * <p>
  422. * @param width the new width
  423. * @see #getWidth
  424. * @see #setMinWidth
  425. * @see #setMaxWidth
  426. * @see #setPreferredWidth
  427. * @see JTable#sizeColumnsToFit(int)
  428. * @beaninfo
  429. * bound: true
  430. * description: The width of the column.
  431. */
  432. public void setWidth(int width) {
  433. int old = this.width;
  434. this.width = Math.min(Math.max(width, minWidth), maxWidth);
  435. firePropertyChange("width", old, this.width);
  436. }
  437. /**
  438. * Returns the width of the <code>TableColumn</code>. The default width is
  439. * 75.
  440. *
  441. * @return the <code>width</code> property
  442. * @see #setWidth
  443. */
  444. public int getWidth() {
  445. return width;
  446. }
  447. /**
  448. * Sets this column's preferred width to <code>preferredWidth</code>.
  449. * If <code>preferredWidth</code> exceeds the minimum or maximum width,
  450. * it is adjusted to the appropriate limiting value.
  451. * <p>
  452. * For details on how the widths of columns in the <code>JTable</code>
  453. * (and <code>JTableHeader</code>) are calculated from the
  454. * <code>preferredWidth</code>,
  455. * see the <code>doLayout</code> method in <code>JTable</code>.
  456. *
  457. * @param preferredWidth the new preferred width
  458. * @see #getPreferredWidth
  459. * @see JTable#doLayout()
  460. * @beaninfo
  461. * bound: true
  462. * description: The preferred width of the column.
  463. */
  464. public void setPreferredWidth(int preferredWidth) {
  465. int old = this.preferredWidth;
  466. this.preferredWidth = Math.min(Math.max(preferredWidth, minWidth), maxWidth);
  467. firePropertyChange("preferredWidth", old, this.preferredWidth);
  468. }
  469. /**
  470. * Returns the preferred width of the <code>TableColumn</code>.
  471. * The default preferred width is 75.
  472. *
  473. * @return the <code>preferredWidth</code> property
  474. * @see #setPreferredWidth
  475. */
  476. public int getPreferredWidth() {
  477. return preferredWidth;
  478. }
  479. /**
  480. * Sets the <code>TableColumn</code>'s minimum width to
  481. * <code>minWidth</code> also adjusts the current width
  482. * and preferred width if they are less than this value.
  483. *
  484. * @param minWidth the new minimum width
  485. * @see #getMinWidth
  486. * @see #setPreferredWidth
  487. * @see #setMaxWidth
  488. * @beaninfo
  489. * bound: true
  490. * description: The minimum width of the column.
  491. */
  492. public void setMinWidth(int minWidth) {
  493. int old = this.minWidth;
  494. this.minWidth = Math.max(minWidth, 0);
  495. if (width < minWidth) {
  496. setWidth(minWidth);
  497. }
  498. if (preferredWidth < minWidth) {
  499. setPreferredWidth(minWidth);
  500. }
  501. firePropertyChange("minWidth", old, this.minWidth);
  502. }
  503. /**
  504. * Returns the minimum width for the <code>TableColumn</code>. The
  505. * <code>TableColumn</code>'s width can't be made less than this either
  506. * by the user or programmatically. The default minWidth is 15.
  507. *
  508. * @return the <code>minWidth</code> property
  509. * @see #setMinWidth
  510. */
  511. public int getMinWidth() {
  512. return minWidth;
  513. }
  514. /**
  515. * Sets the <code>TableColumn</code>'s maximum width to
  516. * <code>maxWidth</code> also adjusts the width and preferred
  517. * width if they are greater than this value.
  518. *
  519. * @param maxWidth the new maximum width
  520. * @see #getMaxWidth
  521. * @see #setPreferredWidth
  522. * @see #setMinWidth
  523. * @beaninfo
  524. * bound: true
  525. * description: The maximum width of the column.
  526. */
  527. public void setMaxWidth(int maxWidth) {
  528. int old = this.maxWidth;
  529. this.maxWidth = Math.max(minWidth, maxWidth);
  530. if (width > maxWidth) {
  531. setWidth(maxWidth);
  532. }
  533. if (preferredWidth > maxWidth) {
  534. setPreferredWidth(maxWidth);
  535. }
  536. firePropertyChange("maxWidth", old, this.maxWidth);
  537. }
  538. /**
  539. * Returns the maximum width for the <code>TableColumn</code>. The
  540. * <code>TableColumn</code>'s width can't be made larger than this
  541. * either by the user or programmatically. The default maxWidth
  542. * is Integer.MAX_VALUE.
  543. *
  544. * @return the <code>maxWidth</code> property
  545. * @see #setMaxWidth
  546. */
  547. public int getMaxWidth() {
  548. return maxWidth;
  549. }
  550. /**
  551. * Sets whether this column can be resized.
  552. *
  553. * @param isResizable if true, resizing is allowed; otherwise false
  554. * @see #getResizable
  555. * @beaninfo
  556. * bound: true
  557. * description: Whether or not this column can be resized.
  558. */
  559. public void setResizable(boolean isResizable) {
  560. boolean old = this.isResizable;
  561. this.isResizable = isResizable;
  562. firePropertyChange("isResizable", old, this.isResizable);
  563. }
  564. /**
  565. * Returns true if the user is allowed to resize the
  566. * <code>TableColumn</code>'s
  567. * width, false otherwise. You can change the width programmatically
  568. * regardless of this setting. The default is true.
  569. *
  570. * @return the <code>isResizable</code> property
  571. * @see #setResizable
  572. */
  573. public boolean getResizable() {
  574. return isResizable;
  575. }
  576. /**
  577. * Resizes the <code>TableColumn</code> to fit the width of its header cell.
  578. * This method does nothing if the header renderer is <code>null</code>
  579. * (the default case). Otherwise, it sets the minimum, maximum and preferred
  580. * widths of this column to the widths of the minimum, maximum and preferred
  581. * sizes of the Component delivered by the header renderer.
  582. * The transient "width" property of this TableColumn is also set to the
  583. * preferred width. Note this method is not used internally by the table
  584. * package.
  585. *
  586. * @see #setPreferredWidth
  587. */
  588. public void sizeWidthToFit() {
  589. if (headerRenderer == null) {
  590. return;
  591. }
  592. Component c = headerRenderer.getTableCellRendererComponent(null,
  593. getHeaderValue(), false, false, 0, 0);
  594. setMinWidth(c.getMinimumSize().width);
  595. setMaxWidth(c.getMaximumSize().width);
  596. setPreferredWidth(c.getPreferredSize().width);
  597. setWidth(getPreferredWidth());
  598. }
  599. /**
  600. * This field was not used in previous releases and there are
  601. * currently no plans to support it in the future.
  602. *
  603. * @deprecated as of Java 2 platform v1.3
  604. */
  605. @Deprecated
  606. public void disableResizedPosting() {
  607. resizedPostingDisableCount++;
  608. }
  609. /**
  610. * This field was not used in previous releases and there are
  611. * currently no plans to support it in the future.
  612. *
  613. * @deprecated as of Java 2 platform v1.3
  614. */
  615. @Deprecated
  616. public void enableResizedPosting() {
  617. resizedPostingDisableCount--;
  618. }
  619. //
  620. // Property Change Support
  621. //
  622. /**
  623. * Adds a <code>PropertyChangeListener</code> to the listener list.
  624. * The listener is registered for all properties.
  625. * <p>
  626. * A <code>PropertyChangeEvent</code> will get fired in response to an
  627. * explicit call to <code>setFont</code>, <code>setBackground</code>,
  628. * or <code>setForeground</code> on the
  629. * current component. Note that if the current component is
  630. * inheriting its foreground, background, or font from its
  631. * container, then no event will be fired in response to a
  632. * change in the inherited property.
  633. *
  634. * @param listener the listener to be added
  635. *
  636. */
  637. public synchronized void addPropertyChangeListener(
  638. PropertyChangeListener listener) {
  639. if (changeSupport == null) {
  640. changeSupport = new SwingPropertyChangeSupport(this);
  641. }
  642. changeSupport.addPropertyChangeListener(listener);
  643. }
  644. /**
  645. * Removes a <code>PropertyChangeListener</code> from the listener list.
  646. * The <code>PropertyChangeListener</code> to be removed was registered
  647. * for all properties.
  648. *
  649. * @param listener the listener to be removed
  650. *
  651. */
  652. public synchronized void removePropertyChangeListener(
  653. PropertyChangeListener listener) {
  654. if (changeSupport != null) {
  655. changeSupport.removePropertyChangeListener(listener);
  656. }
  657. }
  658. /**
  659. * Returns an array of all the <code>PropertyChangeListener</code>s added
  660. * to this TableColumn with addPropertyChangeListener().
  661. *
  662. * @return all of the <code>PropertyChangeListener</code>s added or an empty
  663. * array if no listeners have been added
  664. * @since 1.4
  665. */
  666. public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
  667. if (changeSupport == null) {
  668. return new PropertyChangeListener[0];
  669. }
  670. return changeSupport.getPropertyChangeListeners();
  671. }
  672. //
  673. // Protected Methods
  674. //
  675. /**
  676. * As of Java 2 platform v1.3, this method is not called by the <code>TableColumn</code>
  677. * constructor. Previously this method was used by the
  678. * <code>TableColumn</code> to create a default header renderer.
  679. * As of Java 2 platform v1.3, the default header renderer is <code>null</code>.
  680. * <code>JTableHeader</code> now provides its own shared default
  681. * renderer, just as the <code>JTable</code> does for its cell renderers.
  682. *
  683. * @return the default header renderer
  684. * @see javax.swing.table.JTableHeader#createDefaultRenderer()
  685. */
  686. protected TableCellRenderer createDefaultHeaderRenderer() {
  687. DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
  688. public Component getTableCellRendererComponent(JTable table, Object value,
  689. boolean isSelected, boolean hasFocus, int row, int column) {
  690. if (table != null) {
  691. JTableHeader header = table.getTableHeader();
  692. if (header != null) {
  693. setForeground(header.getForeground());
  694. setBackground(header.getBackground());
  695. setFont(header.getFont());
  696. }
  697. }
  698. setText((value == null) ? "" : value.toString());
  699. setBorder(UIManager.getBorder("TableHeader.cellBorder"));
  700. return this;
  701. }
  702. };
  703. label.setHorizontalAlignment(JLabel.CENTER);
  704. return label;
  705. }
  706. } // End of class TableColumn