1 package org.simantics.spreadsheet.ui;
\r
6 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
\r
7 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
\r
10 import java.awt.Color;
\r
11 import java.awt.Component;
\r
12 import java.awt.Dimension;
\r
13 import java.awt.Font;
\r
14 import java.awt.Rectangle;
\r
15 import java.io.Serializable;
\r
17 import javax.swing.JComponent;
\r
18 import javax.swing.JLabel;
\r
19 import javax.swing.JTable;
\r
20 import javax.swing.SwingConstants;
\r
21 import javax.swing.border.Border;
\r
22 import javax.swing.border.EmptyBorder;
\r
23 import javax.swing.table.TableCellRenderer;
\r
27 * The standard class for rendering (displaying) individual cells
\r
28 * in a <code>JTable</code>.
\r
31 * <strong><a name="override">Implementation Note:</a></strong>
\r
32 * This class inherits from <code>JLabel</code>, a standard component class.
\r
33 * However <code>JTable</code> employs a unique mechanism for rendering
\r
34 * its cells and therefore requires some slightly modified behavior
\r
35 * from its cell renderer.
\r
36 * The table class defines a single cell renderer and uses it as a
\r
37 * as a rubber-stamp for rendering all cells in the table;
\r
38 * it renders the first cell,
\r
39 * changes the contents of that cell renderer,
\r
40 * shifts the origin to the new location, re-draws it, and so on.
\r
41 * The standard <code>JLabel</code> component was not
\r
42 * designed to be used this way and we want to avoid
\r
43 * triggering a <code>revalidate</code> each time the
\r
44 * cell is drawn. This would greatly decrease performance because the
\r
45 * <code>revalidate</code> message would be
\r
46 * passed up the hierarchy of the container to determine whether any other
\r
47 * components would be affected.
\r
48 * As the renderer is only parented for the lifetime of a painting operation
\r
49 * we similarly want to avoid the overhead associated with walking the
\r
50 * hierarchy for painting operations.
\r
52 * overrides the <code>validate</code>, <code>invalidate</code>,
\r
53 * <code>revalidate</code>, <code>repaint</code>, and
\r
54 * <code>firePropertyChange</code> methods to be
\r
55 * no-ops and override the <code>isOpaque</code> method solely to improve
\r
56 * performance. If you write your own renderer,
\r
57 * please keep this performance consideration in mind.
\r
60 * <strong>Warning:</strong>
\r
61 * Serialized objects of this class will not be compatible with
\r
62 * future Swing releases. The current serialization support is
\r
63 * appropriate for short term storage or RMI between applications running
\r
64 * the same version of Swing. As of 1.4, support for long term storage
\r
65 * of all JavaBeans<sup><font size="-2">TM</font></sup>
\r
66 * has been added to the <code>java.beans</code> package.
\r
67 * Please see {@link java.beans.XMLEncoder}.
\r
70 * @author Philip Milne
\r
73 public class Renderer extends JLabel
\r
74 implements TableCellRenderer, Serializable
\r
77 private static final long serialVersionUID = 3056811790713043512L;
\r
80 * An empty <code>Border</code>. This field might not be used. To change the
\r
81 * <code>Border</code> used by this renderer override the
\r
82 * <code>getTableCellRendererComponent</code> method and set the border
\r
83 * of the returned component directly.
\r
85 private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);
\r
86 private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);
\r
87 protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
\r
89 // We need a place to store the color the JLabel should be returned
\r
90 // to after its foreground and background colors have been set
\r
91 // to the selection background color.
\r
92 // These ivars will be made protected when their names are finalized.
\r
93 private Color unselectedForeground;
\r
94 private Color unselectedBackground = new Color(240, 40, 40);
\r
97 * Creates a default table cell renderer.
\r
102 setBorder(getNoFocusBorder());
\r
103 setName("Table.cellRenderer");
\r
106 private Border getNoFocusBorder() {
\r
107 Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder");
\r
108 if (System.getSecurityManager() != null) {
\r
109 if (border != null) return border;
\r
110 return SAFE_NO_FOCUS_BORDER;
\r
111 } else if (border != null) {
\r
112 if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
\r
116 return noFocusBorder;
\r
120 * Overrides <code>JComponent.setForeground</code> to assign
\r
121 * the unselected-foreground color to the specified color.
\r
123 * @param c set the foreground color to this value
\r
125 public void setForeground(Color c) {
\r
126 super.setForeground(c);
\r
127 unselectedForeground = c;
\r
131 * Overrides <code>JComponent.setBackground</code> to assign
\r
132 * the unselected-background color to the specified color.
\r
134 * @param c set the background color to this value
\r
136 public void setBackground(Color c) {
\r
137 super.setBackground(c);
\r
138 unselectedBackground = c;
\r
142 * Notification from the <code>UIManager</code> that the look and feel
\r
143 * [L&F] has changed.
\r
144 * Replaces the current UI object with the latest version from the
\r
145 * <code>UIManager</code>.
\r
147 * @see JComponent#updateUI
\r
149 public void updateUI() {
\r
151 setForeground(null);
\r
152 setBackground(null);
\r
155 // implements javax.swing.table.TableCellRenderer
\r
158 * Returns the default table cell renderer.
\r
160 * During a printing operation, this method will be called with
\r
161 * <code>isSelected</code> and <code>hasFocus</code> values of
\r
162 * <code>false</code> to prevent selection and focus from appearing
\r
163 * in the printed output. To do other customization based on whether
\r
164 * or not the table is being printed, check the return value from
\r
165 * {@link javax.swing.JComponent#isPaintingForPrint()}.
\r
167 * @param table the <code>JTable</code>
\r
168 * @param value the value to assign to the cell at
\r
169 * <code>[row, column]</code>
\r
170 * @param isSelected true if cell is selected
\r
171 * @param hasFocus true if cell has focus
\r
172 * @param row the row of the cell to render
\r
173 * @param column the column of the cell to render
\r
174 * @return the default table cell renderer
\r
175 * @see javax.swing.JComponent#isPaintingForPrint()
\r
177 public Component getTableCellRendererComponent(JTable table, Object value_,
\r
178 boolean isSelected, boolean hasFocus, int row, int column) {
\r
183 CellValue value = (CellValue)value_;
\r
185 JTable.DropLocation dropLocation = table.getDropLocation();
\r
186 if (dropLocation != null
\r
187 && !dropLocation.isInsertRow()
\r
188 && !dropLocation.isInsertColumn()
\r
189 && dropLocation.getRow() == row
\r
190 && dropLocation.getColumn() == column) {
\r
192 fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
\r
193 bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
\r
198 int hAlign = value.align & 3;
\r
199 int vAlign = value.align >> 2;
\r
201 if(hAlign == 0) setHorizontalAlignment(SwingConstants.LEFT);
\r
202 else if(hAlign == 1) setHorizontalAlignment(SwingConstants.CENTER);
\r
203 else if(hAlign == 2) setHorizontalAlignment(SwingConstants.RIGHT);
\r
205 if(vAlign == 0) setVerticalAlignment(SwingConstants.TOP);
\r
206 else if(vAlign == 1) setVerticalAlignment(SwingConstants.CENTER);
\r
207 else if(vAlign == 2) setVerticalAlignment(SwingConstants.BOTTOM);
\r
210 super.setForeground(fg == null ? table.getSelectionForeground()
\r
212 super.setBackground(bg == null ? table.getSelectionBackground()
\r
215 Color background = value.background != null
\r
217 : table.getBackground();
\r
218 Color foreground = value.foreground != null
\r
220 : table.getForeground();
\r
221 super.setForeground(foreground);
\r
222 super.setBackground(background);
\r
225 Font f = value.font;
\r
229 setFont(table.getFont());
\r
232 Border border = null;
\r
234 border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");
\r
236 if (border == null) {
\r
237 border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");
\r
241 if (!isSelected && table.isCellEditable(row, column)) {
\r
243 col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");
\r
245 super.setForeground(col);
\r
247 col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");
\r
249 super.setBackground(col);
\r
253 setBorder(value.getBorder());
\r
256 setValue(value.label);
\r
263 * The following methods are overridden as a performance measure to
\r
264 * to prune code-paths are often called in the case of renders
\r
265 * but which we know are unnecessary. Great care should be taken
\r
266 * when writing your own renderer to weigh the benefits and
\r
267 * drawbacks of overriding methods like these.
\r
271 * Overridden for performance reasons.
\r
272 * See the <a href="#override">Implementation Note</a>
\r
273 * for more information.
\r
275 public boolean isOpaque() {
\r
276 Color back = getBackground();
\r
277 Component p = getParent();
\r
279 p = p.getParent();
\r
282 // p should now be the JTable.
\r
283 boolean colorMatch = (back != null) && (p != null) &&
\r
284 back.equals(p.getBackground()) &&
\r
286 return !colorMatch && super.isOpaque();
\r
290 * Overridden for performance reasons.
\r
291 * See the <a href="#override">Implementation Note</a>
\r
292 * for more information.
\r
296 public void invalidate() {}
\r
299 * Overridden for performance reasons.
\r
300 * See the <a href="#override">Implementation Note</a>
\r
301 * for more information.
\r
303 public void validate() {}
\r
306 * Overridden for performance reasons.
\r
307 * See the <a href="#override">Implementation Note</a>
\r
308 * for more information.
\r
310 public void revalidate() {}
\r
313 * Overridden for performance reasons.
\r
314 * See the <a href="#override">Implementation Note</a>
\r
315 * for more information.
\r
317 public void repaint(long tm, int x, int y, int width, int height) {}
\r
320 * Overridden for performance reasons.
\r
321 * See the <a href="#override">Implementation Note</a>
\r
322 * for more information.
\r
324 public void repaint(Rectangle r) { }
\r
327 * Overridden for performance reasons.
\r
328 * See the <a href="#override">Implementation Note</a>
\r
329 * for more information.
\r
333 public void repaint() {
\r
337 * Overridden for performance reasons.
\r
338 * See the <a href="#override">Implementation Note</a>
\r
339 * for more information.
\r
341 protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
\r
342 // Strings get interned...
\r
343 if (propertyName=="text"
\r
344 || propertyName == "labelFor"
\r
345 || propertyName == "displayedMnemonic"
\r
346 || ((propertyName == "font" || propertyName == "foreground")
\r
347 && oldValue != newValue
\r
348 && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
\r
350 super.firePropertyChange(propertyName, oldValue, newValue);
\r
355 * Overridden for performance reasons.
\r
356 * See the <a href="#override">Implementation Note</a>
\r
357 * for more information.
\r
359 public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
\r
363 * Sets the <code>String</code> object for the cell being rendered to
\r
364 * <code>value</code>.
\r
366 * @param value the string value for this cell; if value is
\r
367 * <code>null</code> it sets the text value to an empty string
\r
368 * @see JLabel#setText
\r
371 protected void setValue(Object value) {
\r
372 setText((value == null) ? "" : value.toString());
\r
377 * A subclass of <code>DefaultTableCellRenderer</code> that
\r
378 * implements <code>UIResource</code>.
\r
379 * <code>DefaultTableCellRenderer</code> doesn't implement
\r
380 * <code>UIResource</code>
\r
381 * directly so that applications can safely override the
\r
382 * <code>cellRenderer</code> property with
\r
383 * <code>DefaultTableCellRenderer</code> subclasses.
\r
385 * <strong>Warning:</strong>
\r
386 * Serialized objects of this class will not be compatible with
\r
387 * future Swing releases. The current serialization support is
\r
388 * appropriate for short term storage or RMI between applications running
\r
389 * the same version of Swing. As of 1.4, support for long term storage
\r
390 * of all JavaBeans<sup><font size="-2">TM</font></sup>
\r
391 * has been added to the <code>java.beans</code> package.
\r
392 * Please see {@link java.beans.XMLEncoder}.
\r
394 public static class UIResource extends Renderer
\r
395 implements javax.swing.plaf.UIResource
\r