1 /*
2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.apple.laf;
27 
28 import java.awt.*;
29 
30 import javax.swing.*;
31 import javax.swing.plaf.ComponentUI;
32 import javax.swing.plaf.basic.BasicTextFieldUI;
33 import javax.swing.text.*;
34 
35 import com.apple.laf.AquaUtils.JComponentPainter;
36 
37 public class AquaTextFieldUI extends BasicTextFieldUI {
createUI(final JComponent c)38     public static ComponentUI createUI(final JComponent c) {
39         return new AquaTextFieldUI();
40     }
41 
42     protected JComponentPainter delegate;
43     protected AquaFocusHandler handler;
44 
45     @Override
installListeners()46     protected void installListeners() {
47         super.installListeners();
48 
49         handler = new AquaFocusHandler();
50         final JTextComponent c = getComponent();
51         c.addFocusListener(handler);
52         c.addPropertyChangeListener(handler);
53 
54         LookAndFeel.installProperty(c, "opaque", UIManager.getBoolean(getPropertyPrefix() + "opaque"));
55         AquaUtilControlSize.addSizePropertyListener(c);
56         AquaTextFieldSearch.installSearchFieldListener(c);
57     }
58 
59     @Override
uninstallListeners()60     protected void uninstallListeners() {
61         final JTextComponent c = getComponent();
62         AquaTextFieldSearch.uninstallSearchFieldListener(c);
63         AquaUtilControlSize.removeSizePropertyListener(c);
64         c.removeFocusListener(handler);
65         c.removePropertyChangeListener(handler);
66         handler = null;
67 
68         super.uninstallListeners();
69     }
70 
71     boolean oldDragState = false;
72     @Override
installDefaults()73     protected void installDefaults() {
74         if (!GraphicsEnvironment.isHeadless()) {
75             oldDragState = getComponent().getDragEnabled();
76             getComponent().setDragEnabled(true);
77         }
78 
79         super.installDefaults();
80     }
81 
82     @Override
uninstallDefaults()83     protected void uninstallDefaults() {
84         super.uninstallDefaults();
85 
86         if (!GraphicsEnvironment.isHeadless()) {
87             getComponent().setDragEnabled(oldDragState);
88         }
89     }
90 
91     // Install a default keypress action which handles Cmd and Option keys
92     // properly
93     @Override
installKeyboardActions()94     protected void installKeyboardActions() {
95         super.installKeyboardActions();
96         AquaKeyBindings.instance().setDefaultAction(getKeymapName());
97     }
98 
99     @Override
getVisibleEditorRect()100     protected Rectangle getVisibleEditorRect() {
101         final Rectangle rect = super.getVisibleEditorRect();
102         if (rect == null) return null;
103 
104         if (!getComponent().isOpaque()) {
105             rect.y -= 3;
106             rect.height += 6;
107         }
108 
109         return rect;
110     }
111 
112     @Override
paintSafely(final Graphics g)113     protected void paintSafely(final Graphics g) {
114         paintBackgroundSafely(g);
115         super.paintSafely(g);
116     }
117 
paintBackgroundSafely(final Graphics g)118     protected void paintBackgroundSafely(final Graphics g) {
119         final JTextComponent c = getComponent();
120         final int width = c.getWidth();
121         final int height = c.getHeight();
122 
123         // a delegate takes precedence
124         if (delegate != null) {
125             delegate.paint(c, g, 0, 0, width, height);
126             return;
127         }
128 
129         final boolean isOpaque = c.isOpaque();
130         if (!(c.getBorder() instanceof AquaTextFieldBorder)) {
131             // developer must have set a custom border
132             if (!isOpaque && AquaUtils.hasOpaqueBeenExplicitlySet(c)) return;
133 
134             // must fill whole region with background color if opaque
135             g.setColor(c.getBackground());
136             g.fillRect(0, 0, width, height);
137             return;
138         }
139 
140         // using our own border
141         g.setColor(c.getBackground());
142         if (isOpaque) {
143             g.fillRect(0, 0, width, height);
144             return;
145         }
146 
147         final Insets margin = c.getMargin();
148         Insets insets = c.getInsets();
149 
150         if (insets == null) insets = new Insets(0, 0, 0, 0);
151         if (margin != null) {
152             insets.top -= margin.top;
153             insets.left -= margin.left;
154             insets.bottom -= margin.bottom;
155             insets.right -= margin.right;
156         }
157 
158         // the common case
159         final int shrinkage = AquaTextFieldBorder.getShrinkageFor(c, height);
160         g.fillRect(insets.left - 2, insets.top - shrinkage - 1,
161                    width - insets.right - insets.left + 4,
162                    height - insets.bottom - insets.top + shrinkage * 2 + 2);
163     }
164 
165     @Override
paintBackground(final Graphics g)166     protected void paintBackground(final Graphics g) {
167         // we have already ensured that the background is painted to our liking
168         // by paintBackgroundSafely(), called from paintSafely().
169     }
170 
171     @Override
createCaret()172     protected Caret createCaret() {
173         return new AquaCaret();
174     }
175 
176     @Override
createHighlighter()177     protected Highlighter createHighlighter() {
178         return new AquaHighlighter();
179     }
180 
setPaintingDelegate(final JComponentPainter delegate)181     protected void setPaintingDelegate(final JComponentPainter delegate) {
182         this.delegate = delegate;
183     }
184 }
185