1. /*
  2. * @(#)TableColumn.java 1.57 03/01/23
  3. *
  4. * Copyright 2003 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.57 01/23/03
  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. transient protected int resizedPostingDisableCount;
  139. /**
  140. * If any <code>PropertyChangeListeners</code> have been registered, the
  141. * <code>changeSupport</code> field describes them.
  142. */
  143. private SwingPropertyChangeSupport changeSupport;
  144. //
  145. // Constructors
  146. //
  147. /**
  148. * Cover method, using a default model index of 0,
  149. * default width of 75, a <code>null</code> renderer and a
  150. * <code>null</code> editor.
  151. * This method is intended for serialization.
  152. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  153. */
  154. public TableColumn() {
  155. this(0);
  156. }
  157. /**
  158. * Cover method, using a default width of 75, a <code>null</code>
  159. * renderer and a <code>null</code> editor.
  160. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  161. */
  162. public TableColumn(int modelIndex) {
  163. this(modelIndex, 75, null, null);
  164. }
  165. /**
  166. * Cover method, using a <code>null</code> renderer and a
  167. * <code>null</code> editor.
  168. * @see #TableColumn(int, int, TableCellRenderer, TableCellEditor)
  169. */
  170. public TableColumn(int modelIndex, int width) {
  171. this(modelIndex, width, null, null);
  172. }
  173. /**
  174. * Creates and initializes an instance of
  175. * <code>TableColumn</code> with <code>modelIndex</code>.
  176. * All <code>TableColumn</code> constructors delegate to this one.
  177. * The <code>modelIndex</code> is the index of the column
  178. * in the model which will supply the data for this column in the table.
  179. * The <code>modelIndex</code> does not change as the columns are reordered
  180. * in the view. The width parameter is used to set both the
  181. * <code>preferredWidth</code> for this
  182. * column and the initial width. The renderer and editor are the objects
  183. * used respectively to render and edit values in this column. When
  184. * these are <code>null</code>, default values, provided by the
  185. * <code>getDefaultRenderer</code>
  186. * and <code>getDefaultEditor</code> methods in the
  187. * <code>JTable</code> class are used to
  188. * provide defaults based on the type of the data in this column.
  189. * This column-centric rendering strategy can be circumvented by overriding
  190. * the <code>getCellRenderer</code> methods in the <code>JTable</code>.
  191. * <p>
  192. *
  193. * @see JTable#getDefaultRenderer(Class)
  194. * @see JTable#getDefaultEditor(Class)
  195. * @see JTable#getCellRenderer(int, int)
  196. * @see JTable#getCellEditor(int, int)
  197. */
  198. public TableColumn(int modelIndex, int width,
  199. TableCellRenderer cellRenderer,
  200. TableCellEditor cellEditor) {
  201. super();
  202. this.modelIndex = modelIndex;
  203. this.width = width;
  204. this.preferredWidth = width;
  205. this.cellRenderer = cellRenderer;
  206. this.cellEditor = cellEditor;
  207. // Set other instance variables to default values.
  208. minWidth = 15;
  209. maxWidth = Integer.MAX_VALUE;
  210. isResizable = true;
  211. resizedPostingDisableCount = 0;
  212. headerValue = null;
  213. }
  214. //
  215. // Modifying and Querying attributes
  216. //
  217. private void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
  218. if (changeSupport != null) {
  219. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  220. }
  221. }
  222. private void firePropertyChange(String propertyName, int oldValue, int newValue) {
  223. if (oldValue != newValue) {
  224. firePropertyChange(propertyName, new Integer(oldValue), new Integer(newValue));
  225. }
  226. }
  227. private void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
  228. if (oldValue != newValue) {
  229. firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
  230. }
  231. }
  232. /**
  233. * Sets the model index for this column. The model index is the
  234. * index of the column in the model that will be displayed by this
  235. * <code>TableColumn</code>. As the <code>TableColumn</code>
  236. * is moved around in the view the model index remains constant.
  237. * @param modelIndex the new modelIndex
  238. * @beaninfo
  239. * bound: true
  240. * description: The model index.
  241. */
  242. public void setModelIndex(int modelIndex) {
  243. int old = this.modelIndex;
  244. this.modelIndex = modelIndex;
  245. firePropertyChange("modelIndex", old, modelIndex);
  246. }
  247. /**
  248. * Returns the model index for this column.
  249. * @return the <code>modelIndex</code> property
  250. */
  251. public int getModelIndex() {
  252. return modelIndex;
  253. }
  254. /**
  255. * Sets the <code>TableColumn</code>'s identifier to
  256. * <code>anIdentifier</code>. <p>
  257. * Note: identifiers are not used by the <code>JTable</code>,
  258. * they are purely a
  259. * convenience for the external tagging and location of columns.
  260. *
  261. * @param identifier an identifier for this column
  262. * @see #getIdentifier
  263. * @beaninfo
  264. * bound: true
  265. * description: A unique identifier for this column.
  266. */
  267. public void setIdentifier(Object identifier) {
  268. Object old = this.identifier;
  269. this.identifier = identifier;
  270. firePropertyChange("identifier", old, identifier);
  271. }
  272. /**
  273. * Returns the <code>identifier</code> object for this column.
  274. * Note identifiers are not used by <code>JTable</code>,
  275. * they are purely a convenience for external use.
  276. * If the <code>identifier</code> is <code>null</code>,
  277. * <code>getIdentifier()</code> returns <code>getHeaderValue</code>
  278. * as a default.
  279. *
  280. * @return the <code>identifier</code> property
  281. * @see #setIdentifier
  282. */
  283. public Object getIdentifier() {
  284. return (identifier != null) ? identifier : getHeaderValue();
  285. }
  286. /**
  287. * Sets the <code>Object</code> whose string representation will be
  288. * used as the value for the <code>headerRenderer</code>. When the
  289. * <code>TableColumn</code> is created, the default <code>headerValue</code>
  290. * is <code>null</code>.
  291. * @param headerValue the new headerValue
  292. * @see #getHeaderValue
  293. * @beaninfo
  294. * bound: true
  295. * description: The text to be used by the header renderer.
  296. */
  297. public void setHeaderValue(Object headerValue) {
  298. Object old = this.headerValue;
  299. this.headerValue = headerValue;
  300. firePropertyChange("headerValue", old, headerValue);
  301. }
  302. /**
  303. * Returns the <code>Object</code> used as the value for the header
  304. * renderer.
  305. *
  306. * @return the <code>headerValue</code> property
  307. * @see #setHeaderValue
  308. */
  309. public Object getHeaderValue() {
  310. return headerValue;
  311. }
  312. //
  313. // Renderers and Editors
  314. //
  315. /**
  316. * Sets the <code>TableCellRenderer</code> used to draw the
  317. * <code>TableColumn</code>'s header to <code>headerRenderer</code>.
  318. *
  319. * @param headerRenderer the new headerRenderer
  320. *
  321. * @see #getHeaderRenderer
  322. * @beaninfo
  323. * bound: true
  324. * description: The header renderer.
  325. */
  326. public void setHeaderRenderer(TableCellRenderer headerRenderer) {
  327. TableCellRenderer old = this.headerRenderer;
  328. this.headerRenderer = headerRenderer;
  329. firePropertyChange("headerRenderer", old, headerRenderer);
  330. }
  331. /**
  332. * Returns the <code>TableCellRenderer</code> used to draw the header of the
  333. * <code>TableColumn</code>. When the <code>headerRenderer</code> is
  334. * <code>null</code>, the <code>JTableHeader</code>
  335. * uses its <code>defaultRenderer</code>. The default value for a
  336. * <code>headerRenderer</code> is <code>null</code>.
  337. *
  338. * @return the <code>headerRenderer</code> property
  339. * @see #setHeaderRenderer
  340. * @see #setHeaderValue
  341. * @see javax.swing.table.JTableHeader#getDefaultRenderer()
  342. */
  343. public TableCellRenderer getHeaderRenderer() {
  344. return headerRenderer;
  345. }
  346. /**
  347. * Sets the <code>TableCellRenderer</code> used by <code>JTable</code>
  348. * to draw individual values for this column.
  349. *
  350. * @param cellRenderer the new cellRenderer
  351. * @see #getCellRenderer
  352. * @beaninfo
  353. * bound: true
  354. * description: The renderer to use for cell values.
  355. */
  356. public void setCellRenderer(TableCellRenderer cellRenderer) {
  357. TableCellRenderer old = this.cellRenderer;
  358. this.cellRenderer = cellRenderer;
  359. firePropertyChange("cellRenderer", old, cellRenderer);
  360. }
  361. /**
  362. * Returns the <code>TableCellRenderer</code> used by the
  363. * <code>JTable</code> to draw
  364. * values for this column. The <code>cellRenderer</code> of the column
  365. * not only controls the visual look for the column, but is also used to
  366. * interpret the value object supplied by the <code>TableModel</code>.
  367. * When the <code>cellRenderer</code> is <code>null</code>,
  368. * the <code>JTable</code> uses a default renderer based on the
  369. * class of the cells in that column. The default value for a
  370. * <code>cellRenderer</code> is <code>null</code>.
  371. *
  372. * @return the <code>cellRenderer</code> property
  373. * @see #setCellRenderer
  374. * @see JTable#setDefaultRenderer
  375. */
  376. public TableCellRenderer getCellRenderer() {
  377. return cellRenderer;
  378. }
  379. /**
  380. * Sets the editor to used by when a cell in this column is edited.
  381. *
  382. * @param cellEditor the new cellEditor
  383. * @see #getCellEditor
  384. * @beaninfo
  385. * bound: true
  386. * description: The editor to use for cell values.
  387. */
  388. public void setCellEditor(TableCellEditor cellEditor){
  389. TableCellEditor old = this.cellEditor;
  390. this.cellEditor = cellEditor;
  391. firePropertyChange("cellEditor", old, cellEditor);
  392. }
  393. /**
  394. * Returns the <code>TableCellEditor</code> used by the
  395. * <code>JTable</code> to edit values for this column. When the
  396. * <code>cellEditor</code> is <code>null</code>, the <code>JTable</code>
  397. * uses a default editor based on the
  398. * class of the cells in that column. The default value for a
  399. * <code>cellEditor</code> is <code>null</code>.
  400. *
  401. * @return the <code>cellEditor</code> property
  402. * @see #setCellEditor
  403. * @see JTable#setDefaultEditor
  404. */
  405. public TableCellEditor getCellEditor() {
  406. return cellEditor;
  407. }
  408. /**
  409. * This method should not be used to set the widths of columns in the
  410. * <code>JTable</code>, use <code>setPreferredWidth</code> instead.
  411. * Like a layout manager in the
  412. * AWT, the <code>JTable</code> adjusts a column's width automatically
  413. * whenever the
  414. * table itself changes size, or a column's preferred width is changed.
  415. * Setting widths programmatically therefore has no long term effect.
  416. * <p>
  417. * This method sets this column's width to <code>width</code>.
  418. * If <code>width</code> exceeds the minimum or maximum width,
  419. * it is adjusted to the appropriate limiting value.
  420. * <p>
  421. * @param width the new width
  422. * @see #getWidth
  423. * @see #setMinWidth
  424. * @see #setMaxWidth
  425. * @see #setPreferredWidth
  426. * @see JTable#sizeColumnsToFit(int)
  427. * @beaninfo
  428. * bound: true
  429. * description: The width of the column.
  430. */
  431. public void setWidth(int width) {
  432. int old = this.width;
  433. this.width = Math.min(Math.max(width, minWidth), maxWidth);
  434. firePropertyChange("width", old, this.width);
  435. }
  436. /**
  437. * Returns the width of the <code>TableColumn</code>. The default width is
  438. * 75.
  439. *
  440. * @return the <code>width</code> property
  441. * @see #setWidth
  442. */
  443. public int getWidth() {
  444. return width;
  445. }
  446. /**
  447. * Sets this column's preferred width to <code>preferredWidth</code>.
  448. * If <code>preferredWidth</code> exceeds the minimum or maximum width,
  449. * it is adjusted to the appropriate limiting value.
  450. * <p>
  451. * For details on how the widths of columns in the <code>JTable</code>
  452. * (and <code>JTableHeader</code>) are calculated from the
  453. * <code>preferredWidth</code>,
  454. * see the <code>sizeColumnsToFit</code> method in <code>JTable</code>.
  455. *
  456. * @param preferredWidth the new preferred width
  457. * @see #getPreferredWidth
  458. * @see JTable#sizeColumnsToFit(int)
  459. * @beaninfo
  460. * bound: true
  461. * description: The preferred width of the column.
  462. */
  463. public void setPreferredWidth(int preferredWidth) {
  464. int old = this.preferredWidth;
  465. this.preferredWidth = Math.min(Math.max(preferredWidth, minWidth), maxWidth);
  466. firePropertyChange("preferredWidth", old, this.preferredWidth);
  467. }
  468. /**
  469. * Returns the preferred width of the <code>TableColumn</code>.
  470. * The default preferred width is 75.
  471. *
  472. * @return the <code>preferredWidth</code> property
  473. * @see #setPreferredWidth
  474. */
  475. public int getPreferredWidth() {
  476. return preferredWidth;
  477. }
  478. /**
  479. * Sets the <code>TableColumn</code>'s minimum width to
  480. * <code>minWidth</code> also adjusts the current width
  481. * and preferred width if they are less than this value.
  482. *
  483. * @param minWidth the new minimum width
  484. * @see #getMinWidth
  485. * @see #setPreferredWidth
  486. * @see #setMaxWidth
  487. * @beaninfo
  488. * bound: true
  489. * description: The minimum width of the column.
  490. */
  491. public void setMinWidth(int minWidth) {
  492. int old = this.minWidth;
  493. this.minWidth = Math.max(minWidth, 0);
  494. if (width < minWidth) {
  495. setWidth(minWidth);
  496. }
  497. if (preferredWidth < minWidth) {
  498. setPreferredWidth(minWidth);
  499. }
  500. firePropertyChange("minWidth", old, this.minWidth);
  501. }
  502. /**
  503. * Returns the minimum width for the <code>TableColumn</code>. The
  504. * <code>TableColumn</code>'s width can't be made less than this either
  505. * by the user or programmatically. The default minWidth is 15.
  506. *
  507. * @return the <code>minWidth</code> property
  508. * @see #setMinWidth
  509. */
  510. public int getMinWidth() {
  511. return minWidth;
  512. }
  513. /**
  514. * Sets the <code>TableColumn</code>'s maximum width to
  515. * <code>maxWidth</code> also adjusts the width and preferred
  516. * width if they are greater than this value.
  517. *
  518. * @param maxWidth the new maximum width
  519. * @see #getMaxWidth
  520. * @see #setPreferredWidth
  521. * @see #setMinWidth
  522. * @beaninfo
  523. * bound: true
  524. * description: The maximum width of the column.
  525. */
  526. public void setMaxWidth(int maxWidth) {
  527. int old = this.maxWidth;
  528. this.maxWidth = Math.max(minWidth, maxWidth);
  529. if (width > maxWidth) {
  530. setWidth(maxWidth);
  531. }
  532. if (preferredWidth > maxWidth) {
  533. setPreferredWidth(maxWidth);
  534. }
  535. firePropertyChange("maxWidth", old, this.maxWidth);
  536. }
  537. /**
  538. * Returns the maximum width for the <code>TableColumn</code>. The
  539. * <code>TableColumn</code>'s width can't be made larger than this
  540. * either by the user or programmatically. The default maxWidth
  541. * is Integer.MAX_VALUE.
  542. *
  543. * @return the <code>maxWidth</code> property
  544. * @see #setMaxWidth
  545. */
  546. public int getMaxWidth() {
  547. return maxWidth;
  548. }
  549. /**
  550. * Sets whether this column can be resized.
  551. *
  552. * @param isResizable if true, resizing is allowed; otherwise false
  553. * @see #getResizable
  554. * @beaninfo
  555. * bound: true
  556. * description: Whether or not this column can be resized.
  557. */
  558. public void setResizable(boolean isResizable) {
  559. boolean old = this.isResizable;
  560. this.isResizable = isResizable;
  561. firePropertyChange("isResizable", old, this.isResizable);
  562. }
  563. /**
  564. * Returns true if the user is allowed to resize the
  565. * <code>TableColumn</code>'s
  566. * width, false otherwise. You can change the width programmatically
  567. * regardless of this setting. The default is true.
  568. *
  569. * @return the <code>isResizable</code> property
  570. * @see #setResizable
  571. */
  572. public boolean getResizable() {
  573. return isResizable;
  574. }
  575. /**
  576. * Resizes the <code>TableColumn</code> to fit the width of its header cell.
  577. * This method does nothing if the header renderer is <code>null</code>
  578. * (the default case). Otherwise, it sets the minimum, maximum and preferred
  579. * widths of this column to the widths of the minimum, maximum and preferred
  580. * sizes of the Component delivered by the header renderer.
  581. * The transient "width" property of this TableColumn is also set to the
  582. * preferred width. Note this method is not used internally by the table
  583. * package.
  584. *
  585. * @see #setPreferredWidth
  586. */
  587. public void sizeWidthToFit() {
  588. if (headerRenderer == null) {
  589. return;
  590. }
  591. Component c = headerRenderer.getTableCellRendererComponent(null,
  592. getHeaderValue(), false, false, 0, 0);
  593. setMinWidth(c.getMinimumSize().width);
  594. setMaxWidth(c.getMaximumSize().width);
  595. setPreferredWidth(c.getPreferredSize().width);
  596. setWidth(getPreferredWidth());
  597. }
  598. /**
  599. * This field was not used in previous releases and there are
  600. * currently no plans to support it in the future.
  601. *
  602. * @deprecated as of Java 2 platform v1.3
  603. */
  604. public void disableResizedPosting() {
  605. resizedPostingDisableCount++;
  606. }
  607. /**
  608. * This field was not used in previous releases and there are
  609. * currently no plans to support it in the future.
  610. *
  611. * @deprecated as of Java 2 platform v1.3
  612. */
  613. public void enableResizedPosting() {
  614. resizedPostingDisableCount--;
  615. }
  616. //
  617. // Property Change Support
  618. //
  619. /**
  620. * Adds a <code>PropertyChangeListener</code> to the listener list.
  621. * The listener is registered for all properties.
  622. * <p>
  623. * A <code>PropertyChangeEvent</code> will get fired in response to an
  624. * explicit call to <code>setFont</code>, <code>setBackground</code>,
  625. * or <code>setForeground</code> on the
  626. * current component. Note that if the current component is
  627. * inheriting its foreground, background, or font from its
  628. * container, then no event will be fired in response to a
  629. * change in the inherited property.
  630. *
  631. * @param listener the listener to be added
  632. *
  633. */
  634. public synchronized void addPropertyChangeListener(
  635. PropertyChangeListener listener) {
  636. if (changeSupport == null) {
  637. changeSupport = new SwingPropertyChangeSupport(this);
  638. }
  639. changeSupport.addPropertyChangeListener(listener);
  640. }
  641. /**
  642. * Removes a <code>PropertyChangeListener</code> from the listener list.
  643. * The <code>PropertyChangeListener</code> to be removed was registered
  644. * for all properties.
  645. *
  646. * @param listener the listener to be removed
  647. *
  648. */
  649. public synchronized void removePropertyChangeListener(
  650. PropertyChangeListener listener) {
  651. if (changeSupport != null) {
  652. changeSupport.removePropertyChangeListener(listener);
  653. }
  654. }
  655. /**
  656. * Returns an array of all the <code>PropertyChangeListener</code>s added
  657. * to this TableColumn with addPropertyChangeListener().
  658. *
  659. * @return all of the <code>PropertyChangeListener</code>s added or an empty
  660. * array if no listeners have been added
  661. * @since 1.4
  662. */
  663. public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
  664. if (changeSupport == null) {
  665. return new PropertyChangeListener[0];
  666. }
  667. return changeSupport.getPropertyChangeListeners();
  668. }
  669. //
  670. // Protected Methods
  671. //
  672. /**
  673. * As of Java 2 platform v1.3, this method is not called by the <code>TableColumn</code>
  674. * constructor. Previously this method was used by the
  675. * <code>TableColumn</code> to create a default header renderer.
  676. * As of Java 2 platform v1.3, the default header renderer is <code>null</code>.
  677. * <code>JTableHeader</code> now provides its own shared default
  678. * renderer, just as the <code>JTable</code> does for its cell renderers.
  679. *
  680. * @return the default header renderer
  681. * @see javax.swing.table.JTableHeader#createDefaultRenderer()
  682. */
  683. protected TableCellRenderer createDefaultHeaderRenderer() {
  684. DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
  685. public Component getTableCellRendererComponent(JTable table, Object value,
  686. boolean isSelected, boolean hasFocus, int row, int column) {
  687. if (table != null) {
  688. JTableHeader header = table.getTableHeader();
  689. if (header != null) {
  690. setForeground(header.getForeground());
  691. setBackground(header.getBackground());
  692. setFont(header.getFont());
  693. }
  694. }
  695. setText((value == null) ? "" : value.toString());
  696. setBorder(UIManager.getBorder("TableHeader.cellBorder"));
  697. return this;
  698. }
  699. };
  700. label.setHorizontalAlignment(JLabel.CENTER);
  701. return label;
  702. }
  703. } // End of class TableColumn