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.icon;
32
import java.awt.AlphaComposite;
33
import java.awt.Component;
34
import java.awt.Graphics;
35
import java.awt.Graphics2D;
36
import java.awt.image.BufferedImage;
39
import javax.swing.Icon;
40
import javax.swing.ImageIcon;
41
import javax.swing.JCheckBoxMenuItem;
42
import javax.swing.JMenuItem;
43
import javax.swing.plaf.UIResource;
45
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
46
import org.pushingpixels.substance.api.ComponentState;
47
import org.pushingpixels.substance.api.ComponentStateFacet;
48
import org.pushingpixels.substance.api.SubstanceColorScheme;
49
import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter;
50
import org.pushingpixels.substance.api.painter.fill.SubstanceFillPainter;
51
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
52
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
53
import org.pushingpixels.substance.internal.utils.HashMapKey;
54
import org.pushingpixels.substance.internal.utils.LazyResettableHashMap;
55
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
56
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
57
import org.pushingpixels.substance.internal.utils.SubstanceImageCreator;
58
import org.pushingpixels.substance.internal.utils.SubstanceSizeUtils;
61
* Icon for the {@link JCheckBoxMenuItem}s.
63
* @author Kirill Grouchnikov
65
public class CheckBoxMenuItemIcon implements Icon, UIResource {
67
* The size of <code>this</code> icon.
72
* The associated menu item.
74
private JMenuItem menuItem;
77
* Icon cache to speed up the painting.
79
private static LazyResettableHashMap<Icon> iconMap = new LazyResettableHashMap<Icon>(
80
"CheckBoxMenuItemIcon");
86
* The corresponding menu item.
88
* The size of <code>this</code> icon.
90
public CheckBoxMenuItemIcon(JMenuItem menuItem, int size) {
91
this.menuItem = menuItem;
96
* Returns the current icon to paint.
98
* @return Icon to paint.
100
private Icon getIconToPaint() {
101
if (this.menuItem == null)
104
TransitionAwareUI transitionAwareUI = (TransitionAwareUI) this.menuItem
106
StateTransitionTracker stateTransitionTracker = transitionAwareUI
107
.getTransitionTracker();
109
StateTransitionTracker.ModelStateInfo modelStateInfo = stateTransitionTracker
110
.getModelStateInfo();
111
Map<ComponentState, StateTransitionTracker.StateContributionInfo> activeStates = modelStateInfo
112
.getStateContributionMap();
114
SubstanceFillPainter fillPainter = SubstanceCoreUtilities
115
.getFillPainter(this.menuItem);
116
SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
117
.getBorderPainter(this.menuItem);
118
ComponentState currState = modelStateInfo.getCurrModelState();
120
SubstanceColorScheme baseFillColorScheme = SubstanceColorSchemeUtilities
121
.getColorScheme(this.menuItem, ColorSchemeAssociationKind.FILL,
123
SubstanceColorScheme baseMarkColorScheme = SubstanceColorSchemeUtilities
124
.getColorScheme(this.menuItem, ColorSchemeAssociationKind.MARK,
126
SubstanceColorScheme baseBorderColorScheme = SubstanceColorSchemeUtilities
127
.getColorScheme(this.menuItem,
128
ColorSchemeAssociationKind.BORDER, currState);
129
float visibility = stateTransitionTracker
130
.getFacetStrength(ComponentStateFacet.SELECTION);
131
boolean isCheckMarkFadingOut = !currState
132
.isFacetActive(ComponentStateFacet.SELECTION);
134
int fontSize = SubstanceSizeUtils.getComponentFontSize(this.menuItem);
135
int checkMarkSize = this.size + 3;
137
HashMapKey keyBase = SubstanceCoreUtilities.getHashKey(fontSize,
138
checkMarkSize, fillPainter.getDisplayName(), borderPainter
140
baseFillColorScheme.getDisplayName(), baseMarkColorScheme
141
.getDisplayName(), baseBorderColorScheme
142
.getDisplayName(), visibility, isCheckMarkFadingOut);
143
Icon iconBase = iconMap.get(keyBase);
144
if (iconBase == null) {
145
iconBase = new ImageIcon(SubstanceImageCreator.getCheckBox(
146
this.menuItem, fillPainter, borderPainter, checkMarkSize,
147
currState, baseFillColorScheme, baseMarkColorScheme,
148
baseBorderColorScheme, visibility, isCheckMarkFadingOut));
149
iconMap.put(keyBase, iconBase);
151
if (currState.isDisabled() || (activeStates.size() == 1)) {
155
BufferedImage result = SubstanceCoreUtilities.getBlankImage(iconBase
156
.getIconWidth(), iconBase.getIconHeight());
157
Graphics2D g2d = result.createGraphics();
158
// draw the base layer
159
iconBase.paintIcon(this.menuItem, g2d, 0, 0);
161
// draw other active layers
162
for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : activeStates
164
ComponentState activeState = activeEntry.getKey();
165
// System.out.println("Painting state " + activeState + "[curr is "
166
// + currState + "] with " + activeEntry.getValue());
167
if (activeState == currState)
170
float stateContribution = activeEntry.getValue().getContribution();
171
if (stateContribution > 0.0f) {
172
g2d.setComposite(AlphaComposite.SrcOver
173
.derive(stateContribution));
174
SubstanceColorScheme fillColorScheme = SubstanceColorSchemeUtilities
175
.getColorScheme(this.menuItem,
176
ColorSchemeAssociationKind.FILL, activeState);
177
SubstanceColorScheme markColorScheme = SubstanceColorSchemeUtilities
178
.getColorScheme(this.menuItem,
179
ColorSchemeAssociationKind.MARK, activeState);
180
SubstanceColorScheme borderColorScheme = SubstanceColorSchemeUtilities
181
.getColorScheme(this.menuItem,
182
ColorSchemeAssociationKind.BORDER, activeState);
184
HashMapKey keyLayer = SubstanceCoreUtilities.getHashKey(
185
fontSize, checkMarkSize, fillPainter.getDisplayName(),
186
borderPainter.getDisplayName(), fillColorScheme
187
.getDisplayName(), markColorScheme
188
.getDisplayName(), borderColorScheme
189
.getDisplayName(), visibility);
190
Icon iconLayer = iconMap.get(keyLayer);
191
if (iconLayer == null) {
192
iconLayer = new ImageIcon(SubstanceImageCreator
193
.getCheckBox(this.menuItem, fillPainter,
194
borderPainter, checkMarkSize, currState,
195
fillColorScheme, markColorScheme,
196
borderColorScheme, visibility,
197
isCheckMarkFadingOut));
198
iconMap.put(keyLayer, iconLayer);
201
iconLayer.paintIcon(this.menuItem, g2d, 0, 0);
206
return new ImageIcon(result);
212
* @see javax.swing.Icon#paintIcon(java.awt.Component, java.awt.Graphics,
216
public void paintIcon(Component c, Graphics g, int x, int y) {
217
Icon iconToDraw = this.getIconToPaint();
218
if (iconToDraw != null)
219
iconToDraw.paintIcon(c, g, x, y);
225
* @see javax.swing.Icon#getIconWidth()
228
public int getIconWidth() {
229
return this.size + 2;
235
* @see javax.swing.Icon#getIconHeight()
238
public int getIconHeight() {
239
return this.size + 2;