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.api.renderers;
32
import java.awt.Color;
33
import java.awt.Component;
34
import java.awt.Dimension;
35
import java.awt.Insets;
38
import javax.swing.JComboBox;
39
import javax.swing.JComponent;
40
import javax.swing.JLabel;
41
import javax.swing.JList;
42
import javax.swing.border.EmptyBorder;
43
import javax.swing.plaf.ColorUIResource;
44
import javax.swing.plaf.ComboBoxUI;
45
import javax.swing.plaf.ListUI;
47
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
48
import org.pushingpixels.substance.api.ComponentState;
49
import org.pushingpixels.substance.api.ComponentStateFacet;
50
import org.pushingpixels.substance.api.SubstanceColorScheme;
51
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
52
import org.pushingpixels.substance.internal.animation.StateTransitionTracker.ModelStateInfo;
53
import org.pushingpixels.substance.internal.animation.StateTransitionTracker.StateContributionInfo;
54
import org.pushingpixels.substance.internal.ui.SubstanceComboBoxUI;
55
import org.pushingpixels.substance.internal.ui.SubstanceListUI;
56
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
57
import org.pushingpixels.substance.internal.utils.SubstanceSizeUtils;
58
import org.pushingpixels.substance.internal.utils.SubstanceStripingUtils;
59
import org.pushingpixels.substance.internal.utils.SubstanceTextUtilities;
60
import org.pushingpixels.substance.internal.utils.UpdateOptimizationInfo;
63
* Renderer for combo boxes.
65
* @author Kirill Grouchnikov
68
public class SubstanceDefaultComboBoxRenderer extends
69
SubstanceDefaultListCellRenderer {
71
* The associated combo box.
73
private JComboBox combo;
79
* The associated combo box.
81
public SubstanceDefaultComboBoxRenderer(JComboBox combo) {
84
// this.setOpaque(true);
86
Insets ins = SubstanceSizeUtils
87
.getListCellRendererInsets(SubstanceSizeUtils
88
.getComponentFontSize(combo));
90
.setBorder(new EmptyBorder(ins.top, ins.left, ins.bottom,
93
// Insets i = b.getBorderInsets(combo);
94
// System.out.println("Combo inner - " + combo.getFont().getSize() +" :
96
// + i.top + ", " + i.left + ", " + i.bottom + ", " + i.right);
103
* javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing
104
* .JList, java.lang.Object, int, boolean, boolean)
107
public Component getListCellRendererComponent(JList list, Object value,
108
int index, boolean isSelected, boolean cellHasFocus) {
110
JComponent result = (JComponent) super.getListCellRendererComponent(
111
list, value, index, isSelected, cellHasFocus);
113
ListUI baseListUI = list.getUI();
114
ComboBoxUI baseComboUI = combo.getUI();
115
if ((baseListUI instanceof SubstanceListUI)
116
&& (baseComboUI instanceof SubstanceComboBoxUI)) {
117
SubstanceListUI listUI = (SubstanceListUI) baseListUI;
118
SubstanceComboBoxUI comboUI = (SubstanceComboBoxUI) baseComboUI;
120
// special case for the combobox. The selected value is
121
// painted using the renderer of the list, and the index
124
StateTransitionTracker stateTransitionTracker = comboUI
125
.getTransitionTracker();
126
ModelStateInfo modelStateInfo = stateTransitionTracker
127
.getModelStateInfo();
128
ComponentState currState = modelStateInfo.getCurrModelState();
129
float comboAlpha = SubstanceColorSchemeUtilities.getAlpha(
131
Color fg = SubstanceTextUtilities
132
.getForegroundColor(combo, ((JLabel) result).getText(),
133
modelStateInfo, comboAlpha);
134
result.setForeground(fg);
136
// use highlight color scheme for selected and rollover
137
// elements in the drop down list
138
StateTransitionTracker.ModelStateInfo modelStateInfo = listUI
139
.getModelStateInfo(index, result);
140
ComponentState currState = listUI.getCellState(index, result);
141
if (modelStateInfo == null) {
142
SubstanceColorScheme scheme = getColorSchemeForState(list,
143
index, listUI, currState);
144
// SubstanceColorScheme scheme =
145
// SubstanceColorSchemeUtilities
146
// .getColorScheme(list, kindForCurr, currState);
147
result.setForeground(new ColorUIResource(scheme
148
.getForegroundColor()));
150
Map<ComponentState, StateContributionInfo> activeStates = modelStateInfo
151
.getStateContributionMap();
152
SubstanceColorScheme colorScheme = getColorSchemeForState(
153
list, index, listUI, currState);
154
if (currState.isDisabled() || (activeStates == null)
155
|| (activeStates.size() == 1)) {
156
super.setForeground(new ColorUIResource(colorScheme
157
.getForegroundColor()));
159
float aggrRed = 0.0f;
160
float aggrGreen = 0.0f;
161
float aggrBlue = 0.0f;
162
for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> activeEntry : modelStateInfo
163
.getStateContributionMap().entrySet()) {
164
ComponentState activeState = activeEntry.getKey();
165
float activeContribution = activeEntry.getValue()
167
if (activeContribution == 0.0f)
170
SubstanceColorScheme scheme = getColorSchemeForState(
171
list, index, listUI, activeState);
172
// SubstanceColorScheme scheme = (activeState ==
173
// ComponentState.DEFAULT) ? listUI
174
// .getDefaultColorScheme()
175
// : listUI.getHighlightColorScheme(activeState);
176
// if (scheme == null) {
177
// scheme = (activeState == ComponentState.DEFAULT)
179
// SubstanceColorSchemeUtilities
180
// .getColorScheme(list, activeState)
181
// : SubstanceColorSchemeUtilities
184
// ColorSchemeAssociationKind.HIGHLIGHT,
187
Color schemeFg = scheme.getForegroundColor();
188
aggrRed += schemeFg.getRed() * activeContribution;
189
aggrGreen += schemeFg.getGreen()
190
* activeContribution;
191
aggrBlue += schemeFg.getBlue() * activeContribution;
194
.setForeground(new ColorUIResource(new Color(
195
(int) aggrRed, (int) aggrGreen,
201
SubstanceStripingUtils.applyStripedBackground(list, index, this);
203
result.setEnabled(combo.isEnabled());
207
private SubstanceColorScheme getColorSchemeForState(JList list, int index,
208
SubstanceListUI listUI, ComponentState state) {
209
boolean toUseHighlightKindForCurrState = (index >= 0)
210
&& (state.isFacetActive(ComponentStateFacet.ROLLOVER) || state
211
.isFacetActive(ComponentStateFacet.SELECTION));
212
UpdateOptimizationInfo updateOptimizationInfo = listUI
213
.getUpdateOptimizationInfo();
214
if (toUseHighlightKindForCurrState) {
215
if (updateOptimizationInfo == null) {
216
return SubstanceColorSchemeUtilities.getColorScheme(list,
217
ColorSchemeAssociationKind.HIGHLIGHT, state);
219
return updateOptimizationInfo.getHighlightColorScheme(state);
222
if (updateOptimizationInfo == null) {
223
return SubstanceColorSchemeUtilities
224
.getColorScheme(list, state);
226
return updateOptimizationInfo.getDefaultScheme();
234
* @see javax.swing.JComponent#getPreferredSize()
237
public Dimension getPreferredSize() {
240
if ((this.getText() == null) || (this.getText().equals(""))) {
242
size = super.getPreferredSize();
245
size = super.getPreferredSize();
252
* UI resource for renderer (does nothing yet).
254
* @author Kirill Grouchnikov
256
public static class SubstanceUIResource extends
257
SubstanceDefaultComboBoxRenderer implements
258
javax.swing.plaf.UIResource {
260
* Creates a new renderer resource.
265
public SubstanceUIResource(JComboBox combo) {