~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/api/renderers/SubstanceDefaultTreeCellRenderer.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Substance Kirill Grouchnikov. 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 Substance Kirill Grouchnikov 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
package org.pushingpixels.substance.api.renderers;
 
31
 
 
32
import java.awt.Color;
 
33
import java.awt.Component;
 
34
import java.awt.Dimension;
 
35
import java.awt.Font;
 
36
import java.awt.Graphics;
 
37
import java.awt.Insets;
 
38
import java.awt.Rectangle;
 
39
import java.util.Map;
 
40
 
 
41
import javax.swing.Icon;
 
42
import javax.swing.JLabel;
 
43
import javax.swing.JTree;
 
44
import javax.swing.SwingConstants;
 
45
import javax.swing.UIManager;
 
46
import javax.swing.plaf.BorderUIResource;
 
47
import javax.swing.plaf.ColorUIResource;
 
48
import javax.swing.plaf.FontUIResource;
 
49
import javax.swing.plaf.TreeUI;
 
50
import javax.swing.tree.TreeCellRenderer;
 
51
 
 
52
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
 
53
import org.pushingpixels.substance.api.ComponentState;
 
54
import org.pushingpixels.substance.api.SubstanceColorScheme;
 
55
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
 
56
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
 
57
import org.pushingpixels.substance.internal.animation.StateTransitionTracker.StateContributionInfo;
 
58
import org.pushingpixels.substance.internal.ui.SubstanceTreeUI;
 
59
import org.pushingpixels.substance.internal.ui.SubstanceTreeUI.TreePathId;
 
60
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
 
61
import org.pushingpixels.substance.internal.utils.SubstanceImageCreator;
 
62
import org.pushingpixels.substance.internal.utils.SubstanceStripingUtils;
 
63
 
 
64
/**
 
65
 * Default renderer for tree cells.
 
66
 * 
 
67
 * @author Kirill Grouchnikov
 
68
 */
 
69
@SubstanceRenderer
 
70
public class SubstanceDefaultTreeCellRenderer extends JLabel implements
 
