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;
33
import java.awt.image.BufferedImage;
37
import javax.swing.border.Border;
39
import org.pushingpixels.lafwidget.LafWidgetUtilities;
40
import org.pushingpixels.lafwidget.animation.AnimationConfigurationManager;
41
import org.pushingpixels.lafwidget.animation.AnimationFacet;
42
import org.pushingpixels.substance.api.*;
43
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
44
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
47
* Drop down button in <b>Substance</b> look and feel.
49
* @author Kirill Grouchnikov
51
public final class SubstanceDropDownButton extends JButton implements
52
SubstanceInternalArrowButton {
54
AnimationConfigurationManager.getInstance().disallowAnimations(
55
AnimationFacet.GHOSTING_BUTTON_PRESS,
56
SubstanceDropDownButton.class);
57
AnimationConfigurationManager.getInstance().disallowAnimations(
58
AnimationFacet.GHOSTING_ICON_ROLLOVER,
59
SubstanceDropDownButton.class);
66
* The parent component.
68
public SubstanceDropDownButton(JComponent parent) {
70
this.setModel(new DefaultButtonModel() {
72
public void setArmed(boolean armed) {
73
super.setArmed(this.isPressed() || armed);
76
this.setEnabled(parent.isEnabled());
77
this.setFocusable(false);
78
this.setRequestFocusEnabled(parent.isEnabled());
80
int fontSize = SubstanceSizeUtils.getComponentFontSize(parent);
81
int tbInset = SubstanceSizeUtils.getAdjustedSize(fontSize, 1, 2, 1,
84
this.setMargin(new Insets(tbInset, lrInset, tbInset, tbInset));
86
this.setBorderPainted(false);
87
this.putClientProperty(SubstanceLookAndFeel.FLAT_PROPERTY, Boolean.TRUE);
88
this.setOpaque(false);
92
public void setBorder(Border border) {
96
protected void paintBorder(Graphics g) {
97
if (SubstanceCoreUtilities.isButtonNeverPainted(this)) {
101
TransitionAwareUI transitionAwareUI = (TransitionAwareUI) this.getUI();
102
StateTransitionTracker stateTransitionTracker = transitionAwareUI
103
.getTransitionTracker();
104
StateTransitionTracker.ModelStateInfo modelStateInfo = stateTransitionTracker
105
.getModelStateInfo();
106
Map<ComponentState, StateTransitionTracker.StateContributionInfo> activeStates = modelStateInfo
107
.getStateContributionMap();
109
ComponentState currState = modelStateInfo.getCurrModelState();
110
float extraAlpha = stateTransitionTracker.getActiveStrength();
112
if (currState == ComponentState.DISABLED_UNSELECTED)
115
if (extraAlpha == 0.0f)
118
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(this);
119
int borderDelta = (int) Math.floor(1.5 * SubstanceSizeUtils
120
.getBorderStrokeWidth(componentFontSize));
121
float radius = Math.max(0, 2.0f
123
.getClassicButtonCornerRadius(componentFontSize)
126
int width = getWidth();
127
int height = getHeight();
129
int offsetX = this.getX();
130
int offsetY = this.getY();
131
JComponent parent = (JComponent) this.getParent();
132
SubstanceColorScheme baseBorderScheme = SubstanceColorSchemeUtilities
133
.getColorScheme(this, ColorSchemeAssociationKind.BORDER,
136
BufferedImage offscreen = SubstanceCoreUtilities.getBlankImage(width,
138
Graphics2D g2offscreen = offscreen.createGraphics();
140
SubstanceImageCreator.paintTextComponentBorder(this, g2offscreen, 0, 0,
141
width, height, radius, baseBorderScheme);
142
g2offscreen.translate(-offsetX, -offsetY);
143
SubstanceImageCreator.paintTextComponentBorder(parent, g2offscreen, 0,
144
0, parent.getWidth(), parent.getHeight(), radius,
146
g2offscreen.translate(offsetX, offsetY);
148
for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : activeStates
150
ComponentState activeState = activeEntry.getKey();
151
if (activeState == currState)
154
float contribution = activeEntry.getValue().getContribution();
155
if (contribution == 0.0f)
158
g2offscreen.setComposite(AlphaComposite.SrcOver
159
.derive(contribution));
160
SubstanceColorScheme borderScheme = SubstanceColorSchemeUtilities
161
.getColorScheme(this, ColorSchemeAssociationKind.BORDER,
164
SubstanceImageCreator.paintTextComponentBorder(this, g2offscreen,
165
0, 0, width, height, radius, borderScheme);
166
g2offscreen.translate(-offsetX, -offsetY);
167
SubstanceImageCreator.paintTextComponentBorder(parent, g2offscreen,
168
0, 0, parent.getWidth(), parent.getHeight(), radius,
170
g2offscreen.translate(offsetX, offsetY);
172
g2offscreen.dispose();
174
Graphics2D g2d = (Graphics2D) g.create();
175
g2d.setComposite(LafWidgetUtilities.getAlphaComposite(this, extraAlpha,
178
g2d.drawImage(offscreen, 0, 0, null);
183
public void paint(Graphics g) {
184
Graphics2D g2d = (Graphics2D) g.create();
186
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(this);
187
int width = getWidth();
188
int height = getHeight();
189
int clipDelta = (int) SubstanceSizeUtils
190
.getBorderStrokeWidth(componentFontSize);
192
if (this.getComponentOrientation().isLeftToRight()) {
193
g2d.clipRect(clipDelta, 0, width - clipDelta, height);
195
g2d.clipRect(0, 0, width - clipDelta, height);