]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/Renderer.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.spreadsheet.ui / src / org / simantics / spreadsheet / ui / Renderer.java
1 package org.simantics.spreadsheet.ui;
2
3 /*
4  * %W% %E%
5  *
6  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
7  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
8  */
9
10 import java.awt.Color;
11 import java.awt.Component;
12 import java.awt.Dimension;
13 import java.awt.Font;
14 import java.awt.Rectangle;
15 import java.io.Serializable;
16
17 import javax.swing.JComponent;
18 import javax.swing.JLabel;
19 import javax.swing.JTable;
20 import javax.swing.SwingConstants;
21 import javax.swing.border.Border;
22 import javax.swing.border.EmptyBorder;
23 import javax.swing.table.TableCellRenderer;
24
25
26 /**
27  * The standard class for rendering (displaying) individual cells
28  * in a <code>JTable</code>.
29  * <p>
30  *
31  * <strong><a name="override">Implementation Note:</a></strong>
32  * This class inherits from <code>JLabel</code>, a standard component class. 
33  * However <code>JTable</code> employs a unique mechanism for rendering
34  * its cells and therefore requires some slightly modified behavior
35  * from its cell renderer.  
36  * The table class defines a single cell renderer and uses it as a 
37  * as a rubber-stamp for rendering all cells in the table; 
38  * it renders the first cell,
39  * changes the contents of that cell renderer, 
40  * shifts the origin to the new location, re-draws it, and so on.
41  * The standard <code>JLabel</code> component was not
42  * designed to be used this way and we want to avoid 
43  * triggering a <code>revalidate</code> each time the
44  * cell is drawn. This would greatly decrease performance because the
45  * <code>revalidate</code> message would be
46  * passed up the hierarchy of the container to determine whether any other
47  * components would be affected.  
48  * As the renderer is only parented for the lifetime of a painting operation
49  * we similarly want to avoid the overhead associated with walking the
50  * hierarchy for painting operations.
51  * So this class
52  * overrides the <code>validate</code>, <code>invalidate</code>,
53  * <code>revalidate</code>, <code>repaint</code>, and
54  * <code>firePropertyChange</code> methods to be 
55  * no-ops and override the <code>isOpaque</code> method solely to improve
56  * performance.  If you write your own renderer,
57  * please keep this performance consideration in mind.
58  * <p>
59  *
60  * <strong>Warning:</strong>
61  * Serialized objects of this class will not be compatible with
62  * future Swing releases. The current serialization support is
63  * appropriate for short term storage or RMI between applications running
64  * the same version of Swing.  As of 1.4, support for long term storage
65  * of all JavaBeans<sup><font size="-2">TM</font></sup>
66  * has been added to the <code>java.beans</code> package.
67  * Please see {@link java.beans.XMLEncoder}.
68  *
69  * @version %I% %G%
70  * @author Philip Milne 
71  * @see JTable
72  */
73 public class Renderer extends JLabel
74 implements TableCellRenderer, Serializable
75 {
76
77         private static final long serialVersionUID = 3056811790713043512L;
78
79         /**
80          * An empty <code>Border</code>. This field might not be used. To change the
81          * <code>Border</code> used by this renderer override the 
82          * <code>getTableCellRendererComponent</code> method and set the border
83          * of the returned component directly.
84          */
85         private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);
86         private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);
87         protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
88
89         // We need a place to store the color the JLabel should be returned 
90         // to after its foreground and background colors have been set 
91         // to the selection background color. 
92         // These ivars will be made protected when their names are finalized. 
93         private Color unselectedForeground; 
94         private Color unselectedBackground = new Color(240, 40, 40); 
95
96         /**
97          * Creates a default table cell renderer.
98          */
99         public Renderer() {
100                 super();
101                 setOpaque(true);
102                 setBorder(getNoFocusBorder());
103                 setName("Table.cellRenderer");
104         }
105
106         private Border getNoFocusBorder() {
107                 Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder");
108                 if (System.getSecurityManager() != null) {
109                         if (border != null) return border;
110                         return SAFE_NO_FOCUS_BORDER;
111                 } else if (border != null) {
112                         if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
113                                 return border;
114                         }
115                 }
116                 return noFocusBorder;
117         }
118
119         /**
120          * Overrides <code>JComponent.setForeground</code> to assign
121          * the unselected-foreground color to the specified color.
122          * 
123          * @param c set the foreground color to this value
124          */
125         public void setForeground(Color c) {
126                 super.setForeground(c); 
127                 unselectedForeground = c; 
128         }
129
130         /**
131          * Overrides <code>JComponent.setBackground</code> to assign
132          * the unselected-background color to the specified color.
133          *
134          * @param c set the background color to this value
135          */
136         public void setBackground(Color c) {
137                 super.setBackground(c); 
138                 unselectedBackground = c; 
139         }
140
141         /**
142          * Notification from the <code>UIManager</code> that the look and feel
143          * [L&F] has changed.
144          * Replaces the current UI object with the latest version from the 
145          * <code>UIManager</code>.
146          *
147          * @see JComponent#updateUI
148          */
149         public void updateUI() {
150                 super.updateUI(); 
151                 setForeground(null);
152                 setBackground(null);
153         }
154
155         // implements javax.swing.table.TableCellRenderer
156         /**
157          *
158          * Returns the default table cell renderer.
159          * <p>
160          * During a printing operation, this method will be called with
161          * <code>isSelected</code> and <code>hasFocus</code> values of
162          * <code>false</code> to prevent selection and focus from appearing
163          * in the printed output. To do other customization based on whether
164          * or not the table is being printed, check the return value from
165          * {@link javax.swing.JComponent#isPaintingForPrint()}.
166          *
167          * @param table  the <code>JTable</code>
168          * @param value  the value to assign to the cell at
169          *                      <code>[row, column]</code>
170          * @param isSelected true if cell is selected
171          * @param hasFocus true if cell has focus
172          * @param row  the row of the cell to render
173          * @param column the column of the cell to render
174          * @return the default table cell renderer
175          * @see javax.swing.JComponent#isPaintingForPrint()
176          */
177         public Component getTableCellRendererComponent(JTable table, Object value_,
178                         boolean isSelected, boolean hasFocus, int row, int column) {
179
180                 Color fg = null;
181                 Color bg = null;
182
183                 CellValue value = (CellValue)value_;
184                 
185                 JTable.DropLocation dropLocation = table.getDropLocation();
186                 if (dropLocation != null
187                                 && !dropLocation.isInsertRow()
188                                 && !dropLocation.isInsertColumn()
189                                 && dropLocation.getRow() == row
190                                 && dropLocation.getColumn() == column) {
191
192                         fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
193                         bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
194
195                         isSelected = true;
196                 }
197
198                 int hAlign = value.align & 3;
199                 int vAlign = value.align >> 2;
200                 
201                 if(hAlign == 0) setHorizontalAlignment(SwingConstants.LEFT);
202                 else if(hAlign == 1) setHorizontalAlignment(SwingConstants.CENTER);
203                 else if(hAlign == 2) setHorizontalAlignment(SwingConstants.RIGHT);
204
205                 if(vAlign == 0) setVerticalAlignment(SwingConstants.TOP);
206                 else if(vAlign == 1) setVerticalAlignment(SwingConstants.CENTER);
207                 else if(vAlign == 2) setVerticalAlignment(SwingConstants.BOTTOM);
208                 
209                 if (isSelected) {
210                         super.setForeground(fg == null ? table.getSelectionForeground()
211                                         : fg);
212                         super.setBackground(bg == null ? table.getSelectionBackground()
213                                         : bg);
214                 } else {
215                         Color background = value.background != null
216                                         ? value.background
217                                                         : table.getBackground();
218                         Color foreground = value.foreground != null
219                                         ? value.foreground
220                                                         : table.getForeground();
221                         super.setForeground(foreground);
222                         super.setBackground(background);
223                 }
224
225                 Font f = value.font;
226                 if(f != null)
227                         setFont(f);
228                 else
229                         setFont(table.getFont());
230
231                 if (hasFocus) {
232                         Border border = null;
233                         if (isSelected) {
234                                 border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");
235                         }
236                         if (border == null) {
237                                 border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");
238                         }
239                         setBorder(border);
240
241                         if (!isSelected && table.isCellEditable(row, column)) {
242                                 Color col;
243                                 col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");
244                                 if (col != null) {
245                                         super.setForeground(col);
246                                 }
247                                 col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");
248                                 if (col != null) {
249                                         super.setBackground(col);
250                                 }
251                         }
252                 } else {
253                         setBorder(value.getBorder());
254                 }
255
256                 setValue(value.label); 
257
258                 return this;
259                 
260         }
261
262         /*
263          * The following methods are overridden as a performance measure to 
264          * to prune code-paths are often called in the case of renders
265          * but which we know are unnecessary.  Great care should be taken
266          * when writing your own renderer to weigh the benefits and 
267          * drawbacks of overriding methods like these.
268          */
269
270         /**
271          * Overridden for performance reasons.
272          * See the <a href="#override">Implementation Note</a> 
273          * for more information.
274          */
275         public boolean isOpaque() { 
276                 Color back = getBackground();
277                 Component p = getParent(); 
278                 if (p != null) { 
279                         p = p.getParent(); 
280                 }
281
282                 // p should now be the JTable. 
283                 boolean colorMatch = (back != null) && (p != null) && 
284                                 back.equals(p.getBackground()) && 
285                                 p.isOpaque();
286                 return !colorMatch && super.isOpaque(); 
287         }
288
289         /**
290          * Overridden for performance reasons.
291          * See the <a href="#override">Implementation Note</a> 
292          * for more information.
293          *
294          * @since 1.5
295          */
296         public void invalidate() {}
297
298         /**
299          * Overridden for performance reasons.
300          * See the <a href="#override">Implementation Note</a> 
301          * for more information.
302          */
303         public void validate() {}
304
305         /**
306          * Overridden for performance reasons.
307          * See the <a href="#override">Implementation Note</a> 
308          * for more information.
309          */
310         public void revalidate() {}
311
312         /**
313          * Overridden for performance reasons.
314          * See the <a href="#override">Implementation Note</a> 
315          * for more information.
316          */
317         public void repaint(long tm, int x, int y, int width, int height) {}
318
319         /**
320          * Overridden for performance reasons.
321          * See the <a href="#override">Implementation Note</a> 
322          * for more information.
323          */
324         public void repaint(Rectangle r) { }
325
326         /**
327          * Overridden for performance reasons.
328          * See the <a href="#override">Implementation Note</a> 
329          * for more information.
330          *
331          * @since 1.5
332          */
333         public void repaint() {
334         }
335
336         /**
337          * Overridden for performance reasons.
338          * See the <a href="#override">Implementation Note</a> 
339          * for more information.
340          */
341         protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {      
342                 // Strings get interned...
343                 if (propertyName=="text"
344                                 || propertyName == "labelFor"
345                                 || propertyName == "displayedMnemonic"
346                                 || ((propertyName == "font" || propertyName == "foreground")
347                                                 && oldValue != newValue
348                                                 && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
349
350                         super.firePropertyChange(propertyName, oldValue, newValue);
351                 }
352         }
353
354         /**
355          * Overridden for performance reasons.
356          * See the <a href="#override">Implementation Note</a> 
357          * for more information.
358          */
359         public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
360
361
362         /**
363          * Sets the <code>String</code> object for the cell being rendered to
364          * <code>value</code>.
365          * 
366          * @param value  the string value for this cell; if value is
367          *              <code>null</code> it sets the text value to an empty string
368          * @see JLabel#setText
369          * 
370          */
371         protected void setValue(Object value) {
372                 setText((value == null) ? "" : value.toString());
373         }
374
375
376         /**
377          * A subclass of <code>DefaultTableCellRenderer</code> that
378          * implements <code>UIResource</code>.
379          * <code>DefaultTableCellRenderer</code> doesn't implement
380          * <code>UIResource</code>
381          * directly so that applications can safely override the
382          * <code>cellRenderer</code> property with
383          * <code>DefaultTableCellRenderer</code> subclasses.
384          * <p>
385          * <strong>Warning:</strong>
386          * Serialized objects of this class will not be compatible with
387          * future Swing releases. The current serialization support is
388          * appropriate for short term storage or RMI between applications running
389          * the same version of Swing.  As of 1.4, support for long term storage
390          * of all JavaBeans<sup><font size="-2">TM</font></sup>
391          * has been added to the <code>java.beans</code> package.
392          * Please see {@link java.beans.XMLEncoder}.
393          */
394         public static class UIResource extends Renderer 
395         implements javax.swing.plaf.UIResource
396         {
397         }
398
399 }
400
401