Swing’s InputVerifier tutorial: A super elegant way for validation

  

Let’s consider a common coding situation. Suppose you have a text field in your form that accepts an email address. Suppose you need to code such that if the email address typed by the user is not valid, then you shouldn’t let the focus out of this textfield. Where would you put such a code? In the focus lost of the email-text-field? In the focus gained for all other text-fields? I don’t know what’s the best way to do this in JavaScript but there’s a super-elegant way in Swing!

The need for InputVerifier

  To understand that let’s see the problems with the other common approach to solve this problem, using the focusLost() of the textfield

The problem with Focus-Snatching:

  One of the common approaches people take to solve such validation issue is to put the code in the focuslost() of a FocusListener attached to the textfield, and if the validation fails the requesting the focus back to the source component. This approach has several problems, but the main is this:
  ”The focus lost is called after the focus is moved to the new component. So if the new component itself has some other validation as a part of it’s focus lost, snatching the focus back to the first component, will trigger the focus lost of the new component too!, this might cause a sort of UI-lock when two components are trying to pull the focus to each other when both of them have invalid data”
din’t get the prose? Here’s the step by step description of the problem


When two things are wrong, does it matter which was wrong first?

  • Assume there are two fields “email1″ and “email2″. both of them cannot accept empty values
  • The user places the focus on field “email1″. No bombs here.
  • He dosen’t type anything and moves the foucs to field “email2″.
  • Now focus is given to field “email2″ and the focusLost() for “email1″ is called
  • The focusLost() method of “email1″ validates “email1″ and checks that it cannot be empty so it prompts a messsage to the user saying “email1 cannot be empty” and requests the focus back to field “email1″.
  • But by now, “email2″ already has the focus and when the focus is moved back to “email1″ the focus lost of “email2″ is called which again fires a validation
  • The user gets a message “email2 cannot be empty” and code requests the focus back to “email2″
  • Now, once again the focusLost() of email1 is called and this continues on and on.

  while there are ways to code to stop this from occuring, including putting this code in the focusgained(), of other components,and having flags to prevent this, why not use a better way provided in swing!

Enter InputVerifier:

  It’s great if you could fight and claim back the focus that belongs to you after letting it go to someone else, but wouldn’t it be better if you did not let it go in the first place?
  Coming back to swing, Wouldn’t it be cool, if I can have a method called whenever the user tries to move the focus out of my component and before the focus has actually entered the new component. Well, that’s what InputVerifier is for. To give a chance to the code to determine if the focus can move out of the current component to which it is attached to.

  The InputVerifier class has one main method “verify”, that get called before the focus is moved out of any component that it’s attached to. Let’s make it a little more clearer, here are the steps of invocation

  • The user enter’s a field(the focus is moved to that field)
  • The user does something and tries to moves the focus out of that field(either through mouse or keyboard)
  • before User’s wish is granted and the focus is moved to the new field, the “verify” method in your InputVerifier gets called.
  • Your InputVerifier’s verify() method returns “true” or “false” depending on whether the validation succedes or fails.
  • If the verify() methods returns true the user’s wish is granted and the foucs is moved to the new textfield that the user has requested focus to.
  • If the verify() method returns false, the user’s wish is not granted and the focus remains in the current field.

Please ..Anything but papayas

  Ever tasted a papaya? Some poeple like it. Some of my friends love it. It’s the fruit that I hate most! It’s so… soo.. yucky! So, as a dedication to my hatred, Let’s make a textfield accept anything, but the word “papaya”


The AnitPapayaVerifier:

   Here’s the code for the AnitPapayaVerifier class. See comments in the code for understanding

//class that starts the the anti-papaya movement
class AntiPapayaVerifier extends InputVerifier { 
 //Override the verify method to write the logic and then
 //return true or false
 @Override
 public boolean verify(JComponent input) {
	//Get the text in the text field
	JTextField couldBeEvilField =  (JTextField)input;
	String text = couldBeEvilField.getText().toLowerCase();
 
	//Check if the user has typed the p-word
	if(text.indexOf("papaya")!= -1){
		//show some arrogant message, and 
		//then return false
		//Bad guyz eat papya
		JOptionPane.showMessageDialog(null, "my JForm " +
				"dosen't grow papayas");
 
		//returning false ensures the focus, is not
		//moved out of the attached textfield
		return false;
	}
	else{
		//Nice guyz don't eat papaya
		//return true to ensure that the 
		//the focus is moved to where the 
		//user wishes to
 
		return true;
	}	
 }
}

Now all we need to do is attach it our textfield

JTextField noPapayaField = new JTextField("");
noPapayaField.setInputVerifier(new AntiPapayaVerifier());

  That’s it. Now your evil user dosen’t stand a chance against typing papaya in your text field and getting away with that.







3 Responses to 'Swing’s InputVerifier tutorial: A super elegant way for validation'

  1. Swing links of the week: July 6, 2008 : Pushing Pixels - July 7th, 2008 at 4:10 pm

    […] has a short tutorial on InputVerifier, including background on relevant scenarios and sample […]

  2. Thierry Lefort - July 8th, 2008 at 8:45 am

    Don’t forget to check the really great JGoodies Validation library :

    http://www.jgoodies.com/downloads/libraries.html

  3. Ready made Simple Custom TextField components » Java Swing - July 27th, 2008 at 8:18 am

    […] components in whatever way you like, looking at the code can give you an excellent insight on using InputVerifier and DocumentFilter if you have already not used them    Posted in basic, components, […]


Leave a Reply





Popular Articles

Blog Categories

Monthly Archives

Resources