September 23, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Manipulating User Data at the Model Layer in Swing

  • June 1, 2005
  • By Vlad Kofman
  • Send Email »
  • More Articles »

Most of the graphical user interfaces (GUIs) developed with the Java Swing toolkit accept user input and validate it. Swing is built on the principle of the separable model architecture, a version of Model-View-Controller design where all of the graphical components have corresponding data model objects. The user's data has to be stored in the model layer before it can be accessed or presented in the view layer. It can be also manipulated, changed, or checked before it is put in the model objects. Please see my other article, "Creating Interactive GUIs with Swing's MVC Architecture," for more information about separable model architecture.

In this article, I will show how to use Java Swing data models for components that accept user input, to automatically manipulate it before it is put in the model. In particular, I will cover the limitation of its input to predefined subsets of characters, memory management for large data sets, and filtering of the input data. All of the principles are based on the object inheritance and can be applied to any component that follows the MVC paradigm.

Note that even though Swing is inheritably not thread safe, some atomic operations have been added to it. An atomic operation or code section will be finished by the current thread and not interrupted by other threads. Assignment to variables smaller than 32 bits is an atomic operation, which excludes variables of types double and long (both are 64 bits). As a result, atomic operations do not need synchronization. Because any enterprise-scale Swing program should be and often is multithreaded, data updates of the GUI are likely to be done by multiple threads. Therefore, Swing developers have added atomic components that have synchronized assignment operation already built in. But, I will assume a single thread data assignment in this article.

Limiting User Input

One of the most common problems with GUIs is limiting or filtering user entered data. For instance, consider a text field that accepts only numeric values, or a password field that accepts character values only. To solve this problem, you need to understand the data flow in the Swing framework. In general, when data comes in to the model layer from any source such as database, file, or I/O stream, it is put in the model via a public API of that object. As soon as model object's content is changed, it fires a notification event and the corresponding View object(s) update their presentation after receiving the event.

Therefore, there is a point where the public API of any model object is called to update the model. To limit character sets or establish an allowable subset, several steps need to be taken. First, you need to pre-empt the data at the place where it is entered (the call to the API). Second, you need to manipulate it before it is put in the model. For example, a JTextField uses a Document model that has a public insertString(int offset, String str, AttributeSet a) method. Please see the JDK API doc for more information on this method.

If you want to manipulate the character set that is coming into the JTextField or filter it, you can subclass the Document object or any of its sub-classes and overwrite the insertString method. For example, create a new "Document" type model and set it to a JTextField:

// PlainDocument extends Document
public class NumberDocument extends PlainDocument
{
...
public void insertString(int offset, String stringToInsert,
                         AttributeSet attributes)
                        throws BadLocationException {
   //This rejects the entire insertion if it is not an integer
   //between the min and max values inclusive.

   try {
      Integer.parseInt(stringToInsert);
   }
   catch (NumberFormatException e) {
      return;    //or beep here
   }

      if ( ((getLength()+stringToInsert.length()) >= mMinInteger)
          && ((getLength()+stringToInsert.length()) <= mMaxInteger)) {
      super.insertString(offset, stringToInsert, attributes);
   }
}
...
JTextField tf = new JTextField();
tf.setDocument(new NumberDocument(1, 10));

See the included source code for a complete listing.

This text field will essentially not let the user to type in anything but numeric characters into it. Additional checks can be done as well, such as the range, value, or sign of the number. The model can even be made to beep on incorrect data entry as is the case of the user pressing a non-numeric key on keyboard. Overwriting the insert API can be certainly extended to other components as well.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel