1 /* JTableHeader.java --
2    Copyright (C) 2003, 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.Color;
42 import java.awt.Component;
43 import java.awt.Cursor;
44 import java.awt.Dimension;
45 import java.awt.Font;
46 import java.awt.FontMetrics;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.event.FocusListener;
50 import java.beans.PropertyChangeListener;
51 import java.util.Locale;
52 
53 import javax.accessibility.Accessible;
54 import javax.accessibility.AccessibleAction;
55 import javax.accessibility.AccessibleComponent;
56 import javax.accessibility.AccessibleContext;
57 import javax.accessibility.AccessibleRole;
58 import javax.accessibility.AccessibleSelection;
59 import javax.accessibility.AccessibleStateSet;
60 import javax.accessibility.AccessibleText;
61 import javax.accessibility.AccessibleValue;
62 import javax.swing.JComponent;
63 import javax.swing.JTable;
64 import javax.swing.UIManager;
65 import javax.swing.event.ChangeEvent;
66 import javax.swing.event.ListSelectionEvent;
67 import javax.swing.event.TableColumnModelEvent;
68 import javax.swing.event.TableColumnModelListener;
69 import javax.swing.plaf.TableHeaderUI;
70 
71 /**
72  * Represents the table header. The header displays the column header values,
73  * is always visible event if the rest of the table scrolls up and down and
74  * supports column reordering and resizing with mouse.
75  */
76 public class JTableHeader extends JComponent
77   implements TableColumnModelListener, Accessible
78 {
79   protected class AccessibleJTableHeader extends AccessibleJComponent
80   {
81     protected class AccessibleJTableHeaderEntry extends AccessibleContext
82       implements Accessible, AccessibleComponent
83     {
84 
85       private int columnIndex;
86 
87       private JTableHeader parent;
88 
89       private JTable table;
90 
AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)91       public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)
92       {
93         columnIndex = c;
94         parent = p;
95         table = t;
96       }
97 
98       /**
99        * Returns the column header renderer.
100        *
101        * @return The column header renderer.
102        */
getColumnHeaderRenderer()103       Component getColumnHeaderRenderer()
104       {
105         TableColumn tc = parent.getColumnModel().getColumn(columnIndex);
106         TableCellRenderer r = tc.getHeaderRenderer();
107         if (r == null)
108           r = parent.getDefaultRenderer();
109         return r.getTableCellRendererComponent(table, tc.headerValue,
110             false, false, -1, columnIndex);
111       }
112 
113       /**
114        * Returns the accessible context for the column header renderer, or
115        * <code>null</code>.
116        *
117        * @return The accessible context.
118        */
getAccessibleColumnHeaderRenderer()119       AccessibleContext getAccessibleColumnHeaderRenderer()
120       {
121         Component c = getColumnHeaderRenderer();
122         if (c instanceof Accessible)
123           return c.getAccessibleContext();
124         return null;
125       }
126 
127       /**
128        * @see #removeFocusListener(FocusListener)
129        */
addFocusListener(FocusListener l)130       public void addFocusListener(FocusListener l)
131       {
132         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
133         AccessibleComponent c = ac.getAccessibleComponent();
134         if (c != null)
135           c.addFocusListener(l);
136       }
137 
138       /**
139        * @see #removePropertyChangeListener(PropertyChangeListener)
140        */
addPropertyChangeListener(PropertyChangeListener l)141       public void addPropertyChangeListener(PropertyChangeListener l)
142       {
143         // add the listener to the accessible context for the header
144         // renderer...
145         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
146         if (ac != null)
147           ac.addPropertyChangeListener(l);
148       }
149 
contains(Point p)150       public boolean contains(Point p)
151       {
152         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
153         AccessibleComponent c = ac.getAccessibleComponent();
154         if (c != null)
155           return c.contains(p);
156         else
157           return false;
158       }
159 
getAccessibleAction()160       public AccessibleAction getAccessibleAction()
161       {
162         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
163         if (ac instanceof AccessibleAction)
164           return (AccessibleAction) ac;
165         else
166           return null;
167       }
168 
getAccessibleAt(Point p)169       public Accessible getAccessibleAt(Point p)
170       {
171         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
172         AccessibleComponent c = ac.getAccessibleComponent();
173         if (c != null)
174           return c.getAccessibleAt(p);
175         else
176           return null;
177       }
178 
179       /**
180        * Returns <code>null</code> as the header entry has no accessible
181        * children.
182        *
183        * @return <code>null</code>.
184        */
getAccessibleChild(int i)185       public Accessible getAccessibleChild(int i)
186       {
187         return null;
188       }
189 
190       /**
191        * Returns the number of accessible children, zero in this case.
192        *
193        * @return 0
194        */
getAccessibleChildrenCount()195       public int getAccessibleChildrenCount()
196       {
197         return 0;
198       }
199 
200       /**
201        * Returns the accessible component for this header entry.
202        *
203        * @return <code>this</code>.
204        */
getAccessibleComponent()205       public AccessibleComponent getAccessibleComponent()
206       {
207         return this;
208       }
209 
210       /**
211        * Returns the accessible context for this header entry.
212        *
213        * @return <code>this</code>.
214        */
getAccessibleContext()215       public AccessibleContext getAccessibleContext()
216       {
217         return this;
218       }
219 
220       /**
221        * Returns the accessible description.
222        *
223        * @return The accessible description.
224        *
225        * @see #setAccessibleDescription(String)
226        */
getAccessibleDescription()227       public String getAccessibleDescription()
228       {
229         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
230         if (ac != null)
231           return ac.getAccessibleDescription();
232         return accessibleDescription;
233       }
234 
235       /**
236        * Returns the index of this header entry.
237        *
238        * @return The index of this header entry.
239        */
getAccessibleIndexInParent()240       public int getAccessibleIndexInParent()
241       {
242         return columnIndex;
243       }
244 
245       /**
246        * Returns the accessible name.
247        *
248        * @return The accessible name.
249        *
250        * @see #setAccessibleName(String)
251        */
getAccessibleName()252       public String getAccessibleName()
253       {
254         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
255         if (ac != null)
256           return ac.getAccessibleName();
257         return accessibleName;
258       }
259 
260       /**
261        * Returns the accessible role for the header entry.
262        *
263        * @return The accessible role.
264        */
getAccessibleRole()265       public AccessibleRole getAccessibleRole()
266       {
267         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
268         if (ac != null)
269           return ac.getAccessibleRole();
270         else
271           return null;
272       }
273 
getAccessibleSelection()274       public AccessibleSelection getAccessibleSelection()
275       {
276         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
277         if (ac instanceof AccessibleValue)
278           return (AccessibleSelection) ac;
279         else
280           return null;
281       }
282 
getAccessibleStateSet()283       public AccessibleStateSet getAccessibleStateSet()
284       {
285         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
286         if (ac != null)
287           return ac.getAccessibleStateSet();
288         else
289           return null;
290       }
291 
getAccessibleText()292       public AccessibleText getAccessibleText()
293       {
294         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
295         if (ac != null)
296           return ac.getAccessibleText();
297         else
298           return null;
299       }
300 
getAccessibleValue()301       public AccessibleValue getAccessibleValue()
302       {
303         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
304         if (ac instanceof AccessibleValue)
305           return (AccessibleValue) ac;
306         else
307           return null;
308       }
309 
getBackground()310       public Color getBackground()
311       {
312         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
313         AccessibleComponent c = ac.getAccessibleComponent();
314         if (c != null)
315           return c.getBackground();
316         else
317           return null;
318       }
319 
getBounds()320       public Rectangle getBounds()
321       {
322         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
323         AccessibleComponent c = ac.getAccessibleComponent();
324         if (c != null)
325           return c.getBounds();
326         else
327           return null;
328       }
329 
getCursor()330       public Cursor getCursor()
331       {
332         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
333         AccessibleComponent c = ac.getAccessibleComponent();
334         if (c != null)
335           return c.getCursor();
336         else
337           return null;
338       }
339 
getFont()340       public Font getFont()
341       {
342         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
343         AccessibleComponent c = ac.getAccessibleComponent();
344         if (c != null)
345           return c.getFont();
346         else
347           return null;
348       }
349 
getFontMetrics(Font f)350       public FontMetrics getFontMetrics(Font f)
351       {
352         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
353         AccessibleComponent c = ac.getAccessibleComponent();
354         if (c != null)
355           return c.getFontMetrics(f);
356         else
357           return null;
358       }
359 
getForeground()360       public Color getForeground()
361       {
362         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
363         AccessibleComponent c = ac.getAccessibleComponent();
364         if (c != null)
365           return c.getForeground();
366         else
367           return null;
368       }
369 
getLocale()370       public Locale getLocale()
371       {
372         Component c = getColumnHeaderRenderer();
373         if (c != null)
374           return c.getLocale();
375         return null;
376       }
377 
getLocation()378       public Point getLocation()
379       {
380         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
381         AccessibleComponent c = ac.getAccessibleComponent();
382         if (c != null)
383           return c.getLocation();
384         else
385           return null;
386       }
387 
getLocationOnScreen()388       public Point getLocationOnScreen()
389       {
390         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
391         AccessibleComponent c = ac.getAccessibleComponent();
392         if (c != null)
393           return c.getLocationOnScreen();
394         else
395           return null;
396       }
397 
getSize()398       public Dimension getSize()
399       {
400         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
401         AccessibleComponent c = ac.getAccessibleComponent();
402         if (c != null)
403           return c.getSize();
404         else
405           return null;
406       }
407 
isEnabled()408       public boolean isEnabled()
409       {
410         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
411         AccessibleComponent c = ac.getAccessibleComponent();
412         if (c != null)
413           return c.isEnabled();
414         else
415           return false;
416       }
417 
isFocusTraversable()418       public boolean isFocusTraversable()
419       {
420         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
421         AccessibleComponent c = ac.getAccessibleComponent();
422         if (c != null)
423           return c.isFocusTraversable();
424         else
425           return false;
426       }
427 
isShowing()428       public boolean isShowing()
429       {
430         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
431         AccessibleComponent c = ac.getAccessibleComponent();
432         if (c != null)
433           return c.isShowing();
434         else
435           return false;
436       }
437 
isVisible()438       public boolean isVisible()
439       {
440         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
441         AccessibleComponent c = ac.getAccessibleComponent();
442         if (c != null)
443           return c.isVisible();
444         else
445           return false;
446       }
447 
448       /**
449        * @see #addFocusListener(FocusListener)
450        */
removeFocusListener(FocusListener l)451       public void removeFocusListener(FocusListener l)
452       {
453         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
454         AccessibleComponent c = ac.getAccessibleComponent();
455         if (c != null)
456           c.removeFocusListener(l);
457       }
458 
459       /**
460        * @see #addPropertyChangeListener(PropertyChangeListener)
461        */
removePropertyChangeListener(PropertyChangeListener l)462       public void removePropertyChangeListener(PropertyChangeListener l)
463       {
464         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
465         if (ac != null)
466           ac.removePropertyChangeListener(l);
467       }
468 
469       /**
470        * @see #addFocusListener(FocusListener)
471        */
requestFocus()472       public void requestFocus()
473       {
474         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
475         AccessibleComponent c = ac.getAccessibleComponent();
476         if (c != null)
477           c.requestFocus();
478       }
479 
480       /**
481        * @see #getAccessibleDescription()
482        */
setAccessibleDescription(String s)483       public void setAccessibleDescription(String s)
484       {
485         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
486         if (ac != null)
487           ac.setAccessibleDescription(s);
488         else
489           accessibleDescription = s;
490       }
491 
492       /**
493        * @see #getAccessibleName()
494        */
setAccessibleName(String s)495       public void setAccessibleName(String s)
496       {
497         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
498         if (ac != null)
499           ac.setAccessibleName(s);
500       }
501 
setBackground(Color c)502       public void setBackground(Color c)
503       {
504         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
505         AccessibleComponent comp = ac.getAccessibleComponent();
506         if (comp != null)
507           comp.setBackground(c);
508       }
509 
setBounds(Rectangle r)510       public void setBounds(Rectangle r)
511       {
512         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
513         AccessibleComponent comp = ac.getAccessibleComponent();
514         if (comp != null)
515           comp.setBounds(r);
516       }
517 
setCursor(Cursor c)518       public void setCursor(Cursor c)
519       {
520         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
521         AccessibleComponent comp = ac.getAccessibleComponent();
522         if (comp != null)
523           comp.setCursor(c);
524       }
525 
setEnabled(boolean b)526       public void setEnabled(boolean b)
527       {
528         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
529         AccessibleComponent comp = ac.getAccessibleComponent();
530         if (comp != null)
531           comp.setEnabled(b);
532       }
533 
setFont(Font f)534       public void setFont(Font f)
535       {
536         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
537         AccessibleComponent comp = ac.getAccessibleComponent();
538         if (comp != null)
539           comp.setFont(f);
540       }
541 
setForeground(Color c)542       public void setForeground(Color c)
543       {
544         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
545         AccessibleComponent comp = ac.getAccessibleComponent();
546         if (comp != null)
547           comp.setForeground(c);
548       }
549 
setLocation(Point p)550       public void setLocation(Point p)
551       {
552         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
553         AccessibleComponent comp = ac.getAccessibleComponent();
554         if (comp != null)
555           comp.setLocation(p);
556       }
557 
setSize(Dimension d)558       public void setSize(Dimension d)
559       {
560         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
561         AccessibleComponent comp = ac.getAccessibleComponent();
562         if (comp != null)
563           comp.setSize(d);
564       }
565 
setVisible(boolean b)566       public void setVisible(boolean b)
567       {
568         AccessibleContext ac = getAccessibleColumnHeaderRenderer();
569         AccessibleComponent comp = ac.getAccessibleComponent();
570         if (comp != null)
571           comp.setVisible(b);
572       }
573     }
574 
getAccessibleRole()575     public AccessibleRole getAccessibleRole()
576     {
577       return AccessibleRole.PANEL;
578     }
579 
getAccessibleChildrenCount()580     public int getAccessibleChildrenCount()
581     {
582       return table.getColumnCount();
583     }
584 
getAccessibleChild(int i)585     public Accessible getAccessibleChild(int i)
586     {
587       return new AccessibleJTableHeaderEntry(i, JTableHeader.this, table);
588     }
589 
getAccessibleAt(Point p)590     public Accessible getAccessibleAt(Point p)
591     {
592       return getAccessibleChild(columnAtPoint(p));
593     }
594   }
595 
596   /**
597    * Use serialVersionUid for interoperability.
598    */
599   private static final long serialVersionUID = 5144633983372967710L;
600 
601   /**
602    * The columnModel property.
603    */
604   protected TableColumnModel columnModel;
605 
606   /**
607    * The draggedColumn property.
608    */
609   protected TableColumn draggedColumn;
610 
611   /**
612    * The draggedDistance property.
613    */
614   protected int draggedDistance;
615 
616   /**
617    * The opaque property.
618    */
619   boolean opaque;
620 
621   /**
622    * The reorderingAllowed property.
623    */
624   protected boolean reorderingAllowed;
625 
626   /**
627    * The resizingAllowed property.
628    */
629   protected boolean resizingAllowed = true;
630 
631   /**
632    * The resizingColumn property.
633    */
634   protected TableColumn resizingColumn;
635 
636   /**
637    * The table property.
638    */
639   protected JTable table;
640 
641   /**
642    * The updateTableInRealTime property.
643    */
644   protected boolean updateTableInRealTime;
645 
646   TableCellRenderer cellRenderer;
647 
648   /**
649    * Creates a new default instance.
650    */
JTableHeader()651   public JTableHeader()
652   {
653     this(null);
654   }
655 
656   /**
657    * Creates a new header.  If <code>cm</code> is <code>null</code>, a new
658    * table column model is created by calling
659    * {@link #createDefaultColumnModel()}.
660    *
661    * @param cm  the table column model (<code>null</code> permitted).
662    */
JTableHeader(TableColumnModel cm)663   public JTableHeader(TableColumnModel cm)
664   {
665     columnModel = cm == null ? createDefaultColumnModel() : cm;
666     initializeLocalVars();
667     updateUI();
668   }
669 
670   /**
671    * Creates a default table column model.
672    *
673    * @return A default table column model.
674    */
createDefaultColumnModel()675   protected TableColumnModel createDefaultColumnModel()
676   {
677     return new DefaultTableColumnModel();
678   }
679 
680   /**
681    * Get the value of the {@link #accessibleContext} property.
682    *
683    * @return The current value of the property
684    */
getAccessibleContext()685   public AccessibleContext getAccessibleContext()
686   {
687     return accessibleContext;
688   }
689 
690   /**
691    * Get the value of the {@link #columnModel} property.
692    *
693    * @return The current value of the property
694    */
getColumnModel()695   public TableColumnModel getColumnModel()
696   {
697     return columnModel;
698   }
699 
700   /**
701    * Get the column that is currently being dragged. This is used when
702    * handling the column reordering with mouse.
703    *
704    * @return the column being dragged, null if none.
705    */
getDraggedColumn()706   public TableColumn getDraggedColumn()
707   {
708     return draggedColumn;
709   }
710 
711   /**
712    * Get the value of the {@link #draggedDistance} property.
713    *
714    * @return The current value of the property
715    */
getDraggedDistance()716   public int getDraggedDistance()
717   {
718     return draggedDistance;
719   }
720 
721   /**
722    * Check if it is possible to reorder the table columns by dragging column
723    * header with mouse. The table reordering is enabled by default, but can be
724    * disabled with {@link #setReorderingAllowed(boolean)}.
725    *
726    * @return true if reordering is allowed, false otherwise.
727    */
getReorderingAllowed()728   public boolean getReorderingAllowed()
729   {
730     return reorderingAllowed;
731   }
732 
733   /**
734    * Check if it is possible to resize the table columns by dragging the column
735    * boundary in the table header with mouse. The resizing is enabled
736    * by default, but can be disabled with {@link #setResizingAllowed(boolean)}.
737    *
738    * @return true if resizing is allowed, false otherwise.
739    */
getResizingAllowed()740   public boolean getResizingAllowed()
741   {
742     return resizingAllowed;
743   }
744 
745   /**
746    * Get the column that is currently being resized. This is used when
747    * handling the column resizing with mouse.
748    *
749    * @return the column being currently resized, null if none.
750    */
getResizingColumn()751   public TableColumn getResizingColumn()
752   {
753     return resizingColumn;
754   }
755 
756   /**
757    * Get the table, having this header.
758    *
759    * @return the table, having this header.
760    */
getTable()761   public JTable getTable()
762   {
763     return table;
764   }
765 
766   /**
767    * Get the value of the {@link #updateTableInRealTime} property.
768    *
769    * @return The current value of the property
770    */
getUpdateTableInRealTime()771   public boolean getUpdateTableInRealTime()
772   {
773     return updateTableInRealTime;
774   }
775 
776   /**
777    * Get the value of the {@link #opaque} property.
778    *
779    * @return The current value of the property
780    */
isOpaque()781   public boolean isOpaque()
782   {
783     return opaque;
784   }
785 
786   /**
787    * Set the value of the {@link #columnModel} property.
788    *
789    * @param c The new value of the property
790    */
setColumnModel(TableColumnModel c)791   public void setColumnModel(TableColumnModel c)
792   {
793     columnModel.removeColumnModelListener(this);
794     columnModel = c;
795     columnModel.addColumnModelListener(this);
796   }
797 
798   /**
799    * Set the column that is currently being dragged. This is used when
800    * dragging the column with mouse. Setting to null will stop the
801    * dragging session immediately.
802    *
803    * @param draggingIt the column being currently dragged, null if none.
804    */
setDraggedColumn(TableColumn draggingIt)805   public void setDraggedColumn(TableColumn draggingIt)
806   {
807     draggedColumn = draggingIt;
808   }
809 
810   /**
811    * Set the value of the {@link #draggedDistance} property.
812    *
813    * @param d The new value of the property
814    */
setDraggedDistance(int d)815   public void setDraggedDistance(int d)
816   {
817     draggedDistance = d;
818   }
819 
820   /**
821    * Set the value of the {@link #opaque} property.
822    *
823    * @param o The new value of the property
824    */
setOpaque(boolean o)825   public void setOpaque(boolean o)
826   {
827     opaque = o;
828   }
829 
830   /**
831    * Set the table ability to reorder columns by dragging column header
832    * with mouse. The table reordering is enabled by default, but can be
833    * disabled with this method.
834    *
835    * @param allowed true if reordering is allowed, false otherwise.
836    */
setReorderingAllowed(boolean allowed)837   public void setReorderingAllowed(boolean allowed)
838   {
839     reorderingAllowed = allowed;
840   }
841 
842   /**
843    * Set the table ability to resize columns by dragging the column
844    * boundary in the table header with mouse. The resizing is enabled
845    * by default, but can be disabled using this method.
846    *
847    * @param allowed true if resizing is allowed, false otherwise.
848    */
setResizingAllowed(boolean allowed)849   public void setResizingAllowed(boolean allowed)
850   {
851     resizingAllowed = allowed;
852   }
853 
854   /**
855    * The the column that is currently being resized. This property is used
856    * when handling table resizing with mouse. Setting to null would stop
857    * the resizing session immediately.
858    *
859    * @param resizingIt the column being currently resized
860    */
setResizingColumn(TableColumn resizingIt)861   public void setResizingColumn(TableColumn resizingIt)
862   {
863     resizingColumn = resizingIt;
864   }
865 
866   /**
867    * Set the value of the {@link #table} property.
868    *
869    * @param t The new value of the property
870    */
setTable(JTable t)871   public void setTable(JTable t)
872   {
873     table = t;
874   }
875 
876   /**
877    * Set the value of the {@link #updateTableInRealTime} property.
878    *
879    * @param u The new value of the property
880    */
setUpdateTableInRealTime(boolean u)881   public void setUpdateTableInRealTime(boolean u)
882   {
883     updateTableInRealTime = u;
884   }
885 
886   /**
887    * Creates a default renderer.
888    *
889    * @return A default renderer.
890    */
createDefaultRenderer()891   protected TableCellRenderer createDefaultRenderer()
892   {
893     return new DefaultTableCellRenderer();
894   }
895 
896   /**
897    * Returns the default table cell renderer.
898    *
899    * @return The default table cell renderer.
900    */
getDefaultRenderer()901   public TableCellRenderer getDefaultRenderer()
902   {
903     return cellRenderer;
904   }
905 
906   /**
907    * Sets the default table cell renderer.
908    *
909    * @param cellRenderer  the renderer.
910    */
setDefaultRenderer(TableCellRenderer cellRenderer)911   public void setDefaultRenderer(TableCellRenderer cellRenderer)
912   {
913     this.cellRenderer = cellRenderer;
914   }
915 
916   /**
917    * Get the rectangle, occupied by the header of the given column.
918    *
919    * @param column the column, for that the header area is requested.
920    *
921    * @return the column header area.
922    */
getHeaderRect(int column)923   public Rectangle getHeaderRect(int column)
924   {
925     Rectangle r = getTable().getCellRect(-1, column, false);
926     r.height = getHeight();
927     return r;
928   }
929 
paramString()930   protected String paramString()
931   {
932     return "JTableHeader";
933   }
934 
935   // UI support
936 
getUIClassID()937   public String getUIClassID()
938   {
939     return "TableHeaderUI";
940   }
941 
getUI()942   public TableHeaderUI getUI()
943   {
944     return (TableHeaderUI) ui;
945   }
946 
setUI(TableHeaderUI u)947   public void setUI(TableHeaderUI u)
948   {
949     super.setUI(u);
950   }
951 
updateUI()952   public void updateUI()
953   {
954     setUI((TableHeaderUI) UIManager.getUI(this));
955   }
956 
957   /**
958    * Returns the index of the column at the specified point.
959    *
960    * @param point  the point.
961    *
962    * @return The column index, or -1.
963    */
columnAtPoint(Point point)964   public int columnAtPoint(Point point)
965   {
966     if (getBounds().contains(point))
967       return columnModel.getColumnIndexAtX(point.x);
968 
969     return -1;
970   }
971 
972   /**
973    * Receives notification when a column is added to the column model.
974    *
975    * @param event the table column model event
976    */
columnAdded(TableColumnModelEvent event)977   public void columnAdded(TableColumnModelEvent event)
978   {
979     // TODO: What else to do here (if anything)?
980     resizeAndRepaint();
981   }
982 
983   /**
984    * Receives notification when a column margin changes in the column model.
985    *
986    * @param event the table column model event
987    */
columnMarginChanged(ChangeEvent event)988   public void columnMarginChanged(ChangeEvent event)
989   {
990     // TODO: What else to do here (if anything)?
991     resizeAndRepaint();
992   }
993 
994   /**
995    * Receives notification when a column is moved within the column model.
996    *
997    * @param event the table column model event
998    */
columnMoved(TableColumnModelEvent event)999   public void columnMoved(TableColumnModelEvent event)
1000   {
1001     // TODO: What else to do here (if anything)?
1002     resizeAndRepaint();
1003   }
1004 
1005   /**
1006    * Receives notification when a column is removed from the column model.
1007    *
1008    * @param event the table column model event
1009    */
columnRemoved(TableColumnModelEvent event)1010   public void columnRemoved(TableColumnModelEvent event)
1011   {
1012     // TODO: What else to do here (if anything)?
1013     resizeAndRepaint();
1014   }
1015 
1016   /**
1017    * Receives notification when the column selection has changed.
1018    *
1019    * @param event the table column model event
1020    */
columnSelectionChanged(ListSelectionEvent event)1021   public void columnSelectionChanged(ListSelectionEvent event)
1022   {
1023     // TODO: What else to do here (if anything)?
1024     resizeAndRepaint();
1025   }
1026 
1027   /**
1028    * Validates the layout of this table header and repaints it. This is
1029    * equivalent to <code>revalidate()</code> followed by
1030    * <code>repaint()</code>.
1031    */
resizeAndRepaint()1032   public void resizeAndRepaint()
1033   {
1034     revalidate();
1035     repaint();
1036   }
1037 
1038   /**
1039    * Initializes the fields and properties of this class with default values.
1040    * This is called by the constructors.
1041    */
initializeLocalVars()1042   protected void initializeLocalVars()
1043   {
1044     accessibleContext = new AccessibleJTableHeader();
1045     draggedColumn = null;
1046     draggedDistance = 0;
1047     opaque = true;
1048     reorderingAllowed = true;
1049     resizingAllowed = true;
1050     resizingColumn = null;
1051     table = null;
1052     updateTableInRealTime = true;
1053     cellRenderer = createDefaultRenderer();
1054   }
1055 }
1056