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

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/internal/utils/border/SubstanceBorder.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.internal.utils.border;
 
31
 
 
32
import java.awt.*;
 
33
import java.awt.image.BufferedImage;
 
34
 
 
35
import javax.swing.border.Border;
 
36
import javax.swing.plaf.UIResource;
 
37
 
 
38
import org.pushingpixels.lafwidget.LafWidgetUtilities;
 
39
import org.pushingpixels.substance.api.*;
 
40
import org.pushingpixels.substance.internal.utils.*;
 
41
 
 
42
/**
 
43
 * Gradient border for the <b>Substance</b> look and feel. This class is <b>for
 
44
 * internal use only</b>.
 
45
 * 
 
46
 * @author Kirill Grouchnikov
 
47
 */
 
48
public class SubstanceBorder implements Border, UIResource {
 
49
        /**
 
50
         * Insets of <code>this</code> border.
 
51
         */
 
52
        protected Insets myInsets;
 
53
 
 
54
        /**
 
55
         * Border alpha.
 
56
         */
 
57
        protected float alpha;
 
58
 
 
59
        /**
 
60
         * When the border is painted, the default radius is multiplied by this
 
61
         * factor.
 
62
         */
 
63
        protected float radiusScaleFactor;
 
64
 
 
65
        /**
 
66
         * Cache of small border images.
 
67
         */
 
68
        private static LazyResettableHashMap<BufferedImage> smallImageCache = new LazyResettableHashMap<BufferedImage>(
 
69
                        "SubstanceBorder");
 
70
 
 
71
        /**
 
72
         * Creates a new border with dynamic insets (computed at the invocation time
 
73
         * of {@link #getBorderInsets(Component)} call).
 
74
         */
 
75
        public SubstanceBorder() {
 
76
                super();
 
77
                this.alpha = 1.0f;
 
78
                this.radiusScaleFactor = 0.5f;
 
79
        }
 
80
 
 
81
        /**
 
82
         * Creates a new border with dynamic insets (computed at the invocation time
 
83
         * of {@link #getBorderInsets(Component)} call).
 
84
         * 
 
85
         * @param radiusScaleFactor
 
86
         *            Radius scale factor.
 
87
         */
 
88
        public SubstanceBorder(float radiusScaleFactor) {
 
89
                this();
 
90
                this.radiusScaleFactor = radiusScaleFactor;
 
91
        }
 
92
 
 
93
        /**
 
94
         * Creates a new border with the specified insets.
 
95
         * 
 
96
         * @param insets
 
97
         *            Insets.
 
98
         */
 
99
        public SubstanceBorder(Insets insets) {
 
100
                this();
 
101
                this.myInsets = new Insets(insets.top, insets.left, insets.bottom,
 
102
                                insets.right);
 
103
        }
 
104
 
 
105
        /**
 
106
         * Sets the alpha for this border.
 
107
         * 
 
108
         * @param alpha
 
109
         *            Alpha factor.
 
110
         */
 
111
        public void setAlpha(float alpha) {
 
112
                this.alpha = alpha;
 
113
        }
 
114
 
 
115
        /**
 
116
         * Paints border instance for the specified component.
 
117
         * 
 
118
         * @param c
 
119
         *            The component.
 
120
         * @param g
 
121
         *            Graphics context.
 
122
         * @param x
 
123
         *            Component left X (in graphics context).
 
124
         * @param y
 
125
         *            Component top Y (in graphics context).
 
126
         * @param width
 
127
         *            Component width.
 
128
         * @param height
 
129
         *            Component height.
 
130
         * @param isEnabled
 
131
         *            Component enabled status.
 
132
         * @param hasFocus
 
133
         *            Component focus ownership status.
 
134
         * @param alpha
 
135
         *            Alpha value.
 
136
         */
 
137
        private void paintBorder(Component c, Graphics g, int x, int y, int width,
 
138
                        int height, boolean isEnabled, boolean hasFocus, float alpha) {
 
139
                // failsafe for LAF change
 
140
                if (!SubstanceLookAndFeel.isCurrentLookAndFeel()) {
 
141
                        return;
 
142
                }
 
143
 
 
144
                if ((width <= 0) || (height <= 0))
 
145
                        return;
 
146
 
 
147
                if (alpha == 0.0f) {
 
148
                        return;
 
149
                }
 
150
 
 
151
                Graphics2D graphics = (Graphics2D) g.create();
 
152
 
 
153
                float radius = this.radiusScaleFactor
 
154
                                * SubstanceSizeUtils
 
155
                                                .getClassicButtonCornerRadius(SubstanceSizeUtils
 
156
                                                                .getComponentFontSize(c));
 
157
 
 
158
                ComponentState state = isEnabled ? ComponentState.ENABLED
 
159
                                : ComponentState.DISABLED_UNSELECTED;
 
160
                SubstanceColorScheme borderColorScheme = SubstanceColorSchemeUtilities
 
161
                                .getColorScheme(c, ColorSchemeAssociationKind.BORDER, state);
 
162
                float finalAlpha = alpha
 
163
                                * SubstanceColorSchemeUtilities.getAlpha(c, state);
 
164
 
 
165
                graphics.setComposite(LafWidgetUtilities.getAlphaComposite(c,
 
166
                                finalAlpha, g));
 
167
 
 
168
                if (width * height < 100000) {
 
169
                        HashMapKey hashKey = SubstanceCoreUtilities
 
170
                                        .getHashKey(SubstanceCoreUtilities.getBorderPainter(c)
 
171
                                                        .getDisplayName(), SubstanceSizeUtils
 
172
                                                        .getComponentFontSize(c), width, height, radius,
 
173
                                                        borderColorScheme.getDisplayName());
 
174
                        BufferedImage result = smallImageCache.get(hashKey);
 
175
                        if (result == null) {
 
176
                                result = SubstanceCoreUtilities.getBlankImage(width, height);
 
177
                                Graphics2D g2d = result.createGraphics();
 
178
                                SubstanceImageCreator.paintBorder(c, g2d, 0, 0, width, height,
 
179
                                                radius, borderColorScheme);
 
180
                                g2d.dispose();
 
181
                                smallImageCache.put(hashKey, result);
 
182
                        }
 
183
                        graphics.drawImage(result, x, y, null);
 
184
                } else {
 
185
                        // for borders larger than 100000 pixels, use simple
 
186
                        // painting
 
187
                        graphics.translate(x, y);
 
188
                        SubstanceImageCreator.paintSimpleBorder(c, graphics, width, height,
 
189
                                        borderColorScheme);
 
190
                }
 
191
 
 
192
                graphics.dispose();
 
193
        }
 
194
 
 
195
        /*
 
196
         * (non-Javadoc)
 
197
         * 
 
198
         * @see javax.swing.border.Border#paintBorder(java.awt.Component,
 
199
         * java.awt.Graphics, int, int, int, int)
 
200
         */
 
201
        @Override
 
202
    public void paintBorder(Component c, Graphics g, int x, int y, int width,
 
203
                        int height) {
 
204
                paintBorder(c, g, x, y, width, height, c.isEnabled(), c.hasFocus(),
 
205
                                this.alpha);
 
206
        }
 
207
 
 
208
        /*
 
209
         * (non-Javadoc)
 
210
         * 
 
211
         * @see javax.swing.border.Border#getBorderInsets(java.awt.Component)
 
212
         */
 
213
        @Override
 
214
    public Insets getBorderInsets(Component c) {
 
215
                if (this.myInsets == null) {
 
216
                        return SubstanceSizeUtils.getDefaultBorderInsets(SubstanceSizeUtils
 
217
                                        .getComponentFontSize(c));
 
218
                }
 
219
                return this.myInsets;
 
220
        }
 
221
 
 
222
        /*
 
223
         * (non-Javadoc)
 
224
         * 
 
225
         * @see javax.swing.border.Border#isBorderOpaque()
 
226
         */
 
227
        @Override
 
228
    public boolean isBorderOpaque() {
 
229
                return false;
 
230
        }
 
231
 
 
232
        /**
 
233
         * Returns the radius scale factor of this border.
 
234
         * 
 
235
         * @return The radius scale factor of this border.
 
236
         */
 
237
        public float getRadiusScaleFactor() {
 
238
                return this.radiusScaleFactor;
 
239
        }
 
240
}