blob: 5b7cbd0a5f5af7e2e669673ed99af1c442e9ed59 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.swing.plaf.synth;
27
28import javax.swing.*;
29import javax.swing.text.*;
30import javax.swing.event.*;
31import javax.swing.plaf.*;
32import javax.swing.plaf.basic.BasicTextFieldUI;
33import java.awt.*;
34import java.awt.event.FocusEvent;
35import java.awt.event.FocusListener;
36import java.beans.PropertyChangeEvent;
37
38import sun.swing.plaf.synth.SynthUI;
39
40/**
41 * Basis of a look and feel for a JTextField in the Synth
42 * look and feel.
43 * <p>
44 * <strong>Warning:</strong>
45 * Serialized objects of this class will not be compatible with
46 * future Swing releases. The current serialization support is
47 * appropriate for short term storage or RMI between applications running
48 * the same version of Swing. As of 1.4, support for long term storage
49 * of all JavaBeans<sup><font size="-2">TM</font></sup>
50 * has been added to the <code>java.beans</code> package.
51 * Please see {@link java.beans.XMLEncoder}.
52 *
53 * @author Shannon Hickey
54 */
55class SynthTextFieldUI
56 extends BasicTextFieldUI
57 implements SynthUI, FocusListener
58{
59 private SynthStyle style;
60
61 /**
62 * Creates a UI for a JTextField.
63 *
64 * @param c the text field
65 * @return the UI
66 */
67 public static ComponentUI createUI(JComponent c) {
68 return new SynthTextFieldUI();
69 }
70
71 public SynthTextFieldUI() {
72 super();
73 }
74
75 private void updateStyle(JTextComponent comp) {
76 SynthContext context = getContext(comp, ENABLED);
77 SynthStyle oldStyle = style;
78
79 style = SynthLookAndFeel.updateStyle(context, this);
80
81 if (style != oldStyle) {
82 SynthTextFieldUI.updateStyle(comp, context, getPropertyPrefix());
83
84 if (oldStyle != null) {
85 uninstallKeyboardActions();
86 installKeyboardActions();
87 }
88 }
89 context.dispose();
90 }
91
92 static void updateStyle(JTextComponent comp, SynthContext context,
93 String prefix) {
94 SynthStyle style = context.getStyle();
95
96 Color color = comp.getCaretColor();
97 if (color == null || color instanceof UIResource) {
98 comp.setCaretColor(
99 (Color)style.get(context, prefix + ".caretForeground"));
100 }
101
102 Color fg = comp.getForeground();
103 if (fg == null || fg instanceof UIResource) {
104 fg = style.getColorForState(context, ColorType.TEXT_FOREGROUND);
105 if (fg != null) {
106 comp.setForeground(fg);
107 }
108 }
109
110 Object ar = style.get(context, prefix + ".caretAspectRatio");
111 if (ar instanceof Number) {
112 comp.putClientProperty("caretAspectRatio", ar);
113 }
114
115 context.setComponentState(SELECTED | FOCUSED);
116
117 Color s = comp.getSelectionColor();
118 if (s == null || s instanceof UIResource) {
119 comp.setSelectionColor(
120 style.getColor(context, ColorType.TEXT_BACKGROUND));
121 }
122
123 Color sfg = comp.getSelectedTextColor();
124 if (sfg == null || sfg instanceof UIResource) {
125 comp.setSelectedTextColor(
126 style.getColor(context, ColorType.TEXT_FOREGROUND));
127 }
128
129 context.setComponentState(DISABLED);
130
131 Color dfg = comp.getDisabledTextColor();
132 if (dfg == null || dfg instanceof UIResource) {
133 comp.setDisabledTextColor(
134 style.getColor(context, ColorType.TEXT_FOREGROUND));
135 }
136
137 Insets margin = comp.getMargin();
138 if (margin == null || margin instanceof UIResource) {
139 margin = (Insets)style.get(context, prefix + ".margin");
140
141 if (margin == null) {
142 // Some places assume margins are non-null.
143 margin = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
144 }
145 comp.setMargin(margin);
146 }
147
148 Caret caret = comp.getCaret();
149 if (caret instanceof UIResource) {
150 Object o = style.get(context, prefix + ".caretBlinkRate");
151 if (o != null && o instanceof Integer) {
152 Integer rate = (Integer)o;
153 caret.setBlinkRate(rate.intValue());
154 }
155 }
156 }
157
158 public SynthContext getContext(JComponent c) {
159 return getContext(c, getComponentState(c));
160 }
161
162 private SynthContext getContext(JComponent c, int state) {
163 return SynthContext.getContext(SynthContext.class, c,
164 SynthLookAndFeel.getRegion(c), style, state);
165 }
166
167 private int getComponentState(JComponent c) {
168 return SynthLookAndFeel.getComponentState(c);
169 }
170
171 public void update(Graphics g, JComponent c) {
172 SynthContext context = getContext(c);
173
174 SynthLookAndFeel.update(context, g);
175 paintBackground(context, g, c);
176 paint(context, g);
177 context.dispose();
178 }
179
180 /**
181 * Paints the interface. This is routed to the
182 * paintSafely method under the guarantee that
183 * the model won't change from the view of this thread
184 * while it's rendering (if the associated model is
185 * derived from AbstractDocument). This enables the
186 * model to potentially be updated asynchronously.
187 */
188 protected void paint(SynthContext context, Graphics g) {
189 super.paint(g, getComponent());
190 }
191
192 void paintBackground(SynthContext context, Graphics g, JComponent c) {
193 context.getPainter().paintTextFieldBackground(context, g, 0, 0,
194 c.getWidth(), c.getHeight());
195 }
196
197 public void paintBorder(SynthContext context, Graphics g, int x,
198 int y, int w, int h) {
199 context.getPainter().paintTextFieldBorder(context, g, x, y, w, h);
200 }
201
202 protected void paintBackground(Graphics g) {
203 // Overriden to do nothing, all our painting is done from update/paint.
204 }
205
206 /**
207 * This method gets called when a bound property is changed
208 * on the associated JTextComponent. This is a hook
209 * which UI implementations may change to reflect how the
210 * UI displays bound properties of JTextComponent subclasses.
211 * This is implemented to do nothing (i.e. the response to
212 * properties in JTextComponent itself are handled prior
213 * to calling this method).
214 *
215 * @param evt the property change event
216 */
217 protected void propertyChange(PropertyChangeEvent evt) {
218 if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
219 updateStyle((JTextComponent)evt.getSource());
220 }
221 super.propertyChange(evt);
222 }
223
224 public void focusGained(FocusEvent e) {
225 getComponent().repaint();
226 }
227
228 public void focusLost(FocusEvent e) {
229 getComponent().repaint();
230 }
231
232 protected void installDefaults() {
233 // Installs the text cursor on the component
234 super.installDefaults();
235 updateStyle((JTextComponent)getComponent());
236 getComponent().addFocusListener(this);
237 }
238
239 protected void uninstallDefaults() {
240 SynthContext context = getContext(getComponent(), ENABLED);
241
242 getComponent().putClientProperty("caretAspectRatio", null);
243 getComponent().removeFocusListener(this);
244
245 style.uninstallDefaults(context);
246 context.dispose();
247 style = null;
248 super.uninstallDefaults();
249 }
250
251 public void installUI(JComponent c) {
252 super.installUI(c);
253 }
254}