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.utils.border;
34
import javax.swing.JRootPane;
35
import javax.swing.SwingUtilities;
36
import javax.swing.border.AbstractBorder;
37
import javax.swing.plaf.UIResource;
39
import org.pushingpixels.substance.api.*;
40
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
43
* Root pane and internal frame border in <b>Substance</b> look and feel. This
44
* class is <b>for internal use only</b>.
46
* @author Kirill Grouchnikov
48
public class SubstancePaneBorder extends AbstractBorder implements UIResource {
50
* Default border thickness.
52
private static final int BORDER_THICKNESS = 4;
53
private static final int BORDER_ROUNDNESS = 12;
58
private static final Insets INSETS = new Insets(
59
SubstancePaneBorder.BORDER_THICKNESS,
60
SubstancePaneBorder.BORDER_THICKNESS,
61
SubstancePaneBorder.BORDER_THICKNESS,
62
SubstancePaneBorder.BORDER_THICKNESS);
64
public static DecorationAreaType getRootPaneType(JRootPane rootPane) {
65
DecorationAreaType type = SubstanceLookAndFeel.getDecorationType(rootPane);
66
if ((type == null) || (type == DecorationAreaType.NONE)) {
67
if (SubstanceCoreUtilities.isPaintRootPaneActivated(rootPane)) {
68
if (SubstanceCoreUtilities.isSecondaryWindow(rootPane)) {
69
type = DecorationAreaType.SECONDARY_TITLE_PANE;
71
type = DecorationAreaType.PRIMARY_TITLE_PANE;
74
if (SubstanceCoreUtilities.isSecondaryWindow(rootPane)) {
75
type = DecorationAreaType.SECONDARY_TITLE_PANE_INACTIVE;
77
type = DecorationAreaType.PRIMARY_TITLE_PANE_INACTIVE;
80
} else if (type == DecorationAreaType.PRIMARY_TITLE_PANE) {
81
if (!SubstanceCoreUtilities.isPaintRootPaneActivated(rootPane)) {
82
type =DecorationAreaType.PRIMARY_TITLE_PANE_INACTIVE;
84
} else if (type == DecorationAreaType.SECONDARY_TITLE_PANE) {
85
if (!SubstanceCoreUtilities.isPaintRootPaneActivated(rootPane)) {
86
type =DecorationAreaType.SECONDARY_TITLE_PANE_INACTIVE;
95
* @see javax.swing.border.Border#paintBorder(java.awt.Component,
96
* java.awt.Graphics, int, int, int, int)
99
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
100
if (SubstanceCoreUtilities.isRoundedCorners(c)) {
101
paintRoundedBorder(c, g, x, y, w, h);
103
paintSquareBorder(c, g, x, y, w, h);
107
public void paintSquareBorder(Component c, Graphics g, int x, int y, int w, int h) {
108
SubstanceSkin skin = SubstanceCoreUtilities.getSkin(c);
113
SubstanceColorScheme scheme = skin
114
.getBackgroundColorScheme(getRootPaneType(SwingUtilities.getRootPane(c)));
115
Component titlePaneComp = SubstanceLookAndFeel
116
.getTitlePaneComponent(SwingUtilities.windowForComponent(c));
117
SubstanceColorScheme borderScheme = skin.getColorScheme(titlePaneComp,
118
ColorSchemeAssociationKind.BORDER, ComponentState.ENABLED);
120
Graphics2D graphics = (Graphics2D) g;
122
// bottom and right in ultra dark
123
graphics.setColor(borderScheme.getUltraDarkColor());
124
graphics.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
125
graphics.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
127
graphics.setColor(borderScheme.getDarkColor());
128
graphics.drawLine(x, y, x + w - 2, y);
129
graphics.drawLine(x, y, x, y + h - 2);
130
// inner bottom and right
131
graphics.setColor(scheme.getMidColor());
132
graphics.drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2);
133
graphics.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 2);
134
// inner top and left
135
graphics.setColor(scheme.getMidColor());
136
graphics.drawLine(x + 1, y + 1, x + w - 3, y + 1);
137
graphics.drawLine(x + 1, y + 1, x + 1, y + h - 3);
139
graphics.setColor(scheme.getLightColor());
140
graphics.drawRect(x + 2, y + 2, w - 5, h - 5);
141
graphics.drawRect(x + 3, y + 3, w - 7, h - 7);
147
* @see javax.swing.border.Border#getBorderInsets(java.awt.Component)
150
public Insets getBorderInsets(Component c) {
151
return SubstancePaneBorder.INSETS;
158
* javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component,
162
public Insets getBorderInsets(Component c, Insets newInsets) {
163
newInsets.top = SubstancePaneBorder.INSETS.top;
164
newInsets.left = SubstancePaneBorder.INSETS.left;
165
newInsets.bottom = SubstancePaneBorder.INSETS.bottom;
166
newInsets.right = SubstancePaneBorder.INSETS.right;
173
* @see javax.swing.border.Border#isBorderOpaque()
176
public boolean isBorderOpaque() {
180
public void paintRoundedBorder(Component c, Graphics g, int x, int y, int w, int h) {
181
SubstanceColorScheme scheme = getColorScheme(c);
182
if (scheme == null) return;
183
SubstanceColorScheme borderScheme = getBorderColorScheme(c);
185
Graphics2D graphics = (Graphics2D) g;
187
int xl = x + BORDER_THICKNESS + 2;
188
int xr = x + w - BORDER_THICKNESS - 3;
189
int yt = y + BORDER_THICKNESS + 2;
190
int yb = y + h - BORDER_THICKNESS - 3;
192
Object rh = graphics.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
193
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
195
// bottom and right in ultra dark
196
graphics.setColor(borderScheme.getUltraDarkColor());
197
graphics.drawLine(xl, y + h - 1, xr, y + h - 1); // bottom
198
graphics.drawLine(x + w - 1, yt, x + w - 1, yb); // right
200
graphics.fillOval(x+w- BORDER_ROUNDNESS,y+h- BORDER_ROUNDNESS, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
204
graphics.setColor(borderScheme.getDarkColor());
205
graphics.drawLine(xl, y, xr, y);
206
graphics.drawLine(x, yt, x, yb);
208
graphics.fillOval(0 ,0 , BORDER_ROUNDNESS, BORDER_ROUNDNESS);
209
graphics.fillOval(0 ,y+h- BORDER_ROUNDNESS, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
210
graphics.fillOval(x+w- BORDER_ROUNDNESS,0 , BORDER_ROUNDNESS, BORDER_ROUNDNESS);
214
// inner bottom and right
215
graphics.setColor(scheme.getMidColor());
216
graphics.drawLine(xl, y + h - 2, xr, y + h - 2);
217
graphics.drawLine(x + w - 2, yt, x + w - 2, yb);
218
graphics.drawLine(xl, y + 1, xr, y + 1);
219
graphics.drawLine(x + 1, yt, x + 1, yb);
221
graphics.fillOval(1, 1, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
222
graphics.fillOval(1, y + h - BORDER_ROUNDNESS - 1, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
223
graphics.fillOval(x + w - BORDER_ROUNDNESS - 1, 1, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
224
graphics.fillOval(x + w - BORDER_ROUNDNESS - 1, y + h - BORDER_ROUNDNESS - 1, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
228
graphics.setColor(scheme.getLightColor());
229
graphics.drawLine(xl, y + 2, xr, y + 2);
230
graphics.drawLine(x + 2, yt, x + 2, yb);
231
graphics.drawLine(xl, y + h - 3, xr, y + h - 3);
232
graphics.drawLine(x + w - 3, yt, x + w - 3, yb);
233
graphics.drawLine(xl, y + 3, xr, y + 3);
234
graphics.drawLine(x + 3, yt, x + 3, yb);
235
graphics.drawLine(xl, y + h - 4, xr, y + h - 4);
236
graphics.drawLine(x + w - 4, yt, x + w - 4, yb);
238
graphics.fillOval(2, 2, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
239
graphics.fillOval(2, y + h - BORDER_ROUNDNESS - 2, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
240
graphics.fillOval(x + w - BORDER_ROUNDNESS -2, 2, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
241
graphics.fillOval(x + w - BORDER_ROUNDNESS -2, y + h - BORDER_ROUNDNESS - 2, BORDER_ROUNDNESS, BORDER_ROUNDNESS);
244
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rh);
247
private SubstanceColorScheme getColorScheme(Component c) {
248
JRootPane rp = c instanceof JRootPane
250
: SwingUtilities.getRootPane(c);
252
SubstanceSkin skin = SubstanceCoreUtilities.getSkin(c);
253
if (skin == null) return null;
255
DecorationAreaType type = getRootPaneType(rp);
256
return skin.getBackgroundColorScheme(type);
259
private SubstanceColorScheme getBorderColorScheme(Component c) {
260
JRootPane rp = c instanceof JRootPane
262
: SwingUtilities.getRootPane(c);
264
SubstanceSkin skin = SubstanceCoreUtilities.getSkin(c);
266
if (skin == null) return null;
269
Component titlePaneComp = SubstanceLookAndFeel
270
.getTitlePaneComponent(SwingUtilities.windowForComponent(c));
272
return skin.getColorScheme(getRootPaneType(rp),
273
ColorSchemeAssociationKind.BORDER, ComponentState.ENABLED);