2

Currently I am using the DocumentListener on every textfield, to live validate the users input, but I am thinking there must be a smarter way, since I am repeating my self so much.

Is there a smarter way of doing it?

nameJTextField.getDocument().addDocumentListener(new DocumentListener() {

        @Override
        public void insertUpdate(DocumentEvent e) {
            validateName(nameJTextField.getText());
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            validateName(nameJTextField.getText());
        }

        @Override
        public void changedUpdate(DocumentEvent e) {

        }

        private void validateName(String name) {
             if (name.matches("^[A-ZÆØÅa-zæøå0-9]{2,40}$")) {
                 errorNameJLabel.setText("");
             } else {
                 errorNameJLabel.setText("Min 2 and max 40 letters and numbers");
             }
        }
    });
mKorbel
  • 109,525
  • 20
  • 134
  • 319

4 Answers4

3

since I am repeating my self so much.

Create a generic DocumentListener that you can add to any text field That is:

  1. The validateName(...) method should be defined in the DocumentListener
  2. Don't use the text field to get the text. Instead you can get the text from the Document. The DocumentEvent has a reference to the Document.

Also, you would not do the validation in the changedUpdate(...) method. That method is only used for a change of attributes (font, color etc) in the text when using a JTextPane or JEditorPane.

Without knowing the details of your validation it is hard to give a more specific answer.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I have changed it, so that I have the validation method inside the DocumentListener. So I could make a more general class, maybe for each type of validation, and then create objects of the DocumentListener for example string validation? –  Oct 08 '14 at 19:42
  • Exactly, maybe you need to pass in parameters to make the class more generic. For example the maxim String length. You can also look at the `JFormattedTextField` which you might be able to use. Also a `DocumentFilter` is maybe even a better approach since it does validation before the Document is updated so you can prevent unwanted data from being entered into the Document. – camickr Oct 08 '14 at 19:49
2

Not in the built-in java. I do a lot with DocumentListeners and want to do exactly this, so I made my own class:

https://github.com/MattPutnam/Common/blob/master/src/common/swing/DocumentAdapter.java

Feel free to copy/paste.

MattPutnam
  • 2,927
  • 2
  • 17
  • 23
  • I am fairly new to Java, so my question might seem to be asking for the obvious, but how would I use it? –  Oct 08 '14 at 19:53
  • 1
    Add it as a DocumentListener like normal, then override the documentChanged method – MattPutnam Oct 08 '14 at 20:03
  • I decided to use your approach with the class you have designed. It is simple and fast. In the long run, I will try and implement @camickr 's solution. –  Oct 09 '14 at 10:38
1

Your approach is fine if you want to put the error message on another location.

I personally like to use the JFormattedTextField (or a pimped version of it at least).

  • I can create a perfect re-usable java.text.Format to format/parse input.
  • When the input is invalid, I change the background color so it is clear to the user which field is incorrect. Handy when you create a form where multiple fields can be incorrect at the same time.
  • You only get events (PropertyChangeEvents for the value property) when valid input is entered. Invalid input does not result in an event. Easy to e.g. enable a submit button on a form.

An example of this for numbers can be found in this question.

Community
  • 1
  • 1
Robin
  • 36,233
  • 5
  • 47
  • 99
1

Just crate an interface that extends DocumentListener and implements all DocumentListener methods:

@FunctionalInterface
public interface SimpleDocumentListener extends DocumentListener {
    void update(DocumentEvent e);

    @Override
    default void insertUpdate(DocumentEvent e) {
        update(e);
    }
    @Override
    default void removeUpdate(DocumentEvent e) {
        update(e);
    }
    @Override
    default void changedUpdate(DocumentEvent e) {
        update(e);
    }
}

and then:

jTextField.getDocument().addDocumentListener(new SimpleDocumentListener() {
    @Override
    public void update(DocumentEvent e) {
        // Your code here
    }
});

or you can even use lambda expression:

jTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
    // Your code here
});
Andrey Megvinov
  • 421
  • 5
  • 4