71
                TreeCellRenderer {
 
72
        /** Last tree the renderer was painted in. */
 
73
        private JTree tree;
 
74
 
 
75
        /** Is the value currently selected. */
 
76
        protected boolean selected;
 
77
 
 
78
        /** True if has focus. */
 
79
        protected boolean hasFocus;
 
80
 
 
81
        /**
 
82
         * Returns a new instance of SubstanceDefaultTreeCellRenderer. Alignment is
 
83
         * set to left aligned. Icons and text color are determined from the
 
84
         * UIManager.
 
85
         */
 
86
        public SubstanceDefaultTreeCellRenderer() {
 
87
                this.setHorizontalAlignment(SwingConstants.LEFT);
 
88
                this.putClientProperty(SubstanceLookAndFeel.COLORIZATION_FACTOR, 1.0);
 
89
        }
 
90
 
 
91
        /**
 
92
         * Returns the default icon that is used to represent non-leaf nodes that
 
93
         * are expanded.
 
94
         * 
 
95
         * @return The default icon for non-leaf expanded nodes.
 
96
         */
 
97
        public Icon getDefaultOpenIcon() {
 
98
                return UIManager.getIcon("Tree.openIcon");
 
99
        }
 
100
 
 
101
        /**
 
102
         * Returns the default icon that is used to represent non-leaf nodes that
 
103
         * are not expanded.
 
104
         * 
 
105
         * @return The default icon for non-leaf non-expanded nodes.
 
106
         */
 
107
        public Icon getDefaultClosedIcon() {
 
108
                return UIManager.getIcon("Tree.closedIcon");
 
109
        }
 
110
 
 
111
        /**
 
112
         * Returns the default icon that is used to represent leaf nodes.
 
113
         * 
 
114
         * @return The default icon for leaf nodes.
 
115
         */
 
116
        public Icon getDefaultLeafIcon() {
 
117
                return UIManager.getIcon("Tree.leafIcon");
 
118
        }
 
119
 
 
120
        /**
 
121
         * Subclassed to map <code>FontUIResource</code>s to null. If
 
122
         * <code>font</code> is null, or a <code>FontUIResource</code>, this has the
 
123
         * effect of letting the font of the JTree show through. On the other hand,
 
124
         * if <code>font</code> is non-null, and not a <code>FontUIResource</code>,
 
125
         * the font becomes <code>font</code>.
 
126
         */
 
127
        @Override
 
128
        public void setFont(Font font) {
 
129
                if (font instanceof FontUIResource)
 
130
                        font = null;
 
131
                super.setFont(font);
 
132
        }
 
133
 
 
134
        /**
 
135
         * Gets the font of this component.
 
136
         * 
 
137
         * @return this component's font; if a font has not been set for this
 
138
         *         component, the font of its parent is returned
 
139
         */
 
140
        @Override
 
141
        public Font getFont() {
 
142
                Font font = super.getFont();
 
143
 
 
144
                if ((font == null) && (this.tree != null)) {
 
145
                        // Strive to return a non-null value, otherwise the html support
 
146
                        // will typically pick up the wrong font in certain situations.
 
147
                        font = this.tree.getFont();
 
148
                }
 
149
                return font;
 
150
        }
 
151
 
 
152
        /**
 
153
         * Configures the renderer based on the passed in components. The value is
 
154
         * set from messaging the tree with <code>convertValueToText</code>, which
 
155
         * ultimately invokes <code>toString</code> on <code>value</code>. The
 
156
         * foreground color is set based on the selection and the icon is set based
 
157
         * on on leaf and expanded.
 
158
         */
 
159
        @Override
 
160
    public Component getTreeCellRendererComponent(JTree tree, Object value,
 
161
                        boolean sel, boolean expanded, boolean leaf, int row,
 
162
                        boolean hasFocus) {
 
163
                String stringValue = tree.convertValueToText(value, sel, expanded,
 
164
                                leaf, row, hasFocus);
 
165
 
 
166
                this.tree = tree;
 
167
                this.hasFocus = hasFocus;
 
168
                this.setText(stringValue);
 
169
 
 
170
                TreeUI treeUI = tree.getUI();
 
171
                if (treeUI instanceof SubstanceTreeUI) {
 
172
                        SubstanceTreeUI ui = (SubstanceTreeUI) treeUI;
 
173
                        TreePathId pathId = new TreePathId(tree.getPathForRow(row));
 
174
 
 
175
                        StateTransitionTracker.ModelStateInfo modelStateInfo = ui
 
176
                                        .getModelStateInfo(pathId);
 
177
                        ComponentState currState = ui.getPathState(pathId);
 
178
 
 
179
                        // special case for drop location
 
180
                        JTree.DropLocation dropLocation = tree.getDropLocation();
 
181
                        boolean isDropLocation = (dropLocation != null
 
182
                                        && dropLocation.getChildIndex() == -1 && tree
 
183
                                        .getRowForPath(dropLocation.getPath()) == row);
 
184
 
 
185
                        if (!isDropLocation && (modelStateInfo != null)) {
 
186
                                Map<ComponentState, StateContributionInfo> activeStates = modelStateInfo
 
187
                                                .getStateContributionMap();
 
188
                                SubstanceColorScheme colorScheme = getColorSchemeForState(tree,
 
189
                                                ui, currState);
 
190
                                if (currState.isDisabled() || (activeStates == null)
 
191
                                                || (activeStates.size() == 1)) {
 
192
                                        super.setForeground(new ColorUIResource(colorScheme
 
193
                                                        .getForegroundColor()));
 
194
                                } else {
 
195
                                        float aggrRed = 0;
 
196
                                        float aggrGreen = 0;
 
197
                                        float aggrBlue = 0;
 
198
 
 
199
                                        for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : modelStateInfo
 
200
                                                        .getStateContributionMap().entrySet()) {
 
201
                                                ComponentState activeState = activeEntry.getKey();
 
202
                                                SubstanceColorScheme scheme = getColorSchemeForState(
 
203
                                                                tree, ui, activeState);
 
204
                                                Color schemeFg = scheme.getForegroundColor();
 
205
                                                float contribution = activeEntry.getValue()
 
206
                                                                .getContribution();
 
207
                                                aggrRed += schemeFg.getRed() * contribution;
 
208
                                                aggrGreen += schemeFg.getGreen() * contribution;
 
209
                                                aggrBlue += schemeFg.getBlue() * contribution;
 
210
                                        }
 
211
                                        super.setForeground(new ColorUIResource(new Color(
 
212
                                                        (int) aggrRed, (int) aggrGreen, (int) aggrBlue)));
 
213
                                }
 
214
                        } else {
 
215
                                SubstanceColorScheme scheme = getColorSchemeForState(tree, ui,
 
216
                                                currState);
 
217
                                if (isDropLocation) {
 
218
                                        scheme = SubstanceColorSchemeUtilities.getColorScheme(tree,
 
219
                                                        ColorSchemeAssociationKind.TEXT_HIGHLIGHT,
 
220
                                                        currState);
 
221
                                }
 
222
                                super.setForeground(new ColorUIResource(scheme
 
223
                                                .getForegroundColor()));
 
224
                        }
 
225
                } else {
 
226
                        if (sel)
 
227
                                this.setForeground(UIManager
 
228
                                                .getColor("Tree.selectionForeground"));
 
229
                        else
 
230
                                this.setForeground(UIManager.getColor("Tree.textForeground"));
 
231
                }
 
232
 
 
233
                if (SubstanceLookAndFeel.isCurrentLookAndFeel())
 
234
                        SubstanceStripingUtils.applyStripedBackground(tree, row, this);
 
235
 
 
236
                // There needs to be a way to specify disabled icons.
 
237
                if (!tree.isEnabled()) {
 
238
                        this.setEnabled(false);
 
239
                        if (leaf) {
 
240
                                this.setDisabledIcon(SubstanceImageCreator
 
241
                                                .toGreyscale(SubstanceImageCreator.makeTransparent(
 
242
                                                                tree, this.getDefaultLeafIcon(), 0.5)));
 
243
                        } else if (expanded) {
 
244
                                this.setDisabledIcon(SubstanceImageCreator
 
245
                                                .toGreyscale(SubstanceImageCreator.makeTransparent(
 
246
                                                                tree, this.getDefaultOpenIcon(), 0.5)));
 
247
                                // setIcon(SubstanceImageCreator.toGreyscale(
 
248
                                // SubstanceImageCreator
 
249
                                // .makeTransparent(getDefaultOpenIcon(), 0.5)));
 
250
                        } else {
 
251
                                this.setDisabledIcon(SubstanceImageCreator
 
252
                                                .toGreyscale(SubstanceImageCreator.makeTransparent(
 
253
                                                                tree, this.getDefaultClosedIcon(), 0.5)));
 
254
                                // setIcon(SubstanceImageCreator.toGreyscale(
 
255
                                // SubstanceImageCreator
 
256
                                // .makeTransparent(getDefaultClosedIcon(), 0.5)));
 
257
                        }
 
258
                } else {
 
259
                        this.setEnabled(true);
 
260
                        if (leaf) {
 
261
                                this.setIcon(this.getDefaultLeafIcon());
 
262
                        } else if (expanded) {
 
263
                                this.setIcon(this.getDefaultOpenIcon());
 
264
                        } else {
 
265
                                this.setIcon(this.getDefaultClosedIcon());
 
266
                        }
 
267
                }
 
268
                this.setComponentOrientation(tree.getComponentOrientation());
 
269
 
 
270
                this.setOpaque(false);
 
271
 
 
272
                this.selected = sel;
 
273
 
 
274
                if (treeUI instanceof SubstanceTreeUI) {
 
275
                        SubstanceTreeUI ui = (SubstanceTreeUI) treeUI;
 
276
                        Insets regInsets = ui.getCellRendererInsets();
 
277
                        this
 
278
                                        .setBorder(new BorderUIResource.EmptyBorderUIResource(
 
279
                                                        regInsets));
 
280
                }
 
281
 
 
282
                return this;
 
283
        }
 
