Demystifying JFormattedTextField: A Step by Step tutorial

  

   JFormattedTextField is a very useful Swing component, that let’s your users see data in a format suitable for them, while letting you read or write from it in a way that that suitable for your code. Let’s make sure that you clearly understand everything related to it.

   Ok, let’s start. here’s the first thing you need to know about the JFormattedTextField:

What you see is not what’s inside:

   Consider the TextField component. It has only one value associated with its model. The “text”. This is the same value that the user sees, and the value that you set or get using your code. This is OK for simple text fields, but what about cases where it’s convenient for you to manipulate the data in different way than what you need to show to the user. Not sure when such a case would arise? Consider this. Say you have a percentageTextField, in which the user can type his value in percentage like “30%” , “40%” etc. It’s very intuitive and readable for the user to see the string with “%” appeneded in the end (like “30%” instead of “30″), but wouldn’t you find it more easier to manipulate this value as integers 30 and 40, instead of Strings “30%” and “40%”?
   To solve this problem, JFormattedTextField introduces the notion of “value” in addition to the concept of “text”. The “text” part is what is showed to the user and the “value” part is what is easy for the code to manipulate. Got it? If you did, it should be obvious that the “text” part can only be a string(as it’s the one that displayed to the user) and the “value” part can be any object
   Easy So far? The rest should be even easier. read on.

Formatter: The one who converts between the “text” and “value”

   So, as far, you have understood that the JFormattedTextField has both “text” and “value” associated with it. But there’s one small catch left yet. When the “text” is updated so should the “value” and vice verca. For eg., when the user types “30%” the value should have an integer value of 30. and then when the user changes the text to “40%” the value should get automatically updated to integer 40. Right? And viceverca is true too, when through code you set the value to “50″ the user should see “50%” in the UI. When does this conversion happen? Before that let’s see who converts these.
   The “JFormattedTextField” has an inner class “AbstractFormatter”, instances of which are responsible for this conversion. So what methods should this class have for the subclasses to override? Obviously, one method that converts and returns the “value” object from the “text” string, and another method that converts and returns the “text” string from the “value” object. So here are the two methods that you need to override when you are making your own Formatter. Ofcourse, I need not tell now, which method should do what.

  • public String valueToString(Object value) ;
  • public Object stringToValue(String text) ;

When does Synchronization between text and value happen?

   When the user types some text it should get converted to the appropriate value object and when you modify the value object through code, it should somehow get converted back to the “text” string that the user sees. When does this conversion happen? When modifying the value object the conversion to text happens immediately, but when ther user types text, it usually happens in one of the following ways

  • When the user presses enter after typing in some value
  • When the user goes out of the text field (during focus lost)

Note, however this is not always true. The Formatter may decide to do it in other times too, like for example , for each character press by the user. You can also programatically call the commitEdit() method in the JFormattedTextField to convert the text to value at once.

An Example:

   Let’s write the percentage text field that we were discussing above. As discussed above it displays values like “30%”, “40%” etc., while the in the code we use integers like 30, 40 etc. First Let’s write an AbstractFormatter subclass
 &nsbp;&nsbp;Here’s the class. It implements the methods “stringToValue” and “valueToString”. The implementation is pretty simple, follow the code comments, if you have any doubts

Step 1: Create the PertentageFormatter class

class PercentageFormatter extends AbstractFormatter{
  //Convert the string to Integer	
  @Override
  public Integer stringToValue(String text) throws ParseException {
    if(text == null){
      return Integer.valueOf(0);
    }
    //If the text ends with "%" remove it
    if(text.endsWith("%")){
      text = text.substring(0, text.length()-1);
    }
		//If the text is empty, assume it's 0
    if("".equals(text)){
      return Integer.valueOf(0);
    }
    else{
 
      try {
        //Try to parse the remaining string, if there's an exception use 0
        return Integer.valueOf(text);
      } catch (NumberFormatException e) {
        //Leave it. If there's any exception return 0 below
      }
 
    }
 
    return Integer.valueOf(0);
  }
 
  @Override
  public String valueToString(Object value) throws ParseException {
     //If the value is an integer, append "%" to it
     // and return the value to display.
    if(value == null || (! (value instanceof Integer)))
    {
         return "0%";
    }
    Integer val = (Integer)value;
    return val.intValue() + "%";
  }
 
}

Step2: Create the JFormattedTextField using the “PercentageFormatter” formatter

This is really simple. You pass an instance of the “PercentageFormatter” sub class to the JFormattedTextField.

JFormattedTextField field = 
  new JFormattedTextField(new PercentageFormatter());

tha’s it. Now add this field to your form, type some value like “40%” and use the getValue() to get the value as an Integer Object 40.







4 Responses to 'Demystifying JFormattedTextField: A Step by Step tutorial'

  1. John - July 30th, 2008 at 2:30 pm

    crisp and clear. Would have been better if you have explained the MaskFormatter too.

  2. Swing links of the week: August 3 : Pushing Pixels - August 4th, 2008 at 4:51 pm

    […] continues its series of tutorials on Swing text components, and this time they write an introduction to working with JFormattedTextField […]

  3. bitguru - August 4th, 2008 at 11:01 pm

    I feel compelled to point out that the easy way to get a JFormattedTextField for percents is to do:

    new JFormattedTextField(java.text.NumberFormat.getPercentInstance())

    This way there’s no need to write your own formatter, but note that if you type 33% into the field and call getValue() it will return 0.33, not 33.0 (that’s how I generally prefer to deal with my percentage values anyway).

  4. Demystifying JFormattedTextField: A Step by Step tutorial | 2-cents - August 8th, 2008 at 8:38 pm

    […] Demystifying JFormattedTextField: A Step by Step tutorial » Java Swing JFormattedTextField is a very useful Swing component, that let’s your users see data in a format suitable for them, while letting you read or write from it in a way that that suitable for your code. Let’s make sure that you clearly understand everything related to it. […]


Leave a Reply





Popular Articles

Blog Categories

Monthly Archives

Resources