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

Last change on this file since 3128 was 3083, checked in by bastiK, 14 years ago

added svn:eol-style=native to source files

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