Index: trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java	(revision 16970)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java	(revision 16971)
@@ -4,5 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Color;
 import java.awt.Component;
 import java.awt.GridBagLayout;
@@ -19,7 +18,5 @@
 import javax.swing.JSeparator;
 import javax.swing.JTabbedPane;
-import javax.swing.UIManager;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
 
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -30,4 +27,5 @@
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.util.WindowGeometry;
+import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
@@ -40,5 +38,4 @@
  */
 public class LatLonDialog extends ExtendedDialog {
-    private static final Color BG_COLOR_ERROR = new Color(255, 224, 224);
 
     /**
@@ -48,5 +45,7 @@
     private JosmTextField tfLatLon, tfEastNorth;
     private LatLon latLonCoordinates;
+    private LatLonValidator latLonValidator;
     private EastNorth eastNorthCoordinates;
+    private EastNorthValidator eastNorthValidator;
 
     protected JPanel buildLatLon() {
@@ -108,7 +107,5 @@
 
         // parse and verify input on the fly
-        //
-        LatLonInputVerifier inputVerifier = new LatLonInputVerifier();
-        tfLatLon.getDocument().addDocumentListener(inputVerifier);
+        latLonValidator = new LatLonValidator(tfLatLon);
 
         // select the text in the field on focus
@@ -136,6 +133,5 @@
         pnl.add(GBC.glue(1, 1), GBC.eol().fill().weight(1.0, 1.0));
 
-        EastNorthInputVerifier inputVerifier = new EastNorthInputVerifier();
-        tfEastNorth.getDocument().addDocumentListener(inputVerifier);
+        eastNorthValidator = new EastNorthValidator(tfEastNorth);
 
         TextFieldFocusHandler focusHandler = new TextFieldFocusHandler();
@@ -151,6 +147,6 @@
         tabs.getModel().addChangeListener(e -> {
             switch (tabs.getModel().getSelectedIndex()) {
-                case 0: parseLatLonUserInput(); break;
-                case 1: parseEastNorthUserInput(); break;
+                case 0: latLonValidator.validate(); break;
+                case 1: eastNorthValidator.validate(); break;
                 default: throw new AssertionError();
             }
@@ -233,54 +229,66 @@
     }
 
-    protected void setErrorFeedback(JosmTextField tf, String message) {
-        tf.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
-        tf.setToolTipText(message);
-        tf.setBackground(BG_COLOR_ERROR);
-    }
-
-    protected void clearErrorFeedback(JosmTextField tf, String message) {
-        tf.setBorder(UIManager.getBorder("TextField.border"));
-        tf.setToolTipText(message);
-        tf.setBackground(UIManager.getColor("TextField.background"));
-    }
-
-    protected void parseLatLonUserInput() {
-        LatLon latLon;
-        try {
-            latLon = LatLonParser.parse(tfLatLon.getText());
-            if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) {
+    private class LatLonValidator extends AbstractTextComponentValidator {
+        LatLonValidator(JTextComponent tc) {
+            super(tc);
+        }
+
+        @Override
+        public void validate() {
+            LatLon latLon;
+            try {
+                latLon = LatLonParser.parse(tfLatLon.getText());
+                if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) {
+                    latLon = null;
+                }
+            } catch (IllegalArgumentException e) {
+                Logging.trace(e);
                 latLon = null;
             }
-        } catch (IllegalArgumentException e) {
-            Logging.trace(e);
-            latLon = null;
-        }
-        if (latLon == null) {
-            setErrorFeedback(tfLatLon, tr("Please enter a GPS coordinates"));
-            latLonCoordinates = null;
-            setOkEnabled(false);
-        } else {
-            clearErrorFeedback(tfLatLon, tr("Please enter a GPS coordinates"));
-            latLonCoordinates = latLon;
-            setOkEnabled(true);
-        }
-    }
-
-    protected void parseEastNorthUserInput() {
-        EastNorth en;
-        try {
-            en = parseEastNorth(tfEastNorth.getText());
-        } catch (IllegalArgumentException e) {
-            Logging.trace(e);
-            en = null;
-        }
-        if (en == null) {
-            setErrorFeedback(tfEastNorth, tr("Please enter a Easting and Northing"));
-            latLonCoordinates = null;
-            setOkEnabled(false);
-        } else {
-            clearErrorFeedback(tfEastNorth, tr("Please enter a Easting and Northing"));
-            eastNorthCoordinates = en;
-            setOkEnabled(true);
+            if (latLon == null) {
+                feedbackInvalid(tr("Please enter a GPS coordinates"));
+                latLonCoordinates = null;
+                setOkEnabled(false);
+            } else {
+                feedbackValid(null);
+                latLonCoordinates = latLon;
+                setOkEnabled(true);
+            }
+        }
+
+        @Override
+        public boolean isValid() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private class EastNorthValidator extends AbstractTextComponentValidator {
+        EastNorthValidator(JTextComponent tc) {
+            super(tc);
+        }
+
+        @Override
+        public void validate() {
+            EastNorth en;
+            try {
+                en = parseEastNorth(tfEastNorth.getText());
+            } catch (IllegalArgumentException e) {
+                Logging.trace(e);
+                en = null;
+            }
+            if (en == null) {
+                feedbackInvalid(tr("Please enter a Easting and Northing"));
+                latLonCoordinates = null;
+                setOkEnabled(false);
+            } else {
+                feedbackValid(null);
+                eastNorthCoordinates = en;
+                setOkEnabled(true);
+            }
+        }
+
+        @Override
+        public boolean isValid() {
+            throw new UnsupportedOperationException();
         }
     }
@@ -306,38 +314,4 @@
     }
 
-    class LatLonInputVerifier implements DocumentListener {
-        @Override
-        public void changedUpdate(DocumentEvent e) {
-            parseLatLonUserInput();
-        }
-
-        @Override
-        public void insertUpdate(DocumentEvent e) {
-            parseLatLonUserInput();
-        }
-
-        @Override
-        public void removeUpdate(DocumentEvent e) {
-            parseLatLonUserInput();
-        }
-    }
-
-    class EastNorthInputVerifier implements DocumentListener {
-        @Override
-        public void changedUpdate(DocumentEvent e) {
-            parseEastNorthUserInput();
-        }
-
-        @Override
-        public void insertUpdate(DocumentEvent e) {
-            parseEastNorthUserInput();
-        }
-
-        @Override
-        public void removeUpdate(DocumentEvent e) {
-            parseEastNorthUserInput();
-        }
-    }
-
     static class TextFieldFocusHandler implements FocusListener {
         @Override
