]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/Renderer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.spreadsheet.ui / src / org / simantics / spreadsheet / ui / Renderer.java
1 package org.simantics.spreadsheet.ui;\r
2 \r
3 /*\r
4  * %W% %E%\r
5  *\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
8  */\r
9 \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
16 \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
24 \r
25 \r
26 /**\r
27  * The standard class for rendering (displaying) individual cells\r
28  * in a <code>JTable</code>.\r
29  * <p>\r
30  *\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
51  * So this class\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
58  * <p>\r
59  *\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
68  *\r
69  * @version %I% %G%\r
70  * @author Philip Milne \r
71  * @see JTable\r
72  */\r
73 public class Renderer extends JLabel\r
74 implements TableCellRenderer, Serializable\r
75 {\r
76 \r
77         private static final long serialVersionUID = 3056811790713043512L;\r
78 \r
79         /**\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
84          */\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
88 \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
95 \r
96         /**\r
97          * Creates a default table cell renderer.\r
98          */\r
99         public Renderer() {\r
100                 super();\r
101                 setOpaque(true);\r
102                 setBorder(getNoFocusBorder());\r
103                 setName("Table.cellRenderer");\r
104         }\r
105 \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
113                                 return border;\r
114                         }\r
115                 }\r
116                 return noFocusBorder;\r
117         }\r
118 \r
119         /**\r
120          * Overrides <code>JComponent.setForeground</code> to assign\r
121          * the unselected-foreground color to the specified color.\r
122          * \r
123          * @param c set the foreground color to this value\r
124          */\r
125         public void setForeground(Color c) {\r
126                 super.setForeground(c); \r
127                 unselectedForeground = c; \r
128         }\r
129 \r
130         /**\r
131          * Overrides <code>JComponent.setBackground</code> to assign\r
132          * the unselected-background color to the specified color.\r
133          *\r
134          * @param c set the background color to this value\r
135          */\r
136         public void setBackground(Color c) {\r
137                 super.setBackground(c); \r
138                 unselectedBackground = c; \r
139         }\r
140 \r
141         /**\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
146          *\r
147          * @see JComponent#updateUI\r
148          */\r
149         public void updateUI() {\r
150                 super.updateUI(); \r
151                 setForeground(null);\r
152                 setBackground(null);\r
153         }\r
154 \r
155         // implements javax.swing.table.TableCellRenderer\r
156         /**\r
157          *\r
158          * Returns the default table cell renderer.\r
159          * <p>\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
166          *\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
176          */\r
177         public Component getTableCellRendererComponent(JTable table, Object value_,\r
178                         boolean isSelected, boolean hasFocus, int row, int column) {\r
179 \r
180                 Color fg = null;\r
181                 Color bg = null;\r
182 \r
183                 CellValue value = (CellValue)value_;\r
184                 \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
191 \r
192                         fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");\r
193                         bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");\r
194 \r
195                         isSelected = true;\r
196                 }\r
197 \r
198                 int hAlign = value.align & 3;\r
199                 int vAlign = value.align >> 2;\r
200                 \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
204 \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
208                 \r
209                 if (isSelected) {\r
210                         super.setForeground(fg == null ? table.getSelectionForeground()\r
211                                         : fg);\r
212                         super.setBackground(bg == null ? table.getSelectionBackground()\r
213                                         : bg);\r
214                 } else {\r
215                         Color background = value.background != null\r
216                                         ? value.background\r
217                                                         : table.getBackground();\r
218                         Color foreground = value.foreground != null\r
219                                         ? value.foreground\r
220                                                         : table.getForeground();\r
221                         super.setForeground(foreground);\r
222                         super.setBackground(background);\r
223                 }\r
224 \r
225                 Font f = value.font;\r
226                 if(f != null)\r
227                         setFont(f);\r
228                 else\r
229                         setFont(table.getFont());\r
230 \r
231                 if (hasFocus) {\r
232                         Border border = null;\r
233                         if (isSelected) {\r
234                                 border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");\r
235                         }\r
236                         if (border == null) {\r
237                                 border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");\r
238                         }\r
239                         setBorder(border);\r
240 \r
241                         if (!isSelected && table.isCellEditable(row, column)) {\r
242                                 Color col;\r
243                                 col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");\r
244                                 if (col != null) {\r
245                                         super.setForeground(col);\r
246                                 }\r
247                                 col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");\r
248                                 if (col != null) {\r
249                                         super.setBackground(col);\r
250                                 }\r
251                         }\r
252                 } else {\r
253                         setBorder(value.getBorder());\r
254                 }\r
255 \r
256                 setValue(value.label); \r
257 \r
258                 return this;\r
259                 \r
260         }\r
261 \r
262         /*\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
268          */\r
269 \r
270         /**\r
271          * Overridden for performance reasons.\r
272          * See the <a href="#override">Implementation Note</a> \r
273          * for more information.\r
274          */\r
275         public boolean isOpaque() { \r
276                 Color back = getBackground();\r
277                 Component p = getParent(); \r
278                 if (p != null) { \r
279                         p = p.getParent(); \r
280                 }\r
281 \r
282                 // p should now be the JTable. \r
283                 boolean colorMatch = (back != null) && (p != null) && \r
284                                 back.equals(p.getBackground()) && \r
285                                 p.isOpaque();\r
286                 return !colorMatch && super.isOpaque(); \r
287         }\r
288 \r
289         /**\r
290          * Overridden for performance reasons.\r
291          * See the <a href="#override">Implementation Note</a> \r
292          * for more information.\r
293          *\r
294          * @since 1.5\r
295          */\r
296         public void invalidate() {}\r
297 \r
298         /**\r
299          * Overridden for performance reasons.\r
300          * See the <a href="#override">Implementation Note</a> \r
301          * for more information.\r
302          */\r
303         public void validate() {}\r
304 \r
305         /**\r
306          * Overridden for performance reasons.\r
307          * See the <a href="#override">Implementation Note</a> \r
308          * for more information.\r
309          */\r
310         public void revalidate() {}\r
311 \r
312         /**\r
313          * Overridden for performance reasons.\r
314          * See the <a href="#override">Implementation Note</a> \r
315          * for more information.\r
316          */\r
317         public void repaint(long tm, int x, int y, int width, int height) {}\r
318 \r
319         /**\r
320          * Overridden for performance reasons.\r
321          * See the <a href="#override">Implementation Note</a> \r
322          * for more information.\r
323          */\r
324         public void repaint(Rectangle r) { }\r
325 \r
326         /**\r
327          * Overridden for performance reasons.\r
328          * See the <a href="#override">Implementation Note</a> \r
329          * for more information.\r
330          *\r
331          * @since 1.5\r
332          */\r
333         public void repaint() {\r
334         }\r
335 \r
336         /**\r
337          * Overridden for performance reasons.\r
338          * See the <a href="#override">Implementation Note</a> \r
339          * for more information.\r
340          */\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
349 \r
350                         super.firePropertyChange(propertyName, oldValue, newValue);\r
351                 }\r
352         }\r
353 \r
354         /**\r
355          * Overridden for performance reasons.\r
356          * See the <a href="#override">Implementation Note</a> \r
357          * for more information.\r
358          */\r
359         public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }\r
360 \r
361 \r
362         /**\r
363          * Sets the <code>String</code> object for the cell being rendered to\r
364          * <code>value</code>.\r
365          * \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
369          * \r
370          */\r
371         protected void setValue(Object value) {\r
372                 setText((value == null) ? "" : value.toString());\r
373         }\r
374 \r
375 \r
376         /**\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
384          * <p>\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
393          */\r
394         public static class UIResource extends Renderer \r
395         implements javax.swing.plaf.UIResource\r
396         {\r
397         }\r
398 \r
399 }\r
400 \r
401 \r