View Javadoc

1   /*
2   This file is part of the xframe software package
3   hosted at http://xframe.sourceforge.net
4   
5   Copyright (c) 2003 Kurt Riede.
6   
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11  
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16  
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21  package net.sf.xframe.swing.table;
22  
23  import java.awt.Component;
24  import java.awt.Dimension;
25  import java.awt.Graphics;
26  import java.awt.Rectangle;
27  import java.util.Enumeration;
28  import java.util.Hashtable;
29  
30  import javax.swing.JComponent;
31  import javax.swing.JTable;
32  import javax.swing.plaf.basic.BasicTableHeaderUI;
33  import javax.swing.table.TableCellRenderer;
34  import javax.swing.table.TableColumn;
35  import javax.swing.table.TableColumnModel;
36  
37  /***
38   * UI of table headers with column groups.
39   *
40   * @see net.sf.xframe.swing.JXTable
41   * @see net.sf.xframe.swing.table.ColumnGroupHeader
42   *
43   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
44   */
45  public class ColumnGroupHeaderUI extends BasicTableHeaderUI {
46  
47      /*** Maximum header width. */
48      private static final long MAX_WIDTH = Integer.MAX_VALUE; //0x7fffffffL
49  
50      /***
51       * Constructor.
52       */
53      public ColumnGroupHeaderUI() {
54      }
55  
56      /***
57       * @see javax.swing.plaf.ComponentUI#paint(java.awt.Graphics, javax.swing.JComponent)
58       */
59      public final void paint(final Graphics graphics, final JComponent component) {
60          final Rectangle rectangle = graphics.getClipBounds();
61          if (super.header.getColumnModel() == null) {
62              return;
63          }
64          int columnIndex = 0;
65          final Dimension dimension = super.header.getSize();
66          final Rectangle rectangle1 = new Rectangle(0, 0, dimension.width, dimension.height);
67          final Hashtable hashtable = new Hashtable();
68          int margin = super.header.getColumnModel().getColumnMargin();
69          for (final Enumeration enumeration = super.header.getColumnModel().getColumns(); enumeration.hasMoreElements();) {
70              rectangle1.height = dimension.height;
71              rectangle1.y = 0;
72              final TableColumn tablecolumn = (TableColumn) enumeration.nextElement();
73              final Enumeration enumeration1 = ((ColumnGroupHeader) super.header).getColumnGroups(tablecolumn);
74              if (enumeration1 != null) {
75                  int height = 0;
76                  while (enumeration1.hasMoreElements()) {
77                      final ColumnGroup columngroup = (ColumnGroup) enumeration1.nextElement();
78                      Rectangle rectangle2 = (Rectangle) hashtable.get(columngroup);
79                      if (rectangle2 == null) {
80                          rectangle2 = new Rectangle(rectangle1);
81                          final Dimension dimension1 = columngroup.getSize(super.header.getTable());
82                          rectangle2.width = dimension1.width;
83                          rectangle2.width -= margin;
84                          rectangle2.height = dimension1.height;
85                          hashtable.put(columngroup, rectangle2);
86                      }
87                      paintCell(graphics, rectangle2, columngroup);
88                      height += rectangle2.height;
89                      rectangle1.height = dimension.height - height;
90                      rectangle1.y = height;
91                  }
92              }
93              rectangle1.width = tablecolumn.getWidth() - margin;
94              if (rectangle1.intersects(rectangle)) {
95                  paintCell(graphics, rectangle1, columnIndex);
96              }
97              rectangle1.x += tablecolumn.getWidth();
98              columnIndex++;
99          }
100     }
101 
102     /***
103      * Paints a column cell.
104      *
105      * @param graphics the graphics
106      * @param rect the rect
107      * @param columnIndex the column index
108      */
109     private void paintCell(final Graphics graphics, final Rectangle rect, final int columnIndex) {
110         final TableColumn tableColumn = super.header.getColumnModel().getColumn(columnIndex);
111         Object obj = tableColumn.getHeaderRenderer();
112         if (obj == null) {
113             obj = new DefaultColumnGroupHeaderRenderer();
114         }
115         final TableCellRenderer renderer = (TableCellRenderer) obj;
116         final JTable table = super.header.getTable();
117         final Object name = tableColumn.getHeaderValue();
118         final Component component = renderer.getTableCellRendererComponent(table, name, false, false, -1, columnIndex);
119         super.rendererPane.add(component);
120         super.rendererPane.paintComponent(graphics, component, super.header, rect.x, rect.y, rect.width, rect.height, true);
121     }
122 
123     /***
124      * Paints a column group cell.
125      *
126      * @param graphics the graphics
127      * @param rect the rect
128      * @param columnGroup the column group
129      */
130     private void paintCell(final Graphics graphics, final Rectangle rect, final ColumnGroup columnGroup) {
131         final TableCellRenderer renderer = columnGroup.getHeaderRenderer();
132         final JTable table = super.header.getTable();
133         final Object name = columnGroup.getHeaderValue();
134         final Component component = renderer.getTableCellRendererComponent(table, name, false, false, -1, -1);
135         super.rendererPane.add(component);
136         super.rendererPane.paintComponent(graphics, component, super.header, rect.x, rect.y, rect.width, rect.height, true);
137     }
138 
139     /***
140      * @see javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent)
141      */
142     public final Dimension getPreferredSize(final JComponent component) {
143         long width = 0L;
144         for (final Enumeration enumeration = super.header.getColumnModel().getColumns(); enumeration.hasMoreElements();) {
145             final TableColumn tablecolumn = (TableColumn) enumeration.nextElement();
146             width += tablecolumn.getPreferredWidth();
147         }
148         final TableColumnModel tableColumnModel = super.header.getColumnModel();
149         final long size = width + tableColumnModel.getColumnMargin() * tableColumnModel.getColumnCount();
150         return new Dimension((int) (size > MAX_WIDTH ? MAX_WIDTH : size), getHeaderHeight());
151     }
152 
153     /***
154      * Returns the height og the header.
155      *
156      * @return header height
157      */
158     private int getHeaderHeight() {
159         int height = 0;
160         final TableColumnModel tablecolumnmodel = super.header.getColumnModel();
161         for (int column = 0; column < tablecolumnmodel.getColumnCount(); column++) {
162             final TableColumn tableColumn = tablecolumnmodel.getColumn(column);
163             Object obj = tableColumn.getHeaderRenderer();
164             if (obj == null) {
165                 obj = new DefaultColumnGroupHeaderRenderer();
166             }
167             final TableCellRenderer renderer = (TableCellRenderer) obj;
168             final JTable table = super.header.getTable();
169             final Object name = tableColumn.getHeaderValue();
170             final Component component = (renderer).getTableCellRendererComponent(table, name, false, false, -1, column);
171             int k = component.getPreferredSize().height;
172             final Enumeration enumeration = ((ColumnGroupHeader) super.header).getColumnGroups(tableColumn);
173             if (enumeration != null) {
174                 while (enumeration.hasMoreElements()) {
175                     final ColumnGroup columngroup = (ColumnGroup) enumeration.nextElement();
176                     k += columngroup.getSize(super.header.getTable()).height;
177                 }
178             }
179             height = Math.max(height, k);
180         }
181         return height;
182     }
183 }