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

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

see #4429 - Right click menu "undo, cut, copy, paste, delete, select all" for each text component (originally based on patch by NooN)

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