284
 
 
285
        private SubstanceColorScheme getColorSchemeForState(JTree tree,
 
286
                        SubstanceTreeUI ui, ComponentState activeState) {
 
287
                SubstanceColorScheme scheme = (activeState == ComponentState.ENABLED) ? ui
 
288
                                .getDefaultColorScheme()
 
289
                                : SubstanceColorSchemeUtilities.getColorScheme(tree,
 
290
                                                ColorSchemeAssociationKind.HIGHLIGHT, activeState);
 
291
                if (scheme == null) {
 
292
                        scheme = SubstanceColorSchemeUtilities.getColorScheme(tree,
 
293
                                        ColorSchemeAssociationKind.HIGHLIGHT, activeState);
 
294
                }
 
295
                return scheme;
 
296
        }
 
297
 
 
298
        /**
 
299
         * Overrides <code>JComponent.getPreferredSize</code> to return slightly
 
300
         * wider preferred size value.
 
301
         */
 
302
        @Override
 
303
        public Dimension getPreferredSize() {
 
304
                Dimension retDimension = super.getPreferredSize();
 
305
 
 
306
                if (retDimension != null)
 
307
                        retDimension = new Dimension(retDimension.width + 3,
 
308
                                        retDimension.height);
 
309
                return retDimension;
 
310
        }
 
311
 
 
312
        /**
 
313
         * Overridden for performance reasons. See the <a
 
314
         * href="#override">Implementation Note</a> for more information.
 
315
         */
 
316
        @Override
 
317
        public void validate() {
 
318
        }
 
319
 
 
320
        /**
 
321
         * Overridden for performance reasons. See the <a
 
322
         * href="#override">Implementation Note</a> for more information.
 
323
         * 
 
324
         * @since 1.5
 
325
         */
 
