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.ui;
33
import java.awt.event.MouseEvent;
34
import java.beans.PropertyChangeEvent;
35
import java.beans.PropertyChangeListener;
38
import javax.swing.border.Border;
39
import javax.swing.plaf.*;
40
import javax.swing.plaf.basic.BasicBorders;
41
import javax.swing.plaf.basic.BasicTextFieldUI;
43
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
44
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
45
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
46
import org.pushingpixels.substance.internal.utils.*;
47
import org.pushingpixels.substance.internal.utils.border.SubstanceTextComponentBorder;
48
import org.pushingpixels.trident.swing.SwingRepaintCallback;
51
* UI for text fields in <b>Substance</b> look and feel.
53
* @author Kirill Grouchnikov
55
public class SubstanceTextFieldUI extends BasicTextFieldUI implements
57
protected StateTransitionTracker stateTransitionTracker;
60
* The associated text field.
62
protected JTextField textField;
65
* Property change listener.
67
protected PropertyChangeListener substancePropertyChangeListener;
70
* Listener for transition animations.
72
private RolloverTextControlListener substanceRolloverListener;
75
* Surrogate button model for tracking the state transitions.
77
private ButtonModel transitionModel;
82
* @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
84
public static ComponentUI createUI(JComponent comp) {
85
SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
86
return new SubstanceTextFieldUI(comp);
93
* Component (text field).
95
public SubstanceTextFieldUI(JComponent c) {
97
this.textField = (JTextField) c;
99
this.transitionModel = new DefaultButtonModel();
100
this.transitionModel.setArmed(false);
101
this.transitionModel.setSelected(false);
102
this.transitionModel.setPressed(false);
103
this.transitionModel.setRollover(false);
104
this.transitionModel.setEnabled(this.textField.isEnabled());
106
this.stateTransitionTracker = new StateTransitionTracker(
107
this.textField, this.transitionModel);
108
this.stateTransitionTracker
109
.setRepaintCallback(new StateTransitionTracker.RepaintCallback() {
111
public SwingRepaintCallback getRepaintCallback() {
112
return SubstanceCoreUtilities
113
.getTextComponentRepaintCallback(textField);
122
* javax.swing.plaf.basic.BasicTextUI#paintBackground(java.awt.Graphics)
125
protected void paintBackground(Graphics g) {
126
SubstanceTextUtilities.paintTextCompBackground(g, this.textField);
132
* @see javax.swing.plaf.basic.BasicTextUI#installListeners()
135
protected void installListeners() {
136
super.installListeners();
138
this.substanceRolloverListener = new RolloverTextControlListener(
139
this.textField, this, this.transitionModel);
140
this.substanceRolloverListener.registerListeners();
142
this.stateTransitionTracker.registerModelListeners();
143
this.stateTransitionTracker.registerFocusListeners();
145
this.substancePropertyChangeListener = new PropertyChangeListener() {
147
public void propertyChange(PropertyChangeEvent evt) {
148
if ("font".equals(evt.getPropertyName())) {
149
SwingUtilities.invokeLater(new Runnable() {
152
// remember the caret location - issue 404
153
int caretPos = textField.getCaretPosition();
154
textField.updateUI();
155
textField.setCaretPosition(caretPos);
156
Container parent = textField.getParent();
157
if (parent != null) {
165
if ("enabled".equals(evt.getPropertyName())) {
166
transitionModel.setEnabled(textField.isEnabled());
171
.addPropertyChangeListener(this.substancePropertyChangeListener);
177
* @see javax.swing.plaf.basic.BasicTextUI#uninstallListeners()
180
protected void uninstallListeners() {
181
this.stateTransitionTracker.unregisterModelListeners();
182
this.stateTransitionTracker.unregisterFocusListeners();
185
.removePropertyChangeListener(this.substancePropertyChangeListener);
186
this.substancePropertyChangeListener = null;
188
this.substanceRolloverListener.unregisterListeners();
189
this.substanceRolloverListener = null;
191
// this.textField.removeFocusListener(this.substanceFocusListener);
192
// this.substanceFocusListener = null;
194
super.uninstallListeners();
200
* @see javax.swing.plaf.basic.BasicTextUI#installDefaults()
203
protected void installDefaults() {
204
super.installDefaults();
205
Border b = this.textField.getBorder();
206
if (b == null || b instanceof UIResource) {
207
Border newB = new BorderUIResource.CompoundBorderUIResource(
208
new SubstanceTextComponentBorder(SubstanceSizeUtils
209
.getTextBorderInsets(SubstanceSizeUtils
210
.getComponentFontSize(this.textField))),
211
new BasicBorders.MarginBorder());
212
this.textField.setBorder(newB);
215
// support for per-window skins
216
SwingUtilities.invokeLater(new Runnable() {
219
if (textField == null)
221
Color foregr = textField.getForeground();
222
if ((foregr == null) || (foregr instanceof UIResource)) {
224
.setForeground(SubstanceColorUtilities
225
.getForegroundColor(SubstanceLookAndFeel
226
.getCurrentSkin(textField)
227
.getEnabledColorScheme(
229
.getDecorationType(textField))));
236
public boolean isInside(MouseEvent me) {
237
if (!SubstanceLookAndFeel.isCurrentLookAndFeel()) {
240
Shape contour = SubstanceOutlineUtilities.getBaseOutline(
241
this.textField, 2.0f * SubstanceSizeUtils
242
.getClassicButtonCornerRadius(SubstanceSizeUtils
243
.getComponentFontSize(this.textField)), null);
244
return contour.contains(me.getPoint());
248
public StateTransitionTracker getTransitionTracker() {
249
return this.stateTransitionTracker;