KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > looks > windows > WindowsXPTableHeaderUI


1 /*
2  * Copyright (c) 2001-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.looks.windows;
32
33 import java.awt.Component JavaDoc;
34 import java.awt.Graphics JavaDoc;
35 import java.awt.Point JavaDoc;
36 import java.awt.Rectangle JavaDoc;
37
38 import javax.swing.JComponent JavaDoc;
39 import javax.swing.JTable JavaDoc;
40 import javax.swing.plaf.ComponentUI JavaDoc;
41 import javax.swing.table.TableCellRenderer JavaDoc;
42 import javax.swing.table.TableColumn JavaDoc;
43 import javax.swing.table.TableColumnModel JavaDoc;
44
45 import com.sun.java.swing.plaf.windows.WindowsTableHeaderUI;
46
47
48 /**
49  * The JGoodies Windows L&amp;F implementation of <code>TableHeaderUI</code>.
50  * A Windows table header that honors the XP header style even if the user
51  * uses custom non-opaque renderers. The renderers should be a subclass of
52  * <code>JComponent</code> because we need to replace the border by the one
53  * specified in the XP style.
54  *
55  * @author Andrej Golovnin
56  * @version $Revision: 1.2 $
57  */

58 public final class WindowsXPTableHeaderUI extends WindowsTableHeaderUI {
59
60     private TableCellRenderer JavaDoc xpRenderer;
61
62     public static ComponentUI JavaDoc createUI(JComponent JavaDoc h) {
63         return new WindowsXPTableHeaderUI();
64     }
65
66     public void installUI(JComponent JavaDoc c) {
67         super.installUI(c);
68         xpRenderer = header.getDefaultRenderer();
69     }
70
71     public void uninstallUI(JComponent JavaDoc c) {
72         xpRenderer = null;
73         super.uninstallUI(c);
74     }
75
76     public void paint(Graphics JavaDoc g, JComponent JavaDoc c) {
77         TableColumnModel JavaDoc cm = header.getColumnModel();
78         if (cm.getColumnCount() <= 0) {
79             return;
80         }
81         boolean ltr = header.getComponentOrientation().isLeftToRight();
82
83         Rectangle JavaDoc clip = g.getClipBounds();
84         Point JavaDoc left = clip.getLocation();
85         Point JavaDoc right = new Point JavaDoc(clip.x + clip.width - 1, clip.y);
86         int cMin = header.columnAtPoint(ltr ? left : right);
87         int cMax = header.columnAtPoint(ltr ? right : left);
88         // This should never happen.
89
if (cMin == -1) {
90             cMin = 0;
91         }
92         // If the table does not have enough columns to fill the view we'll get
93
// -1.
94
// Replace this with the index of the last column.
95
if (cMax == -1) {
96             cMax = cm.getColumnCount() - 1;
97         }
98
99         TableColumn JavaDoc draggedColumn = header.getDraggedColumn();
100         int columnWidth;
101         int columnMargin = cm.getColumnMargin();
102         Rectangle JavaDoc cellRect = header.getHeaderRect(cMin);
103         TableColumn JavaDoc aColumn;
104         if (ltr) {
105             for (int column = cMin; column <= cMax; column++) {
106                 aColumn = cm.getColumn(column);
107                 columnWidth = aColumn.getWidth();
108                 cellRect.width = columnWidth - columnMargin;
109                 if (aColumn != draggedColumn) {
110                     paintCell(g, cellRect, column);
111                 }
112                 cellRect.x += columnWidth;
113             }
114         } else {
115             aColumn = cm.getColumn(cMin);
116             if (aColumn != draggedColumn) {
117                 columnWidth = aColumn.getWidth();
118                 cellRect.width = columnWidth - columnMargin;
119                 cellRect.x += columnMargin;
120                 paintCell(g, cellRect, cMin);
121             }
122             for (int column = cMin + 1; column <= cMax; column++) {
123                 aColumn = cm.getColumn(column);
124                 columnWidth = aColumn.getWidth();
125                 cellRect.width = columnWidth - columnMargin;
126                 cellRect.x -= columnWidth;
127                 if (aColumn != draggedColumn) {
128                     paintCell(g, cellRect, column);
129                 }
130             }
131         }
132
133         // Paint the dragged column if we are dragging.
134
if (draggedColumn != null) {
135             int draggedColumnIndex = viewIndexForColumn(draggedColumn);
136             Rectangle JavaDoc draggedCellRect = header
137                     .getHeaderRect(draggedColumnIndex);
138
139             // Draw a gray well in place of the moving column.
140
g.setColor(header.getParent().getBackground());
141             g.fillRect(draggedCellRect.x, draggedCellRect.y,
142                     draggedCellRect.width, draggedCellRect.height);
143
144             draggedCellRect.x += header.getDraggedDistance();
145
146             // Fill the background.
147
g.setColor(header.getBackground());
148             g.fillRect(draggedCellRect.x, draggedCellRect.y,
149                     draggedCellRect.width, draggedCellRect.height);
150
151             paintCell(g, draggedCellRect, draggedColumnIndex);
152         }
153
154         // Remove all components in the rendererPane.
155
rendererPane.removeAll();
156     }
157
158     private void paintCell(Graphics JavaDoc g, Rectangle JavaDoc cellRect, int columnIndex) {
159         TableColumn JavaDoc aColumn = header.getColumnModel().getColumn(columnIndex);
160         TableCellRenderer JavaDoc renderer = aColumn.getHeaderRenderer();
161         if (renderer == null) {
162             renderer = header.getDefaultRenderer();
163         }
164
165         JTable JavaDoc table = header.getTable();
166         Component JavaDoc c = renderer.getTableCellRendererComponent(table,
167                 aColumn.getHeaderValue(), false, false, -1, columnIndex);
168
169         if (renderer != xpRenderer) {
170             // The DefaultTableCellRenderer is used in the most cases as
171
// the base class for all header renderers. And due to
172
// the optimizations in its #isOpaque method, we have to add
173
// the component to the renderer pane to determine its
174
// non-opaqueness.
175
rendererPane.add(c);
176             boolean nonOpaque = !c.isOpaque();
177             if (nonOpaque) {
178                 Component JavaDoc background = xpRenderer
179                         .getTableCellRendererComponent(table, null, false,
180                                 false, -1, columnIndex);
181                 rendererPane.paintComponent(g, background, header, cellRect.x,
182                         cellRect.y, cellRect.width, cellRect.height, true);
183
184                 // All custom header renderers will use TableHeader.cellBorder
185
// returned by UIManager#getBorder. But this one does not
186
// comply with the Windows XP style. It is the one used by
187
// Windows Classis L&F. So replace the border of the custom
188
// renderers component by the one which comply with XP style.
189
if ((c instanceof JComponent JavaDoc)
190                         && (background instanceof JComponent JavaDoc)) {
191                     ((JComponent JavaDoc) c).setBorder(
192                             ((JComponent JavaDoc) background).getBorder());
193                 }
194             }
195         }
196
197         rendererPane.paintComponent(g, c, header, cellRect.x, cellRect.y,
198                 cellRect.width, cellRect.height, true);
199     }
200
201     private int viewIndexForColumn(TableColumn JavaDoc aColumn) {
202         TableColumnModel JavaDoc cm = header.getColumnModel();
203         for (int column = cm.getColumnCount() - 1; column >= 0; column--) {
204             if (cm.getColumn(column) == aColumn) {
205                 return column;
206             }
207         }
208         return -1;
209     }
210
211 }
212
Popular Tags