Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Make bad users behave by using JFC documents -- revisited

A reader asks for clarity on JFC documents; Java Q&A expert Tony Sintes responds

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Q I just read your previous Java Q&A "Make Bad Users Behave by Using JFC Documents." Upon reading the insertString() method I was a little surprised to see that it checked only the offset at which characters were being inserted, not the length of the document. I did a quick cut and paste and compiled the code. Sure enough: If you place the insertion point anywhere but at the end of the text you can insert more than limit characters up until the insertion point reaches limit.

Also note that the main() method shown is missing an f.pack().

A OK, that's not exactly a question. However, I thought it important to point out this reader's observations. It's also important that I also address the observations.

Fixing the code

Let's look at the original code:

import javax.swing.text.*;
public class LimitDocument extends PlainDocument 
{
    private int limit;
    public LimitDocument(int limit) 
    {
        super();
      setLimit(limit); // store the limit 
    }
    public final int getLimit() 
    {
      return limit;
    }
    public void insertString(int offset, String s, AttributeSet attributeSet) 
        throws BadLocationException 
    {
        if(offset < limit) // if we haven't reached the limit, insert the string
      {
            super.insertString(offset,s,attributeSet);
      } // otherwise, just lose the string
    }
    public final void setLimit(int newValue) 
    {
        this.limit = newValue;
    }
}
public static void main(String args[]) 
{
    JFrame f = new JFrame("Limit Test");
    JTextField text = new JTextField();
    text.setDocument(new LimitDocument(10));
    f.getContentPane().add(BorderLayout.NORTH,text);
    f.show();
}


Sure enough: no f.pack()! And yes, I'm using the offset and not the string length.

First, let's fix the code:

import javax.swing.text.*;
public class LimitDocument extends PlainDocument 
{
    private int limit;
    public LimitDocument(int limit) 
    {
        super();
        setLimit(limit); // store the limit 
    }
    public final int getLimit() 
    {
        return limit;
    }
    public void insertString(int offset, String s, AttributeSet attributeSet) 
    throws BadLocationException 
    {
    int end = getEndPosition().getOffset() - 1; // get the position of where the string ends
    StringBuffer sb = new StringBuffer(getText(0,end)); 
    sb = sb.insert(offset,s);
    String new_s = sb.toString();
    if(new_s.length() >= limit)
    {
        new_s = new_s.substring(0,limit);
    }
    super.remove(0,end);
    super.insertString(0,new_s,attributeSet);
    }
    public final void setLimit(int newValue) 
    {
        this.limit = newValue;
    }
}
public static void main(String args[]) 
{
    JFrame f = new JFrame("Limit Test");
    JTextField text = new JTextField();
    text.setDocument(new LimitDocument(10));
    f.getContentPane().add(BorderLayout.NORTH,text);
    f.pack();
    f.show();
}


Wow, quite a change from the old code. So what am I doing?

Each time we try to enter new text, I grab the preexisting text and throw it in a StringBuffer. Using the offset, I then insert the new text into the old buffer. Finally, I grab the new string, truncate it if necessary, clear the old text, and write the new string.

As more requirements are added, the code becomes a bit more complex. The question in the previous column simply asked how to limit what is typed in, not what is pasted in. Pasting makes the answer much more complicated.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources