source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/AbstractTextComponentValidator.java@ 13146

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

sonar - squid:S1066 - Collapsible "if" statements should be merged

  • Property svn:eol-style set to native
File size: 6.7 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;
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 unnecessary UI updates.
49 tc.setBorder(ERROR_BORDER);
50 tc.setBackground(ERROR_BACKGROUND);
51 tc.setToolTipText(msg);
52 valid = Boolean.FALSE;
53 this.msg = msg;
54 }
55 }
56
57 protected void feedbackDisabled() {
58 feedbackValid(null);
59 }
60
61 protected void feedbackValid(String msg) {
62 if (valid == null || !valid || !Objects.equals(msg, this.msg)) {
63 // only provide feedback if the validity has changed. This avoids unnecessary UI updates.
64 tc.setBorder(UIManager.getBorder("TextField.border"));
65 tc.setBackground(UIManager.getColor("TextField.background"));
66 tc.setToolTipText(msg == null ? "" : msg);
67 valid = Boolean.TRUE;
68 this.msg = msg;
69 }
70 }
71
72 /**
73 * Replies the decorated text component
74 *
75 * @return the decorated text component
76 */
77 public JTextComponent getComponent() {
78 return tc;
79 }
80
81 /**
82 * Creates the validator and weires it to the text component <code>tc</code>.
83 *
84 * @param tc the text component. Must not be null.
85 * @throws IllegalArgumentException if tc is null
86 */
87 public AbstractTextComponentValidator(JTextComponent tc) {
88 this(tc, true);
89 }
90
91 /**
92 * Alternative constructor that allows to turn off the actionListener.
93 * This can be useful if the enter key stroke needs to be forwarded to the default button in a dialog.
94 * @param tc text component
95 * @param addActionListener {@code true} to add the action listener
96 */
97 public AbstractTextComponentValidator(JTextComponent tc, boolean addActionListener) {
98 this(tc, true, true, addActionListener);
99 }
100
101 /**
102 * Constructs a new {@code AbstractTextComponentValidator}.
103 * @param tc text component
104 * @param addFocusListener {@code true} to add the focus listener
105 * @param addDocumentListener {@code true} to add the document listener
106 * @param addActionListener {@code true} to add the action listener
107 */
108 public AbstractTextComponentValidator(JTextComponent tc, boolean addFocusListener, boolean addDocumentListener, boolean addActionListener) {
109 CheckParameterUtil.ensureParameterNotNull(tc, "tc");
110 this.tc = tc;
111 if (addFocusListener) {
112 tc.addFocusListener(this);
113 }
114 if (addDocumentListener) {
115 tc.getDocument().addDocumentListener(this);
116 }
117 if (addActionListener && tc instanceof JosmTextField) {
118 ((JosmTextField) tc).addActionListener(this);
119 }
120 tc.addPropertyChangeListener("enabled", this);
121 }
122
123 /**
124 * Implement in subclasses to validate the content of the text component.
125 *
126 */
127 public abstract void validate();
128
129 /**
130 * Replies true if the current content of the decorated text component is valid;
131 * false otherwise
132 *
133 * @return true if the current content of the decorated text component is valid
134 */
135 public abstract boolean isValid();
136
137 /* -------------------------------------------------------------------------------- */
138 /* interface FocusListener */
139 /* -------------------------------------------------------------------------------- */
140 @Override
141 public void focusGained(FocusEvent arg0) {}
142
143 @Override
144 public void focusLost(FocusEvent arg0) {
145 validate();
146 }
147
148 /* -------------------------------------------------------------------------------- */
149 /* interface ActionListener */
150 /* -------------------------------------------------------------------------------- */
151 @Override
152 public void actionPerformed(ActionEvent arg0) {
153 validate();
154 }
155
156 /* -------------------------------------------------------------------------------- */
157 /* interface DocumentListener */
158 /* -------------------------------------------------------------------------------- */
159 @Override
160 public void changedUpdate(DocumentEvent arg0) {
161 validate();
162 }
163
164 @Override
165 public void insertUpdate(DocumentEvent arg0) {
166 validate();
167 }
168
169 @Override
170 public void removeUpdate(DocumentEvent arg0) {
171 validate();
172 }
173
174 /* -------------------------------------------------------------------------------- */
175 /* interface PropertyChangeListener */
176 /* -------------------------------------------------------------------------------- */
177 @Override
178 public void propertyChange(PropertyChangeEvent evt) {
179 if ("enabled".equals(evt.getPropertyName())) {
180 boolean enabled = (Boolean) evt.getNewValue();
181 if (enabled) {
182 validate();
183 } else {
184 feedbackDisabled();
185 }
186 }
187 }
188}
Note: See TracBrowser for help on using the repository browser.