2
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
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.
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.
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.
30
package org.pushingpixels.substance.internal.painter;
36
import org.pushingpixels.lafwidget.LafWidgetUtilities;
37
import org.pushingpixels.substance.api.*;
38
import org.pushingpixels.substance.api.painter.decoration.SubstanceDecorationPainter;
39
import org.pushingpixels.substance.api.watermark.SubstanceWatermark;
40
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
43
* Contains utility methods related to decoration painters. This class is for
46
* @author Kirill Grouchnikov
48
public class DecorationPainterUtils {
50
* Client property for marking a component with an instance of
51
* {@link DecorationAreaType} enum.
53
private static final String DECORATION_AREA_TYPE = "substancelaf.internal.painter.decorationAreaType";
56
* Sets the decoration type of the specified component.
61
* Decoration type of the component and its children.
63
public static void setDecorationType(JComponent comp,
64
DecorationAreaType type) {
65
comp.putClientProperty(DECORATION_AREA_TYPE, type);
69
* Clears the client properties related to the decoration area type.
74
public static void clearDecorationType(JComponent comp) {
76
comp.putClientProperty(DECORATION_AREA_TYPE, null);
81
* Returns the decoration area type of the specified component. The
82
* component and its ancestor hierarchy are scanned for the registered
83
* decoration area type. If
84
* {@link #setDecorationType(JComponent, DecorationAreaType)} has been
85
* called on the specified component, the matching decoration type is
86
* returned. Otherwise, the component hierarchy is scanned to find the
87
* closest ancestor that was passed to
88
* {@link #setDecorationType(JComponent, DecorationAreaType)} - and its
89
* decoration type is returned. If neither the component, nor any one of its
90
* parent components has been passed to the setter method,
91
* {@link DecorationAreaType#NONE} is returned.
95
* @return Decoration area type of the component.
97
public static DecorationAreaType getDecorationType(Component comp) {
100
if (c instanceof JComponent) {
101
JComponent jc = (JComponent) c;
102
Object prop = jc.getClientProperty(DECORATION_AREA_TYPE);
103
if (prop instanceof DecorationAreaType) {
104
return (DecorationAreaType) prop;
109
return DecorationAreaType.NONE;
113
* Returns the immediate decoration area type of the specified component.
114
* The component is checked for the registered decoration area type. If
115
* {@link #setDecorationType(javax.swing.JComponent, org.pushingpixels.substance.api.DecorationAreaType)} was
116
* not called on this component, this method returns <code>null</code>.
120
* @return Immediate decoration area type of the component.
122
public static DecorationAreaType getImmediateDecorationType(Component comp) {
124
if (c instanceof JComponent) {
125
JComponent jc = (JComponent) c;
126
Object prop = jc.getClientProperty(DECORATION_AREA_TYPE);
127
if (prop instanceof DecorationAreaType)
128
return (DecorationAreaType) prop;
134
* Paints the decoration background on the specified component. The
135
* decoration background is not painted when the <code>force</code>
136
* parameter is <code>false</code> and at least one of the following
139
* <li>The component is in a cell renderer.</li>
140
* <li>The component is not showing on the screen.</li>
141
* <li>The component is in the preview mode.</li>
149
* If <code>true</code>, the painting of decoration background is
152
public static void paintDecorationBackground(Graphics g, Component c,
154
DecorationAreaType decorationType = SubstanceLookAndFeel
155
.getDecorationType(c);
156
paintDecorationBackground(g, c, decorationType, force);
160
* Paints the decoration background on the specified component. See comments
161
* on {@link #paintDecorationBackground(Graphics, Component, boolean)} for
162
* the cases when the decoration background painting is skipped.
168
* @param decorationType
169
* Decoration area type of the component.
171
* If <code>true</code>, the painting of decoration background is
173
* {@link #paintDecorationBackground(Graphics, Component, boolean)}
175
public static void paintDecorationBackground(Graphics g, Component c,
176
DecorationAreaType decorationType, boolean force) {
177
// System.out.println("Painting " + c.getClass().getSimpleName());
178
boolean isInCellRenderer = (SwingUtilities.getAncestorOfClass(
179
CellRendererPane.class, c) != null);
180
boolean isPreviewMode = false;
181
if (c instanceof JComponent) {
182
isPreviewMode = (Boolean.TRUE.equals(((JComponent) c)
183
.getClientProperty(LafWidgetUtilities.PREVIEW_MODE)));
186
if (!force && !isPreviewMode && !c.isShowing() && !isInCellRenderer) {
190
if ((c.getHeight() == 0) || (c.getWidth() == 0))
193
SubstanceSkin skin = SubstanceCoreUtilities.getSkin(c);
194
SubstanceDecorationPainter painter = skin.getDecorationPainter();
196
Graphics2D g2d = (Graphics2D) g.create();
197
painter.paintDecorationArea(g2d, c, decorationType, c.getWidth(), c
200
SubstanceWatermark watermark = SubstanceCoreUtilities.getSkin(c)
202
if ((watermark != null) && !isPreviewMode && !isInCellRenderer
203
&& c.isShowing() && SubstanceCoreUtilities.toDrawWatermark(c)) {
204
// paint the watermark over the component
205
watermark.drawWatermarkImage(g2d, c, 0, 0, c.getWidth(), c
208
// paint the background second time with 50%
209
// translucency, making the watermark' bleed' through.
210
g2d.setComposite(LafWidgetUtilities.getAlphaComposite(c, 0.5f, g));
211
painter.paintDecorationArea(g2d, c, decorationType, c.getWidth(), c