001 /*
002 * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.table;
027
028 import javax.swing.*;
029 import javax.swing.table.TableCellRenderer;
030 import javax.swing.border.*;
031
032 import java.awt.Component;
033 import java.awt.Color;
034 import java.awt.Rectangle;
035
036 import java.io.Serializable;
037
038 /**
039 * The standard class for rendering (displaying) individual cells
040 * in a <code>JTable</code>.
041 * <p>
042 *
043 * <strong><a name="override">Implementation Note:</a></strong>
044 * This class inherits from <code>JLabel</code>, a standard component class.
045 * However <code>JTable</code> employs a unique mechanism for rendering
046 * its cells and therefore requires some slightly modified behavior
047 * from its cell renderer.
048 * The table class defines a single cell renderer and uses it as a
049 * as a rubber-stamp for rendering all cells in the table;
050 * it renders the first cell,
051 * changes the contents of that cell renderer,
052 * shifts the origin to the new location, re-draws it, and so on.
053 * The standard <code>JLabel</code> component was not
054 * designed to be used this way and we want to avoid
055 * triggering a <code>revalidate</code> each time the
056 * cell is drawn. This would greatly decrease performance because the
057 * <code>revalidate</code> message would be
058 * passed up the hierarchy of the container to determine whether any other
059 * components would be affected.
060 * As the renderer is only parented for the lifetime of a painting operation
061 * we similarly want to avoid the overhead associated with walking the
062 * hierarchy for painting operations.
063 * So this class
064 * overrides the <code>validate</code>, <code>invalidate</code>,
065 * <code>revalidate</code>, <code>repaint</code>, and
066 * <code>firePropertyChange</code> methods to be
067 * no-ops and override the <code>isOpaque</code> method solely to improve
068 * performance. If you write your own renderer,
069 * please keep this performance consideration in mind.
070 * <p>
071 *
072 * <strong>Warning:</strong>
073 * Serialized objects of this class will not be compatible with
074 * future Swing releases. The current serialization support is
075 * appropriate for short term storage or RMI between applications running
076 * the same version of Swing. As of 1.4, support for long term storage
077 * of all JavaBeans<sup><font size="-2">TM</font></sup>
078 * has been added to the <code>java.beans</code> package.
079 * Please see {@link java.beans.XMLEncoder}.
080 *
081 * @version 1.52 05/05/07
082 * @author Philip Milne
083 * @see JTable
084 */
085 public class DefaultTableCellRenderer extends JLabel implements
086 TableCellRenderer, Serializable {
087
088 /**
089 * An empty <code>Border</code>. This field might not be used. To change the
090 * <code>Border</code> used by this renderer override the
091 * <code>getTableCellRendererComponent</code> method and set the border
092 * of the returned component directly.
093 */
094 protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
095 private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(
096 1, 1, 1, 1);
097
098 // We need a place to store the color the JLabel should be returned
099 // to after its foreground and background colors have been set
100 // to the selection background color.
101 // These ivars will be made protected when their names are finalized.
102 private Color unselectedForeground;
103 private Color unselectedBackground;
104
105 /**
106 * Creates a default table cell renderer.
107 */
108 public DefaultTableCellRenderer() {
109 super ();
110 setOpaque(true);
111 setBorder(getNoFocusBorder());
112 }
113
114 private static Border getNoFocusBorder() {
115 if (System.getSecurityManager() != null) {
116 return SAFE_NO_FOCUS_BORDER;
117 } else {
118 return noFocusBorder;
119 }
120 }
121
122 /**
123 * Overrides <code>JComponent.setForeground</code> to assign
124 * the unselected-foreground color to the specified color.
125 *
126 * @param c set the foreground color to this value
127 */
128 public void setForeground(Color c) {
129 super .setForeground(c);
130 unselectedForeground = c;
131 }
132
133 /**
134 * Overrides <code>JComponent.setBackground</code> to assign
135 * the unselected-background color to the specified color.
136 *
137 * @param c set the background color to this value
138 */
139 public void setBackground(Color c) {
140 super .setBackground(c);
141 unselectedBackground = c;
142 }
143
144 /**
145 * Notification from the <code>UIManager</code> that the look and feel
146 * [L&F] has changed.
147 * Replaces the current UI object with the latest version from the
148 * <code>UIManager</code>.
149 *
150 * @see JComponent#updateUI
151 */
152 public void updateUI() {
153 super .updateUI();
154 setForeground(null);
155 setBackground(null);
156 }
157
158 // implements javax.swing.table.TableCellRenderer
159 /**
160 *
161 * Returns the default table cell renderer.
162 * <p>
163 * During a printing operation, this method will be called with
164 * <code>isSelected</code> and <code>hasFocus</code> values of
165 * <code>false</code> to prevent selection and focus from appearing
166 * in the printed output. To do other customization based on whether
167 * or not the table is being printed, check the return value from
168 * {@link javax.swing.JComponent#isPaintingForPrint()}.
169 *
170 * @param table the <code>JTable</code>
171 * @param value the value to assign to the cell at
172 * <code>[row, column]</code>
173 * @param isSelected true if cell is selected
174 * @param hasFocus true if cell has focus
175 * @param row the row of the cell to render
176 * @param column the column of the cell to render
177 * @return the default table cell renderer
178 * @see javax.swing.JComponent#isPaintingForPrint()
179 */
180 public Component getTableCellRendererComponent(JTable table,
181 Object value, boolean isSelected, boolean hasFocus,
182 int row, int column) {
183
184 Color fg = null;
185 Color bg = null;
186
187 JTable.DropLocation dropLocation = table.getDropLocation();
188 if (dropLocation != null && !dropLocation.isInsertRow()
189 && !dropLocation.isInsertColumn()
190 && dropLocation.getRow() == row
191 && dropLocation.getColumn() == column) {
192
193 fg = UIManager.getColor("Table.dropCellForeground");
194 bg = UIManager.getColor("Table.dropCellBackground");
195
196 isSelected = true;
197 }
198
199 if (isSelected) {
200 super .setForeground(fg == null ? table
201 .getSelectionForeground() : fg);
202 super .setBackground(bg == null ? table
203 .getSelectionBackground() : bg);
204 } else {
205 super
206 .setForeground(unselectedForeground != null ? unselectedForeground
207 : table.getForeground());
208 super
209 .setBackground(unselectedBackground != null ? unselectedBackground
210 : table.getBackground());
211 }
212
213 setFont(table.getFont());
214
215 if (hasFocus) {
216 Border border = null;
217 if (isSelected) {
218 border = UIManager
219 .getBorder("Table.focusSelectedCellHighlightBorder");
220 }
221 if (border == null) {
222 border = UIManager
223 .getBorder("Table.focusCellHighlightBorder");
224 }
225 setBorder(border);
226
227 if (!isSelected && table.isCellEditable(row, column)) {
228 Color col;
229 col = UIManager.getColor("Table.focusCellForeground");
230 if (col != null) {
231 super .setForeground(col);
232 }
233 col = UIManager.getColor("Table.focusCellBackground");
234 if (col != null) {
235 super .setBackground(col);
236 }
237 }
238 } else {
239 setBorder(getNoFocusBorder());
240 }
241
242 setValue(value);
243
244 return this ;
245 }
246
247 /*
248 * The following methods are overridden as a performance measure to
249 * to prune code-paths are often called in the case of renders
250 * but which we know are unnecessary. Great care should be taken
251 * when writing your own renderer to weigh the benefits and
252 * drawbacks of overriding methods like these.
253 */
254
255 /**
256 * Overridden for performance reasons.
257 * See the <a href="#override">Implementation Note</a>
258 * for more information.
259 */
260 public boolean isOpaque() {
261 Color back = getBackground();
262 Component p = getParent();
263 if (p != null) {
264 p = p.getParent();
265 }
266 // p should now be the JTable.
267 boolean colorMatch = (back != null) && (p != null)
268 && back.equals(p.getBackground()) && p.isOpaque();
269 return !colorMatch && super .isOpaque();
270 }
271
272 /**
273 * Overridden for performance reasons.
274 * See the <a href="#override">Implementation Note</a>
275 * for more information.
276 *
277 * @since 1.5
278 */
279 public void invalidate() {
280 }
281
282 /**
283 * Overridden for performance reasons.
284 * See the <a href="#override">Implementation Note</a>
285 * for more information.
286 */
287 public void validate() {
288 }
289
290 /**
291 * Overridden for performance reasons.
292 * See the <a href="#override">Implementation Note</a>
293 * for more information.
294 */
295 public void revalidate() {
296 }
297
298 /**
299 * Overridden for performance reasons.
300 * See the <a href="#override">Implementation Note</a>
301 * for more information.
302 */
303 public void repaint(long tm, int x, int y, int width, int height) {
304 }
305
306 /**
307 * Overridden for performance reasons.
308 * See the <a href="#override">Implementation Note</a>
309 * for more information.
310 */
311 public void repaint(Rectangle r) {
312 }
313
314 /**
315 * Overridden for performance reasons.
316 * See the <a href="#override">Implementation Note</a>
317 * for more information.
318 *
319 * @since 1.5
320 */
321 public void repaint() {
322 }
323
324 /**
325 * Overridden for performance reasons.
326 * See the <a href="#override">Implementation Note</a>
327 * for more information.
328 */
329 protected void firePropertyChange(String propertyName,
330 Object oldValue, Object newValue) {
331 // Strings get interned...
332 if (propertyName == "text"
333 || propertyName == "labelFor"
334 || propertyName == "displayedMnemonic"
335 || ((propertyName == "font" || propertyName == "foreground")
336 && oldValue != newValue && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
337
338 super .firePropertyChange(propertyName, oldValue, newValue);
339 }
340 }
341
342 /**
343 * Overridden for performance reasons.
344 * See the <a href="#override">Implementation Note</a>
345 * for more information.
346 */
347 public void firePropertyChange(String propertyName,
348 boolean oldValue, boolean newValue) {
349 }
350
351 /**
352 * Sets the <code>String</code> object for the cell being rendered to
353 * <code>value</code>.
354 *
355 * @param value the string value for this cell; if value is
356 * <code>null</code> it sets the text value to an empty string
357 * @see JLabel#setText
358 *
359 */
360 protected void setValue(Object value) {
361 setText((value == null) ? "" : value.toString());
362 }
363
364 /**
365 * A subclass of <code>DefaultTableCellRenderer</code> that
366 * implements <code>UIResource</code>.
367 * <code>DefaultTableCellRenderer</code> doesn't implement
368 * <code>UIResource</code>
369 * directly so that applications can safely override the
370 * <code>cellRenderer</code> property with
371 * <code>DefaultTableCellRenderer</code> subclasses.
372 * <p>
373 * <strong>Warning:</strong>
374 * Serialized objects of this class will not be compatible with
375 * future Swing releases. The current serialization support is
376 * appropriate for short term storage or RMI between applications running
377 * the same version of Swing. As of 1.4, support for long term storage
378 * of all JavaBeans<sup><font size="-2">TM</font></sup>
379 * has been added to the <code>java.beans</code> package.
380 * Please see {@link java.beans.XMLEncoder}.
381 */
382 public static class UIResource extends DefaultTableCellRenderer
383 implements javax.swing.plaf.UIResource {
384 }
385
386 }
|