001 /*
002 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.plaf.synth;
027
028 import javax.swing.*;
029 import javax.swing.text.*;
030 import javax.swing.event.*;
031 import javax.swing.plaf.*;
032 import javax.swing.plaf.basic.BasicTextFieldUI;
033 import java.awt.*;
034 import java.awt.event.FocusEvent;
035 import java.awt.event.FocusListener;
036 import java.beans.PropertyChangeEvent;
037
038 import sun.swing.plaf.synth.SynthUI;
039
040 /**
041 * Basis of a look and feel for a JTextField in the Synth
042 * look and feel.
043 * <p>
044 * <strong>Warning:</strong>
045 * Serialized objects of this class will not be compatible with
046 * future Swing releases. The current serialization support is
047 * appropriate for short term storage or RMI between applications running
048 * the same version of Swing. As of 1.4, support for long term storage
049 * of all JavaBeans<sup><font size="-2">TM</font></sup>
050 * has been added to the <code>java.beans</code> package.
051 * Please see {@link java.beans.XMLEncoder}.
052 *
053 * @author Shannon Hickey
054 * @version 1.19 05/05/07
055 */
056 class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI,
057 FocusListener {
058 private SynthStyle style;
059
060 /**
061 * Creates a UI for a JTextField.
062 *
063 * @param c the text field
064 * @return the UI
065 */
066 public static ComponentUI createUI(JComponent c) {
067 return new SynthTextFieldUI();
068 }
069
070 public SynthTextFieldUI() {
071 super ();
072 }
073
074 private void updateStyle(JTextComponent comp) {
075 SynthContext context = getContext(comp, ENABLED);
076 SynthStyle oldStyle = style;
077
078 style = SynthLookAndFeel.updateStyle(context, this );
079
080 if (style != oldStyle) {
081 SynthTextFieldUI.updateStyle(comp, context,
082 getPropertyPrefix());
083
084 if (oldStyle != null) {
085 uninstallKeyboardActions();
086 installKeyboardActions();
087 }
088 }
089 context.dispose();
090 }
091
092 static void updateStyle(JTextComponent comp, SynthContext context,
093 String prefix) {
094 SynthStyle style = context.getStyle();
095
096 Color color = comp.getCaretColor();
097 if (color == null || color instanceof UIResource) {
098 comp.setCaretColor((Color) style.get(context, prefix
099 + ".caretForeground"));
100 }
101
102 Color fg = comp.getForeground();
103 if (fg == null || fg instanceof UIResource) {
104 fg = style.getColorForState(context,
105 ColorType.TEXT_FOREGROUND);
106 if (fg != null) {
107 comp.setForeground(fg);
108 }
109 }
110
111 Object ar = style.get(context, prefix + ".caretAspectRatio");
112 if (ar instanceof Number) {
113 comp.putClientProperty("caretAspectRatio", ar);
114 }
115
116 context.setComponentState(SELECTED | FOCUSED);
117
118 Color s = comp.getSelectionColor();
119 if (s == null || s instanceof UIResource) {
120 comp.setSelectionColor(style.getColor(context,
121 ColorType.TEXT_BACKGROUND));
122 }
123
124 Color sfg = comp.getSelectedTextColor();
125 if (sfg == null || sfg instanceof UIResource) {
126 comp.setSelectedTextColor(style.getColor(context,
127 ColorType.TEXT_FOREGROUND));
128 }
129
130 context.setComponentState(DISABLED);
131
132 Color dfg = comp.getDisabledTextColor();
133 if (dfg == null || dfg instanceof UIResource) {
134 comp.setDisabledTextColor(style.getColor(context,
135 ColorType.TEXT_FOREGROUND));
136 }
137
138 Insets margin = comp.getMargin();
139 if (margin == null || margin instanceof UIResource) {
140 margin = (Insets) style.get(context, prefix + ".margin");
141
142 if (margin == null) {
143 // Some places assume margins are non-null.
144 margin = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
145 }
146 comp.setMargin(margin);
147 }
148
149 Caret caret = comp.getCaret();
150 if (caret instanceof UIResource) {
151 Object o = style.get(context, prefix + ".caretBlinkRate");
152 if (o != null && o instanceof Integer) {
153 Integer rate = (Integer) o;
154 caret.setBlinkRate(rate.intValue());
155 }
156 }
157 }
158
159 public SynthContext getContext(JComponent c) {
160 return getContext(c, getComponentState(c));
161 }
162
163 private SynthContext getContext(JComponent c, int state) {
164 return SynthContext.getContext(SynthContext.class, c,
165 SynthLookAndFeel.getRegion(c), style, state);
166 }
167
168 private int getComponentState(JComponent c) {
169 return SynthLookAndFeel.getComponentState(c);
170 }
171
172 public void update(Graphics g, JComponent c) {
173 SynthContext context = getContext(c);
174
175 SynthLookAndFeel.update(context, g);
176 paintBackground(context, g, c);
177 paint(context, g);
178 context.dispose();
179 }
180
181 /**
182 * Paints the interface. This is routed to the
183 * paintSafely method under the guarantee that
184 * the model won't change from the view of this thread
185 * while it's rendering (if the associated model is
186 * derived from AbstractDocument). This enables the
187 * model to potentially be updated asynchronously.
188 */
189 protected void paint(SynthContext context, Graphics g) {
190 super .paint(g, getComponent());
191 }
192
193 void paintBackground(SynthContext context, Graphics g, JComponent c) {
194 context.getPainter().paintTextFieldBackground(context, g, 0, 0,
195 c.getWidth(), c.getHeight());
196 }
197
198 public void paintBorder(SynthContext context, Graphics g, int x,
199 int y, int w, int h) {
200 context.getPainter().paintTextFieldBorder(context, g, x, y, w,
201 h);
202 }
203
204 protected void paintBackground(Graphics g) {
205 // Overriden to do nothing, all our painting is done from update/paint.
206 }
207
208 /**
209 * This method gets called when a bound property is changed
210 * on the associated JTextComponent. This is a hook
211 * which UI implementations may change to reflect how the
212 * UI displays bound properties of JTextComponent subclasses.
213 * This is implemented to do nothing (i.e. the response to
214 * properties in JTextComponent itself are handled prior
215 * to calling this method).
216 *
217 * @param evt the property change event
218 */
219 protected void propertyChange(PropertyChangeEvent evt) {
220 if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
221 updateStyle((JTextComponent) evt.getSource());
222 }
223 super .propertyChange(evt);
224 }
225
226 public void focusGained(FocusEvent e) {
227 getComponent().repaint();
228 }
229
230 public void focusLost(FocusEvent e) {
231 getComponent().repaint();
232 }
233
234 protected void installDefaults() {
235 // Installs the text cursor on the component
236 super .installDefaults();
237 updateStyle((JTextComponent) getComponent());
238 getComponent().addFocusListener(this );
239 }
240
241 protected void uninstallDefaults() {
242 SynthContext context = getContext(getComponent(), ENABLED);
243
244 getComponent().putClientProperty("caretAspectRatio", null);
245 getComponent().removeFocusListener(this );
246
247 style.uninstallDefaults(context);
248 context.dispose();
249 style = null;
250 super .uninstallDefaults();
251 }
252
253 public void installUI(JComponent c) {
254 super.installUI(c);
255 }
256 }
|