Thursday, August 23, 2012

Auto-completion for email addresses in Swing


Recently we added the ability to send Electronic Receipts from our Point-of-Sale product at work.   One of the requirements was to enhance the user interface around the capture of email addresses.   We were just using a standard JTextField to capture the value.  Specifically, we were looking to make the entry of the email address easier by way of auto-completion, much like a lot of ajax-enabled fields in web applications.


I didn't want to re-invent the wheel and felt certain that I could something to get me started with the help of Google!   After a couple searches, I found a great starting point for the new code.  Samuel Sjöberg's auto-completion was extremely close to what I wanted.   Rather than auto-completing a person's name, I wanted to provide auto-completion for the part of the email address after the "@".    I also modified the code a bit to read the auto-completion candidates from a properties file.  This allows you to provide a properties file containing some of the most common email addresses.   Below is a copy of a sample properties file.

#################################################################################
# Commonly used Email Addresses                            
#                                                          
# This file will be read when the component starts up      
# and used to create an ArrayList of names to be used 
# for auto-completion of email addresses entered into 
# fields that assign the EmailAddressAutoCompletionDocument                      # to the field.  
#
# For better performance, put the most commonly used/encountered
# email addresses at the top of the list.
#
#################################################################################

 hotmail=hotmail.com
 gmail=gmail.com
 yahoo=yahoo.com
 verizon=verizon.net
 comcast=comcast.net
 aol=aol.com
 outlook=outlook.com
 mail=mail.com
 bigstring=bigstring.com
 shortmail=shortmail.com
 lycos=lycos.com
 excite=excite.com
 zoho=zohomail.com
 zzn=zzn.com

Below is the interesting part of the auto-completion of the email address field. First, I included a check for a max length of 255 to prevent too much data for our database columns. Next, we check for an "@" sign entered.  If no @ sign, add the text.  There is also a check to prevent a second @ from being added to the field.  Once we get past that, its time to call the completion service looking for a match on the email address. If a match is found, we add the rest of the string to the text box and select the part of the address that wasn't actually entered by the user.

 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        if (str == null || str.length() == 0) {
            return;
        }

        // check for max length first
        if (str == null || ((str.length() + getLength() > maxLength) && maxLength > 0))
   return;
        
        String text = getText(0, offs);        // Current text.
        int atSignIdx = text.indexOf(AT_SIGN); // 1st @ sign
        if (atSignIdx != -1 && offs > atSignIdx) {
         String fullText = text+str;
         //prevent entry of 2nd @ sign
         if (fullText.indexOf(AT_SIGN, atSignIdx+1) != -1) {
          return;
         }
         String address = fullText.substring(fullText.indexOf(AT_SIGN)+1);
         String completion = complete(address);
         int length = offs + str.length();
         if (completion != null && text.length() > 0) {
                super.insertString(offs, completion.substring(address.length()-1), a);
                documentOwner.select(length, getLength());
         } else {
          super.insertString(offs, str, a);
         }
        } else {
            super.insertString(offs, str, a);
        }
    }

I also added automatic validation of the full address by providing a regular expression to match against and then assigned a KeyListener to help implement the validation with color coding.   As the user types an email address, the foreground color is red and then when the email address is complete, either through auto-completion of the address portion or just typing, the foreground color is changed to green for a valid address.

Thanks to Samuel for posting his code.  My updated version can be found at GitHub.

Hope this helps!

No comments:

Post a Comment