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

Last change on this file since 13652 was 12630, checked in by Don-vip, 7 years ago

see #15182 - deprecate Main.map and Main.isDisplayingMapView(). Replacements: gui.MainApplication.getMap() / gui.MainApplication.isDisplayingMapView()

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