source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/AbstractTextComponentValidator.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.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.Color;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.awt.event.FocusEvent;
8import java.awt.event.FocusListener;
9import java.beans.PropertyChangeEvent;
10import java.beans.PropertyChangeListener;
11import java.util.Objects;
12
13import javax.swing.BorderFactory;
14import javax.swing.UIManager;
15import javax.swing.border.Border;
16import javax.swing.event.DocumentEvent;
17import javax.swing.event.DocumentListener;
18import javax.swing.text.JTextComponent;
19
20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
22/**
23 * This is an abstract class for a validator on a text component.
24 *
25 * Subclasses implement {@link #validate()}. {@link #validate()} is invoked whenever
26 * <ul>
27 * <li>the content of the text component changes (the validator is a {@link DocumentListener})</li>
28 * <li>the text component loses focus (the validator is a {@link FocusListener})</li>
29 * <li>the text component is a {@link JosmTextField} and an {@link ActionEvent} is detected</li>
30 * </ul>
31 *
32 *
33 */
34public abstract class AbstractTextComponentValidator implements ActionListener, FocusListener, DocumentListener, PropertyChangeListener{
35 private static final Border ERROR_BORDER = BorderFactory.createLineBorder(Color.RED, 1);
36 private static final Color ERROR_BACKGROUND = new Color(255,224,224);
37
38 private JTextComponent tc;
39 /** remembers whether the content of the text component is currently valid or not; null means,
40 * we don't know yet
41 */
42 private Boolean valid = null;
43 // remember the message
44 private String msg;
45
46 protected void feedbackInvalid(String msg) {
47 if (valid == null || valid || !Objects.equals(msg, this.msg)) {
48 // only provide feedback if the validity has changed. This avoids
49 // unnecessary UI updates.
50 tc.setBorder(ERROR_BORDER);
51 tc.setBackground(ERROR_BACKGROUND);
52 tc.setToolTipText(msg);
53 valid = false;
54 this.msg = msg;
55 }
56 }
57
58 protected void feedbackDisabled() {
59 feedbackValid(null);
60 }
61
62 protected void feedbackValid(String msg) {
63 if (valid == null || !valid || !Objects.equals(msg, this.msg)) {
64 // only provide feedback if the validity has changed. This avoids
65 // unnecessary UI updates.
66 tc.setBorder(UIManager.getBorder("TextField.border"));
67 tc.setBackground(UIManager.getColor("TextField.background"));
68 tc.setToolTipText(msg == null ? "" : msg);
69 valid = true;
70 this.msg = msg;
71 }
72 }
73
74 /**
75 * Replies the decorated text component
76 *
77 * @return the decorated text component
78 */
79 public JTextComponent getComponent() {
80 return tc;
81 }
82
83 /**
84 * Creates the validator and weires it to the text component <code>tc</code>.
85 *
86 * @param tc the text component. Must not be null.
87 * @throws IllegalArgumentException if tc is null
88 */
89 public AbstractTextComponentValidator(JTextComponent tc) {
90 this(tc, true);
91 }
92
93 /**
94 * Alternative constructor that allows to turn off the actionListener.
95 * This can be useful if the enter key stroke needs to be forwarded to the default button in a dialog.
96 */
97 public AbstractTextComponentValidator(JTextComponent tc, boolean addActionListener) {
98 this(tc, true, true, addActionListener);
99 }
100
101 public AbstractTextComponentValidator(JTextComponent tc, boolean addFocusListener, boolean addDocumentListener, boolean addActionListener) {
102 CheckParameterUtil.ensureParameterNotNull(tc, "tc");
103 this.tc = tc;
104 if (addFocusListener) {
105 tc.addFocusListener(this);
106 }
107 if (addDocumentListener) {
108 tc.getDocument().addDocumentListener(this);
109 }
110 if (addActionListener) {
111 if (tc instanceof JosmTextField) {
112 JosmTextField tf = (JosmTextField)tc;
113 tf.addActionListener(this);
114 }
115 }
116 tc.addPropertyChangeListener("enabled", this);
117 }
118
119 /**
120 * Implement in subclasses to validate the content of the text component.
121 *
122 */
123 public abstract void validate();
124
125 /**
126 * Replies true if the current content of the decorated text component is valid;
127 * false otherwise
128 *
129 * @return true if the current content of the decorated text component is valid
130 */
131 public abstract boolean isValid();
132
133 /* -------------------------------------------------------------------------------- */
134 /* interface FocusListener */
135 /* -------------------------------------------------------------------------------- */
136 @Override
137 public void focusGained(FocusEvent arg0) {}
138
139 @Override
140 public void focusLost(FocusEvent arg0) {
141 validate();
142 }
143
144 /* -------------------------------------------------------------------------------- */
145 /* interface ActionListener */
146 /* -------------------------------------------------------------------------------- */
147 @Override
148 public void actionPerformed(ActionEvent arg0) {
149 validate();
150 }
151
152 /* -------------------------------------------------------------------------------- */
153 /* interface DocumentListener */
154 /* -------------------------------------------------------------------------------- */
155 @Override
156 public void changedUpdate(DocumentEvent arg0) {
157 validate();
158 }
159
160 @Override
161 public void insertUpdate(DocumentEvent arg0) {
162 validate();
163 }
164
165 @Override
166 public void removeUpdate(DocumentEvent arg0) {
167 validate();
168 }
169
170 /* -------------------------------------------------------------------------------- */
171 /* interface PropertyChangeListener */
172 /* -------------------------------------------------------------------------------- */
173 @Override
174 public void propertyChange(PropertyChangeEvent evt) {
175 if ("enabled".equals(evt.getPropertyName())) {
176 boolean enabled = (Boolean)evt.getNewValue();
177 if (enabled) {
178 validate();
179 } else {
180 feedbackDisabled();
181 }
182 }
183 }
184}
Note: See TracBrowser for help on using the repository browser.