OSDN Git Service

fbb877d977d57bdd88968bfcade09bf798677b21
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / table / TableColumn.java
1 /* TableColumn.java --
2    Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing.table;
40
41 import java.awt.Component;
42 import java.awt.Dimension;
43 import java.beans.PropertyChangeEvent;
44 import java.beans.PropertyChangeListener;
45 import java.io.Serializable;
46
47 import javax.swing.event.SwingPropertyChangeSupport;
48
49 /**
50  * Represents the attributes of a column in a table, including the column index,
51  * width, minimum width, preferred width and maximum width.
52  * 
53  * @author      Andrew Selkirk
54  */
55 public class TableColumn
56   implements Serializable
57 {
58   static final long serialVersionUID = -6113660025878112608L;
59
60   /**
61    * The name for the <code>columnWidth</code> property (this field is
62    * obsolete and no longer used).  Note also that the typo in the value 
63    * string is deliberate, to match the specification.
64    */
65   public static final String COLUMN_WIDTH_PROPERTY = "columWidth";
66
67   /**
68    * The name for the <code>headerValue</code> property.
69    */
70   public static final String HEADER_VALUE_PROPERTY = "headerValue";
71
72   /**
73    * The name for the <code>headerRenderer</code> property.
74    */
75   public static final String HEADER_RENDERER_PROPERTY = "headerRenderer";
76
77   /**
78    * The name for the <code>cellRenderer</code> property.
79    */
80   public static final String CELL_RENDERER_PROPERTY = "cellRenderer";
81
82   /**
83    * The index of the corresponding column in the table model.
84    */
85   protected int modelIndex;
86
87   /**
88    * The identifier for the column.
89    */
90   protected Object identifier;
91
92   /**
93    * The current width for the column.
94    */
95   protected int width;
96
97   /**
98    * The minimum width for the column.
99    */
100   protected int minWidth = 15;
101
102   /**
103    * The preferred width for the column.
104    */
105   private int preferredWidth;
106
107   /**
108    * The maximum width for the column.
109    */
110   protected int maxWidth = Integer.MAX_VALUE;
111
112   /**
113    * The renderer for the column header.
114    */
115   protected TableCellRenderer headerRenderer;
116
117   /**
118    * The value for the column header.
119    */
120   protected Object headerValue;
121
122   /**
123    * The renderer for the regular cells in this column.
124    */
125   protected TableCellRenderer cellRenderer;
126
127   /**
128    * An editor for the regular cells in this column.
129    */
130   protected TableCellEditor cellEditor;
131
132   /**
133    * A flag that determines whether or not the column is resizable (the default
134    * is <code>true</code>).
135    */
136   protected boolean isResizable = true;
137
138   /**
139    * resizedPostingDisableCount
140    *
141    * @deprecated 1.3
142    */
143   protected transient int resizedPostingDisableCount;
144
145   /**
146    * A storage and notification mechanism for property change listeners.
147    */
148   private SwingPropertyChangeSupport changeSupport =
149     new SwingPropertyChangeSupport(this);
150
151   /**
152    * Creates a new <code>TableColumn</code> that maps to column 0 in the
153    * related table model.  The default width is <code>75</code> units.
154    */
155   public TableColumn()
156   {
157     this(0, 75, null, null);
158   }
159
160   /**
161    * Creates a new <code>TableColumn</code> that maps to the specified column 
162    * in the related table model.  The default width is <code>75</code> units.
163    * 
164    * @param modelIndex the index of the column in the model
165    */
166   public TableColumn(int modelIndex)
167   {
168     this(modelIndex, 75, null, null);
169   }
170
171   /**
172    * Creates a new <code>TableColumn</code> that maps to the specified column 
173    * in the related table model, and has the specified <code>width</code>.
174    * 
175    * @param modelIndex the index of the column in the model
176    * @param width the width
177    */
178   public TableColumn(int modelIndex, int width)
179   {
180     this(modelIndex, width, null, null);
181   }
182
183   /**
184    * Creates a new <code>TableColumn</code> that maps to the specified column 
185    * in the related table model, and has the specified <code>width</code>,
186    * <code>cellRenderer</code> and <code>cellEditor</code>.
187    * 
188    * @param modelIndex the index of the column in the model
189    * @param width the width
190    * @param cellRenderer the cell renderer (<code>null</code> permitted).
191    * @param cellEditor the cell editor (<code>null</code> permitted).
192    */
193   public TableColumn(int modelIndex, int width,
194                      TableCellRenderer cellRenderer, TableCellEditor cellEditor)
195   {
196     this.modelIndex = modelIndex;
197     this.width = width;
198     this.preferredWidth = width;
199     this.cellRenderer = cellRenderer;
200     this.cellEditor = cellEditor;
201     this.headerValue = null;
202     this.identifier = null;
203   }
204
205   /**
206    * Sets the index of the column in the related {@link TableModel} that this
207    * <code>TableColumn</code> maps to, and sends a {@link PropertyChangeEvent}
208    * (with the property name 'modelIndex') to all registered listeners.
209    * 
210    * @param modelIndex the column index in the model.
211    * 
212    * @see #getModelIndex()
213    */
214   public void setModelIndex(int modelIndex)
215   {
216     if (this.modelIndex != modelIndex)
217       {
218         int oldValue = this.modelIndex;
219         this.modelIndex = modelIndex;
220         changeSupport.firePropertyChange("modelIndex", oldValue, modelIndex);
221       }
222   }
223
224   /**
225    * Returns the index of the column in the related {@link TableModel} that
226    * this <code>TableColumn</code> maps to.
227    * 
228    * @return the model index.
229    * 
230    * @see #setModelIndex(int)
231    */
232   public int getModelIndex()
233   {
234     return modelIndex;
235   }
236
237   /**
238    * Sets the identifier for the column and sends a {@link PropertyChangeEvent}
239    * (with the property name 'identifier') to all registered listeners.
240    * 
241    * @param identifier the identifier (<code>null</code> permitted).
242    * 
243    * @see #getIdentifier()
244    */
245   public void setIdentifier(Object identifier)
246   {
247     if (this.identifier != identifier)
248       {       
249         Object oldValue = this.identifier;
250         this.identifier = identifier;
251         changeSupport.firePropertyChange("identifier", oldValue, identifier);
252       }
253   }
254
255   /**
256    * Returns the identifier for the column, or {@link #getHeaderValue()} if the 
257    * identifier is <code>null</code>.
258    * 
259    * @return The identifier (or {@link #getHeaderValue()} if the identifier is 
260    *         <code>null</code>).
261    */
262   public Object getIdentifier()
263   {
264     if (identifier == null)
265       return getHeaderValue();
266     return identifier;
267   }
268
269   /**
270    * Sets the header value and sends a {@link PropertyChangeEvent} (with the 
271    * property name {@link #HEADER_VALUE_PROPERTY}) to all registered listeners.
272    * 
273    * @param headerValue the value of the header (<code>null</code> permitted).
274    * 
275    * @see #getHeaderValue()
276    */
277   public void setHeaderValue(Object headerValue)
278   {
279     if (this.headerValue == headerValue)
280       return;
281     
282     Object oldValue = this.headerValue;
283     this.headerValue = headerValue;
284     changeSupport.firePropertyChange(HEADER_VALUE_PROPERTY, oldValue, 
285                                      headerValue);
286   }
287
288   /**
289    * Returns the header value.
290    * 
291    * @return the value of the header.
292    * 
293    * @see #getHeaderValue()
294    */
295   public Object getHeaderValue()
296   {
297     return headerValue;
298   }
299
300   /**
301    * Sets the renderer for the column header and sends a 
302    * {@link PropertyChangeEvent} (with the property name 
303    * {@link #HEADER_RENDERER_PROPERTY}) to all registered listeners.
304    * 
305    * @param renderer the header renderer (<code>null</code> permitted).
306    * 
307    * @see #getHeaderRenderer()
308    */
309   public void setHeaderRenderer(TableCellRenderer renderer)
310   {
311     if (headerRenderer == renderer)
312       return;
313     
314     TableCellRenderer oldRenderer = headerRenderer;
315     headerRenderer = renderer;
316     changeSupport.firePropertyChange(HEADER_RENDERER_PROPERTY, oldRenderer, 
317                                      headerRenderer);
318   }
319
320   /**
321    * Returns the renderer for the column header.
322    * 
323    * @return The renderer for the column header (possibly <code>null</code>).
324    * 
325    * @see #setHeaderRenderer(TableCellRenderer)
326    */
327   public TableCellRenderer getHeaderRenderer()
328   {
329     return headerRenderer;
330   }
331
332   /**
333    * Sets the renderer for cells in this column and sends a 
334    * {@link PropertyChangeEvent} (with the property name 
335    * {@link #CELL_RENDERER_PROPERTY}) to all registered listeners.
336    * 
337    * @param renderer the cell renderer (<code>null</code> permitted).
338    * 
339    * @see #getCellRenderer()
340    */
341   public void setCellRenderer(TableCellRenderer renderer)
342   {
343     if (cellRenderer == renderer)
344       return;
345     
346     TableCellRenderer oldRenderer = cellRenderer;
347     cellRenderer = renderer;
348     changeSupport.firePropertyChange(CELL_RENDERER_PROPERTY, oldRenderer, 
349                                      cellRenderer);
350   }
351
352   /**
353    * Returns the renderer for the table cells in this column.
354    * 
355    * @return The cell renderer (possibly <code>null</code>).
356    * 
357    * @see #setCellRenderer(TableCellRenderer)
358    */
359   public TableCellRenderer getCellRenderer()
360   {
361     return cellRenderer;
362   }
363
364   /**
365    * Sets the cell editor for the column and sends a {@link PropertyChangeEvent}
366    * (with the property name 'cellEditor') to all registered listeners.
367    * 
368    * @param cellEditor the cell editor (<code>null</code> permitted).
369    * 
370    * @see #getCellEditor()
371    */
372   public void setCellEditor(TableCellEditor cellEditor)
373   {
374     if (this.cellEditor != cellEditor)
375       {
376         TableCellEditor oldValue = this.cellEditor;
377         this.cellEditor = cellEditor;
378         changeSupport.firePropertyChange("cellEditor", oldValue, cellEditor);
379       }
380   }
381
382   /**
383    * Returns the cell editor for the column (the default value is 
384    * <code>null</code>).
385    * 
386    * @return The cell editor (possibly <code>null</code>).
387    * 
388    * @see #setCellEditor(TableCellEditor)
389    */
390   public TableCellEditor getCellEditor()
391   {
392     return cellEditor;
393   }
394
395   /**
396    * Sets the width for the column and sends a {@link PropertyChangeEvent} 
397    * (with the property name 'width') to all registered listeners.  If the new
398    * width falls outside the range getMinWidth() to getMaxWidth() it is 
399    * adjusted to the appropriate boundary value.
400    * 
401    * @param newWidth the width.
402    * 
403    * @see #getWidth()
404    */
405   public void setWidth(int newWidth)
406   {
407     int oldWidth = width;
408
409     if (newWidth < minWidth)
410       width = minWidth;
411     else if (newWidth > maxWidth)
412       width = maxWidth;
413     else
414       width = newWidth;
415
416     if (width == oldWidth)
417       return;
418
419     // We do have a constant field COLUMN_WIDTH_PROPERTY,
420     // however, tests show that the actual fired property name is 'width'
421     // and even Sun's API docs say that this constant field is obsolete and
422     // not used.
423     changeSupport.firePropertyChange("width", oldWidth, width);
424   }
425
426   /**
427    * Returns the width for the column (the default value is <code>75</code>).
428    * 
429    * @return The width.
430    *
431    * @see #setWidth(int)
432    */
433   public int getWidth()
434   {
435     return width;
436   }
437
438   /**
439    * Sets the preferred width for the column and sends a 
440    * {@link PropertyChangeEvent} (with the property name 'preferredWidth') to 
441    * all registered listeners.  If necessary, the supplied value will be 
442    * adjusted to fit in the range {@link #getMinWidth()} to 
443    * {@link #getMaxWidth()}.
444    * 
445    * @param preferredWidth  the preferred width.
446    * 
447    * @see #getPreferredWidth()
448    */
449   public void setPreferredWidth(int preferredWidth)
450   {
451     int oldPrefWidth = this.preferredWidth;
452
453     if (preferredWidth < minWidth)
454       this.preferredWidth = minWidth;
455     else if (preferredWidth > maxWidth)
456       this.preferredWidth = maxWidth;
457     else
458       this.preferredWidth = preferredWidth;
459
460     changeSupport.firePropertyChange("preferredWidth", oldPrefWidth, 
461                                      this.preferredWidth);
462   }
463
464   /**
465    * Returns the preferred width for the column (the default value is 
466    * <code>75</code>).
467    * 
468    * @return The preferred width.
469    * 
470    * @see #setPreferredWidth(int)
471    */
472   public int getPreferredWidth()
473   {
474     return preferredWidth;
475   }
476
477   /**
478    * Sets the minimum width for the column and sends a 
479    * {@link PropertyChangeEvent} (with the property name 'minWidth') to all
480    * registered listeners.  If the current <code>width</code> and/or 
481    * <code>preferredWidth</code> are less than the new minimum width, they are
482    * adjusted accordingly.
483    * 
484    * @param minWidth  the minimum width (negative values are treated as 0).
485    * 
486    * @see #getMinWidth()
487    */
488   public void setMinWidth(int minWidth)
489   {
490     if (minWidth < 0)
491       minWidth = 0;
492     if (this.minWidth != minWidth)
493       {
494         if (width < minWidth)
495           setWidth(minWidth);
496         if (preferredWidth < minWidth)
497           setPreferredWidth(minWidth);
498         int oldValue = this.minWidth;
499         this.minWidth = minWidth;
500         changeSupport.firePropertyChange("minWidth", oldValue, minWidth);
501       }
502   }
503
504   /**
505    * Returns the <code>TableColumn</code>'s minimum width (the default value
506    * is <code>15</code>).
507    * 
508    * @return The minimum width.
509    * 
510    * @see #setMinWidth(int)
511    */
512   public int getMinWidth()
513   {
514     return minWidth;
515   }
516
517   /**
518    * Sets the maximum width for the column and sends a 
519    * {@link PropertyChangeEvent} (with the property name 'maxWidth') to all
520    * registered listeners.  If the current <code>width</code> and/or 
521    * <code>preferredWidth</code> are greater than the new maximum width, they 
522    * are adjusted accordingly.
523    * 
524    * @param maxWidth the maximum width.
525    * 
526    * @see #getMaxWidth()
527    */
528   public void setMaxWidth(int maxWidth)
529   {
530     if (this.maxWidth != maxWidth)
531       {
532         if (width > maxWidth)
533           setWidth(maxWidth);
534         if (preferredWidth > maxWidth)
535           setPreferredWidth(maxWidth);
536         int oldValue = this.maxWidth;
537         this.maxWidth = maxWidth;
538         changeSupport.firePropertyChange("maxWidth", oldValue, maxWidth);
539        }
540   }
541
542   /**
543    * Returns the maximum width for the column (the default value is
544    * {@link Integer#MAX_VALUE}).
545    * 
546    * @return The maximum width for the column.
547    * 
548    * @see #setMaxWidth(int)
549    */
550   public int getMaxWidth()
551   {
552     return maxWidth;
553   }
554
555   /**
556    * Sets the flag that controls whether or not the column is resizable, and
557    * sends a {@link PropertyChangeEvent} (with the property name 'isResizable')
558    * to all registered listeners.
559    * 
560    * @param isResizable <code>true</code> if this column is resizable,
561    * <code>false</code> otherwise.
562    * 
563    * @see #getResizable()
564    */
565   public void setResizable(boolean isResizable)
566   {
567     if (this.isResizable != isResizable)
568       {
569         this.isResizable = isResizable;
570         changeSupport.firePropertyChange("isResizable", !this.isResizable, 
571             isResizable);
572       }
573   }
574
575   /**
576    * Returns the flag that controls whether or not the column is resizable.
577    * 
578    * @return <code>true</code> if this column is resizable,
579    * <code>false</code> otherwise.
580    * 
581    * @see #setResizable(boolean)
582    */
583   public boolean getResizable()
584   {
585     return isResizable;
586   }
587
588   /**
589    * Sets the minimum, maximum, preferred and current width to match the
590    * minimum, maximum and preferred width of the header renderer component.
591    * If there is no header renderer component, this method does nothing.
592    */
593   public void sizeWidthToFit()
594   {
595     if (headerRenderer == null)
596       return;
597     Component c = headerRenderer.getTableCellRendererComponent(null, 
598         getHeaderValue(), false, false, 0, 0);
599     Dimension min = c.getMinimumSize();
600     Dimension max = c.getMaximumSize();
601     Dimension pref = c.getPreferredSize();
602     setMinWidth(min.width);
603     setMaxWidth(max.width);
604     setPreferredWidth(pref.width);
605     setWidth(pref.width);
606   }
607
608   /**
609    * This method is empty, unused and deprecated.
610    * @deprecated 1.3
611    */
612   public void disableResizedPosting()
613   {
614     // Does nothing
615   }
616
617   /**
618    * This method is empty, unused and deprecated.
619    * @deprecated 1.3
620    */
621   public void enableResizedPosting()
622   {
623     // Does nothing
624   }
625
626   /**
627    * Adds a listener so that it receives {@link PropertyChangeEvent} 
628    * notifications from this column.  The properties defined by the column are:
629    * <ul>
630    * <li><code>width</code> - see {@link #setWidth(int)};</li>
631    * <li><code>preferredWidth</code> - see {@link #setPreferredWidth(int)};</li>
632    * <li><code>minWidth</code> - see {@link #setMinWidth(int)};</li> 
633    * <li><code>maxWidth</code> - see {@link #setMaxWidth(int)};</li>
634    * <li><code>modelIndex</code> - see {@link #setModelIndex(int)};</li>
635    * <li><code>isResizable</code> - see {@link #setResizable(boolean)};</li>
636    * <li><code>cellRenderer</code> - see 
637    *   {@link #setCellRenderer(TableCellRenderer)};</li>
638    * <li><code>cellEditor</code> - see 
639    *   {@link #setCellEditor(TableCellEditor)};</li>
640    * <li><code>headerRenderer</code> - see 
641    *   {@link #setHeaderRenderer(TableCellRenderer)};</li>
642    * <li><code>headerValue</code> - see {@link #setHeaderValue(Object)};</li>
643    * <li><code>identifier</code> - see {@link #setIdentifier(Object)}.</li>
644    * </ul>
645    * 
646    * @param listener the listener to add (<code>null</code> is ignored).
647    * 
648    * @see #removePropertyChangeListener(PropertyChangeListener)
649    */
650   public synchronized void addPropertyChangeListener(
651       PropertyChangeListener listener)
652   {
653     changeSupport.addPropertyChangeListener(listener);
654   }
655
656   /**
657    * Removes a listener so that it no longer receives 
658    * {@link PropertyChangeEvent} notifications from this column.  If 
659    * <code>listener</code> is not registered with the column, or is 
660    * <code>null</code>, this method does nothing.
661    * 
662    * @param listener the listener to remove (<code>null</code> is ignored).
663    */
664   public synchronized void removePropertyChangeListener(
665       PropertyChangeListener listener)
666   {
667     changeSupport.removePropertyChangeListener(listener);
668   }
669
670   /**
671    * Returns the property change listeners for this <code>TableColumn</code>.
672    * An empty array is returned if there are currently no listeners registered.
673    * 
674    * @return The property change listeners registered with this column.
675    * 
676    * @since 1.4
677    */
678   public PropertyChangeListener[] getPropertyChangeListeners()
679   {
680     return changeSupport.getPropertyChangeListeners();
681   }
682
683   /**
684    * Creates and returns a default renderer for the column header (in this case,
685    * a new instance of {@link DefaultTableCellRenderer}).
686    * 
687    * @return A default renderer for the column header.
688    */
689   protected TableCellRenderer createDefaultHeaderRenderer()
690   {
691     return new DefaultTableCellRenderer();
692   }
693 }