View Javadoc

1   /*
2    *  UnBBayes
3    *  Copyright (C) 2002, 2008 Universidade de Brasilia - http://www.unb.br
4    *
5    *  This file is part of UnBBayes.
6    *
7    *  UnBBayes is free software: you can redistribute it and/or modify
8    *  it under the terms of the GNU General Public License as published by
9    *  the Free Software Foundation, either version 3 of the License, or
10   *  (at your option) any later version.
11   *
12   *  UnBBayes 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
15   *  GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License
18   *  along with UnBBayes.  If not, see <http://www.gnu.org/licenses/>.
19   *
20   */
21  package unbbayes.gui.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  import java.util.Iterator;
30  import java.util.Vector;
31  
32  import javax.swing.JComponent;
33  import javax.swing.plaf.basic.BasicTableHeaderUI;
34  import javax.swing.table.TableCellRenderer;
35  import javax.swing.table.TableColumn;
36  import javax.swing.table.TableColumnModel;
37  
38  
39  /**
40   * This class paints groupable header cells. These can be a combination of
41   * normal header cells and groupable cells.
42   */
43  public class GroupableTableHeaderUI extends BasicTableHeaderUI {
44      
45      /**
46       * Contains a list of ColumnGroups that have already been painted
47       * in the current paint request.
48       */
49      protected Vector paintedGroups = new Vector();
50      
51      /**
52       * Paint a representation of the table header.
53       * @param g the Graphics context in which to paint
54       * @param c the component being painted; this argument is often ignored
55       */
56      public void paint(Graphics g, JComponent c) {
57          Rectangle clipBounds = g.getClipBounds();
58          GroupableTableColumnModel cm = (GroupableTableColumnModel)header.getColumnModel();
59          if (cm == null) return;
60          ((GroupableTableHeader)header).setColumnMargin();
61          int column = 0;
62          Dimension size = header.getSize();
63          Rectangle cellRect  = new Rectangle(0, 0, size.width, size.height);
64          Hashtable h = new Hashtable();
65          int columnMargin = cm.getColumnMargin();
66          
67          Enumeration columns = cm.getColumns();
68          while (columns.hasMoreElements()) {
69              cellRect.height = size.height;
70              cellRect.y      = 0;
71              TableColumn aColumn = (TableColumn)columns.nextElement();
72              Iterator colGrpIter = cm.getColumnGroups(aColumn);
73              if (colGrpIter != null) {
74                  int groupHeight = 0;
75                  while (colGrpIter.hasNext()) {
76                      ColumnGroup cGroup = (ColumnGroup)colGrpIter.next();
77                      Rectangle groupRect = (Rectangle)h.get(cGroup);
78                      if (groupRect == null) {
79                          groupRect = new Rectangle(cellRect);
80                          Dimension d = cGroup.getSize(header.getTable());
81                          groupRect.width  = d.width;
82                          groupRect.height = d.height;
83                          h.put(cGroup, groupRect);
84                      }
85                      if(!paintedGroups.contains(cGroup)) {
86                          paintCell(g, groupRect, cGroup);
87                          paintedGroups.add(cGroup);
88                      }
89                      groupHeight += groupRect.height;
90                      cellRect.height = size.height - groupHeight;
91                      cellRect.y      = groupHeight;
92                  }
93              }
94              cellRect.width = aColumn.getWidth();
95              if (cellRect.intersects(clipBounds)) {
96                  paintCell(g, cellRect, column);
97              }
98              cellRect.x += cellRect.width;
99              column++;
100         }
101         paintedGroups.clear();
102     }
103     
104     /**
105      * Paints a header column cell.
106      * @param g Graphics context
107      * @param cellRect The rectangle to contain the cell
108      * @param columnIndex The header column to be painted
109      */    
110     private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
111         TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
112         TableCellRenderer renderer = aColumn.getHeaderRenderer();
113         if(renderer == null) {
114             renderer = header.getDefaultRenderer();
115         }
116         Component component = renderer.getTableCellRendererComponent(
117         header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex);
118         rendererPane.add(component);
119         rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
120         cellRect.width, cellRect.height, true);
121     }
122     
123     /**
124      * Paint group column cell.
125      * @param g Graphics context
126      * @param cellRect Rectangle that the cell with be painted in
127      * @param cGroup Current column group
128      */    
129     private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) {
130         TableCellRenderer renderer = cGroup.getHeaderRenderer();
131         Component component = renderer.getTableCellRendererComponent(
132         header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1);
133         rendererPane.add(component);
134         rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
135         cellRect.width, cellRect.height, true);
136     }
137     
138     /**
139      * Calculate and return the height of the header.
140      * @return Header Height
141      */    
142     private int getHeaderHeight() {
143         int height = 0;
144         GroupableTableColumnModel columnModel = (GroupableTableColumnModel)header.getColumnModel();
145         for(int column = 0; column < columnModel.getColumnCount(); column++) {
146             TableColumn aColumn = columnModel.getColumn(column);
147             TableCellRenderer renderer = aColumn.getHeaderRenderer();
148             if(renderer == null) {
149                 renderer = header.getDefaultRenderer();
150             }
151             Component comp = renderer.getTableCellRendererComponent(
152             header.getTable(), aColumn.getHeaderValue(), false, false,-1, column);
153             int cHeight = comp.getPreferredSize().height;
154             Iterator iter = columnModel.getColumnGroups(aColumn);
155             if (iter != null) {
156                 while (iter.hasNext()) {
157                     ColumnGroup cGroup = (ColumnGroup)iter.next();
158                     cHeight += cGroup.getSize(header.getTable()).height;
159                 }
160             }
161             height = Math.max(height, cHeight);
162         }
163         return height;
164     }
165     
166     /**
167      * Calculate and return the dimension of the header.
168      * @param width Starting width to be used.
169      * @return Dimension of the header
170      */    
171     private Dimension createHeaderSize(long width) {
172         TableColumnModel columnModel = header.getColumnModel();
173         width += columnModel.getColumnMargin() * columnModel.getColumnCount();
174         if (width > Integer.MAX_VALUE) {
175             width = Integer.MAX_VALUE;
176         }
177         return new Dimension((int)width, getHeaderHeight());
178     }
179     
180     /**
181      * Invokes the getPreferredSize method on each UI handled by this object.
182      * @param c the component whose preferred size is being queried; this argument is ignored.
183      * @return the dimension of the whole header
184      */
185     public Dimension getPreferredSize(JComponent c) {
186         long width = 0;
187         Enumeration columns = header.getColumnModel().getColumns();
188         while (columns.hasMoreElements()) {
189             TableColumn aColumn = (TableColumn)columns.nextElement();
190             width = width + aColumn.getPreferredWidth();
191         }
192         return createHeaderSize(width);
193     }
194 }
195