source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/JosmTextField.java@ 8291

Last change on this file since 8291 was 8291, checked in by Don-vip, 9 years ago

fix squid:RedundantThrowsDeclarationCheck + consistent Javadoc for exceptions

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.Color;
5import java.awt.FontMetrics;
6import java.awt.Graphics;
7import java.awt.Graphics2D;
8import java.awt.Insets;
9import java.awt.RenderingHints;
10import java.awt.event.FocusEvent;
11import java.awt.event.FocusListener;
12
13import javax.swing.JTextField;
14import javax.swing.text.Document;
15
16import org.openstreetmap.josm.Main;
17
18/**
19 * Subclass of {@link JTextField} that:<ul>
20 * <li>adds a "native" context menu (undo/redo/cut/copy/paste/select all)</li>
21 * <li>adds an optional "hint" displayed when no text has been entered</li>
22 * <li>disables the global advanced key press detector when focused</li>
23 * <li>implements a workaround to <a href="https://bugs.openjdk.java.net/browse/JDK-6322854">JDK bug 6322854</a></li>
24 * <br>This class must be used everywhere in core and plugins instead of {@code JTextField}.
25 * @since 5886
26 */
27public class JosmTextField extends JTextField implements FocusListener {
28
29 private String hint;
30
31 /**
32 * Constructs a new <code>JosmTextField</code> that uses the given text
33 * storage model and the given number of columns.
34 * This is the constructor through which the other constructors feed.
35 * If the document is <code>null</code>, a default model is created.
36 *
37 * @param doc the text storage to use; if this is <code>null</code>,
38 * a default will be provided by calling the
39 * <code>createDefaultModel</code> method
40 * @param text the initial string to display, or <code>null</code>
41 * @param columns the number of columns to use to calculate
42 * the preferred width &gt;= 0; if <code>columns</code>
43 * is set to zero, the preferred width will be whatever
44 * naturally results from the component implementation
45 * @throws IllegalArgumentException if <code>columns</code> &lt; 0
46 */
47 public JosmTextField(Document doc, String text, int columns) {
48 this(doc, text, columns, true);
49 }
50
51 /**
52 * Constructs a new <code>JosmTextField</code> that uses the given text
53 * storage model and the given number of columns.
54 * This is the constructor through which the other constructors feed.
55 * If the document is <code>null</code>, a default model is created.
56 *
57 * @param doc the text storage to use; if this is <code>null</code>,
58 * a default will be provided by calling the
59 * <code>createDefaultModel</code> method
60 * @param text the initial string to display, or <code>null</code>
61 * @param columns the number of columns to use to calculate
62 * the preferred width &gt;= 0; if <code>columns</code>
63 * is set to zero, the preferred width will be whatever
64 * naturally results from the component implementation
65 * @param undoRedo Enables or not Undo/Redo feature. Not recommended for table cell editors, unless each cell provides its own editor
66 * @throws IllegalArgumentException if <code>columns</code> &lt; 0
67 */
68 public JosmTextField(Document doc, String text, int columns, boolean undoRedo) {
69 super(doc, text, columns);
70 TextContextualPopupMenu.enableMenuFor(this, undoRedo);
71 // Fix minimum size when columns are specified
72 if (columns > 0) {
73 setMinimumSize(getPreferredSize());
74 }
75 addFocusListener(this);
76 // Workaround for Java bug 6322854
77 JosmPasswordField.workaroundJdkBug6322854(this);
78 }
79
80 /**
81 * Constructs a new <code>JosmTextField</code> initialized with the
82 * specified text and columns. A default model is created.
83 *
84 * @param text the text to be displayed, or <code>null</code>
85 * @param columns the number of columns to use to calculate
86 * the preferred width; if columns is set to zero, the
87 * preferred width will be whatever naturally results from
88 * the component implementation
89 */
90 public JosmTextField(String text, int columns) {
91 this(null, text, columns);
92 }
93
94 /**
95 * Constructs a new <code>JosmTextField</code> initialized with the
96 * specified text. A default model is created and the number of
97 * columns is 0.
98 *
99 * @param text the text to be displayed, or <code>null</code>
100 */
101 public JosmTextField(String text) {
102 this(null, text, 0);
103 }
104
105 /**
106 * Constructs a new empty <code>JosmTextField</code> with the specified
107 * number of columns.
108 * A default model is created and the initial string is set to
109 * <code>null</code>.
110 *
111 * @param columns the number of columns to use to calculate
112 * the preferred width; if columns is set to zero, the
113 * preferred width will be whatever naturally results from
114 * the component implementation
115 */
116 public JosmTextField(int columns) {
117 this(null, null, columns);
118 }
119
120 /**
121 * Constructs a new <code>JosmTextField</code>. A default model is created,
122 * the initial string is <code>null</code>,
123 * and the number of columns is set to 0.
124 */
125 public JosmTextField() {
126 this(null, null, 0);
127 }
128
129 /**
130 * Replies the hint displayed when no text has been entered.
131 * @return the hint
132 * @since 7505
133 */
134 public final String getHint() {
135 return hint;
136 }
137
138 /**
139 * Sets the hint to display when no text has been entered.
140 * @param hint the hint to set
141 * @since 7505
142 */
143 public final void setHint(String hint) {
144 this.hint = hint;
145 }
146
147 @Override
148 public void paint(Graphics g) {
149 super.paint(g);
150 if (hint != null && !hint.isEmpty() && getText().isEmpty() && !isFocusOwner()) {
151 // Taken from http://stackoverflow.com/a/24571681/2257172
152 int h = getHeight();
153 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
154 Insets ins = getInsets();
155 FontMetrics fm = g.getFontMetrics();
156 int c0 = getBackground().getRGB();
157 int c1 = getForeground().getRGB();
158 int m = 0xfefefefe;
159 int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1);
160 g.setColor(new Color(c2, true));
161 g.drawString(hint, ins.left, h / 2 + fm.getAscent() / 2 - 2);
162 }
163 }
164
165 @Override
166 public void focusGained(FocusEvent e) {
167 if (Main.map != null) {
168 Main.map.keyDetector.setEnabled(false);
169 }
170 repaint();
171 }
172
173 @Override
174 public void focusLost(FocusEvent e) {
175 if (Main.map != null) {
176 Main.map.keyDetector.setEnabled(true);
177 }
178 repaint();
179 }
180}
Note: See TracBrowser for help on using the repository browser.