326
        @Override
 
327
        public void invalidate() {
 
328
        }
 
329
 
 
330
        /**
 
331
         * Overridden for performance reasons. See the <a
 
332
         * href="#override">Implementation Note</a> for more information.
 
333
         */
 
334
        @Override
 
335
        public void revalidate() {
 
336
        }
 
337
 
 
338
        /**
 
339
         * Overridden for performance reasons. See the <a
 
340
         * href="#override">Implementation Note</a> for more information.
 
341
         */
 
342
        @Override
 
343
        public void repaint(long tm, int x, int y, int width, int height) {
 
344
        }
 
345
 
 
346
        /**
 
347
         * Overridden for performance reasons. See the <a
 
348
         * href="#override">Implementation Note</a> for more information.
 
349
         */
 
350
        @Override
 
351
        public void repaint(Rectangle r) {
 
352
        }
 
353
 
 
354
        /**
 
355
         * Overridden for performance reasons. See the <a
 
356
         * href="#override">Implementation Note</a> for more information.
 
357
         * 
 
358
         * @since 1.5
 
359
         */
 
360
        @Override
 
361
        public void repaint() {
 
362
        }
 
363
 
 
364
        /**
 
365
         * Overridden for performance reasons. See the <a
 
366
         * href="#override">Implementation Note</a> for more information.
 
367
         */
 
368
        @Override
 
369
        protected void firePropertyChange(String propertyName, Object oldValue,
 
370
                        Object newValue) {
 
371
                if ("text".equals(propertyName))
 
372
                        super.firePropertyChange(propertyName, oldValue, newValue);
 
373
        }
 
374
 
 
375
        /**
 
376
         * Overridden for performance reasons. See the <a
 
377
         * href="#override">Implementation Note</a> for more information.
 
378
         */
 
379
        @Override
 
380
        public void firePropertyChange(String propertyName, byte oldValue,
 
381
                        byte newValue) {
 
382
        }
 
383
 
 
384
        /**
 
385
         * Overridden for performance reasons. See the <a
 
386
         * href="#override">Implementation Note</a> for more information.
 
387
         */
 
388
        @Override
 
389
        public void firePropertyChange(String propertyName, char oldValue,
 
390
                        char newValue) {
 
391
        }
 
392
 
 
393
        /**
 
394
         * Overridden for performance reasons. See the <a
 
395
         * href="#override">Implementation Note</a> for more information.
 
396
         */
 
397
        @Override
 
398
        public void firePropertyChange(String propertyName, short oldValue,
 
399
                        short newValue) {
 
400
        }
 
401
 
 
402
        /**
 
403
         * Overridden for performance reasons. See the <a
 
404
         * href="#override">Implementation Note</a> for more information.
 
405
         */
 
406
        @Override
 
407
        public void firePropertyChange(String propertyName, int oldValue,
 
408
                        int newValue) {
 
409
        }
 
410
 
 
411
        /**
 
412
         * Overridden for performance reasons. See the <a
 
413
         * href="#override">Implementation Note</a> for more information.
 
414
         */
 
415
        @Override
 
416
        public void firePropertyChange(String propertyName, long oldValue,
 
417
                        long newValue) {
 
418
        }
 
419
 
 
420
        /**
 
421
         * Overridden for performance reasons. See the <a
 
422
         * href="#override">Implementation Note</a> for more information.
 
423
         */
 
424
        @Override
 
425
        public void firePropertyChange(String propertyName, float oldValue,
 
426
                        float newValue) {
 
427
        }
 
428
 
 
429
        /**
 
430
         * Overridden for performance reasons. See the <a
 
431
         * href="#override">Implementation Note</a> for more information.
 
432
         */
 
433
        @Override
 
434
        public void firePropertyChange(String propertyName, double oldValue,
 
435
                        double newValue) {
 
436
        }
 
437
 
 
438
        /**
 
439
         * Overridden for performance reasons. See the <a
 
440
         * href="#override">Implementation Note</a> for more information.
 
441
         */
 
442
        @Override
 
443
        public void firePropertyChange(String propertyName, boolean oldValue,
 
444
                        boolean newValue) {
 
445
        }
 
446
 
 
447
        /*
 
448
         * (non-Javadoc)
 
449
         * 
 
450
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
 
451
         */
 
452
        @Override
 
453
        public final void paint(Graphics g) {
 
454
                super.paint(g);
 
455
        }
 
456
 
 
457
        /*
 
458
         * (non-Javadoc)
 
459
         * 
 
460
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
 
461
         */
 
462
        @Override
 
463
        protected final void paintComponent(Graphics g) {
 
464
                super.paintComponent(g);
 
465
        }
 
466
}