001    /* JTableHeader.java --
002       Copyright (C) 2003, 2004, 2005, 2006,  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.swing.table;
040    
041    import java.awt.Color;
042    import java.awt.Component;
043    import java.awt.Cursor;
044    import java.awt.Dimension;
045    import java.awt.Font;
046    import java.awt.FontMetrics;
047    import java.awt.Point;
048    import java.awt.Rectangle;
049    import java.awt.event.FocusListener;
050    import java.beans.PropertyChangeListener;
051    import java.util.Locale;
052    
053    import javax.accessibility.Accessible;
054    import javax.accessibility.AccessibleAction;
055    import javax.accessibility.AccessibleComponent;
056    import javax.accessibility.AccessibleContext;
057    import javax.accessibility.AccessibleRole;
058    import javax.accessibility.AccessibleSelection;
059    import javax.accessibility.AccessibleStateSet;
060    import javax.accessibility.AccessibleText;
061    import javax.accessibility.AccessibleValue;
062    import javax.swing.JComponent;
063    import javax.swing.JTable;
064    import javax.swing.UIManager;
065    import javax.swing.event.ChangeEvent;
066    import javax.swing.event.ListSelectionEvent;
067    import javax.swing.event.TableColumnModelEvent;
068    import javax.swing.event.TableColumnModelListener;
069    import javax.swing.plaf.TableHeaderUI;
070    
071    /**
072     * Represents the table header. The header displays the column header values,
073     * is always visible event if the rest of the table scrolls up and down and
074     * supports column reordering and resizing with mouse.
075     */
076    public class JTableHeader extends JComponent
077      implements TableColumnModelListener, Accessible
078    {
079      protected class AccessibleJTableHeader extends AccessibleJComponent
080      {
081        protected class AccessibleJTableHeaderEntry extends AccessibleContext
082          implements Accessible, AccessibleComponent
083        {
084    
085          private int columnIndex;
086    
087          private JTableHeader parent;
088    
089          private JTable table;
090    
091          public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)
092          {
093            columnIndex = c;
094            parent = p;
095            table = t;
096          }
097    
098          /**
099           * Returns the column header renderer.
100           *
101           * @return The column header renderer.
102           */
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           */
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           */
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           */
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    
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    
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    
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           */
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           */
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           */
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           */
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           */
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           */
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           */
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           */
265          public AccessibleRole getAccessibleRole()
266          {
267            AccessibleContext ac = getAccessibleColumnHeaderRenderer();
268            if (ac != null)
269              return ac.getAccessibleRole();
270            else
271              return null;
272          }
273    
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    
283          public AccessibleStateSet getAccessibleStateSet()
284          {
285            AccessibleContext ac = getAccessibleColumnHeaderRenderer();
286            if (ac != null)
287              return ac.getAccessibleStateSet();
288            else
289              return null;
290          }
291    
292          public AccessibleText getAccessibleText()
293          {
294            AccessibleContext ac = getAccessibleColumnHeaderRenderer();
295            if (ac != null)
296              return ac.getAccessibleText();
297            else
298              return null;
299          }
300    
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    
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    
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    
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    
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    
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    
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    
370          public Locale getLocale()
371          {
372            Component c = getColumnHeaderRenderer();
373            if (c != null)
374              return c.getLocale();
375            return null;
376          }
377    
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    
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    
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    
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    
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    
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    
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           */
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           */
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           */
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           */
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           */
495          public void setAccessibleName(String s)
496          {
497            AccessibleContext ac = getAccessibleColumnHeaderRenderer();
498            if (ac != null)
499              ac.setAccessibleName(s);
500          }
501    
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    
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    
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    
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    
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    
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    
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    
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    
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    
575        public AccessibleRole getAccessibleRole()
576        {
577          return AccessibleRole.PANEL;
578        }
579    
580        public int getAccessibleChildrenCount()
581        {
582          return table.getColumnCount();
583        }
584    
585        public Accessible getAccessibleChild(int i)
586        {
587          return new AccessibleJTableHeaderEntry(i, JTableHeader.this, table);
588        }
589    
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
923      public Rectangle getHeaderRect(int column)
924      {
925        Rectangle r = getTable().getCellRect(-1, column, false);
926        r.height = getHeight();
927        return r;
928      }
929    
930      protected String paramString()
931      {
932        return "JTableHeader";
933      }
934    
935      // UI support
936    
937      public String getUIClassID()
938      {
939        return "TableHeaderUI";
940      }
941    
942      public TableHeaderUI getUI()
943      {
944        return (TableHeaderUI) ui;
945      }
946    
947      public void setUI(TableHeaderUI u)
948      {
949        super.setUI(u);
950      }
951    
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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       */
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    }