How do I validate a TextField/JTextField to only accept valid IP addresses?

Brian Smith

[FAQ Manager Note]There are two answers submitted for this question. The second appears at the end of the page.

Here is a possible soltion. I wrote this last night using a generic bounded text field class I created some time back. This approach doesn't follow the model view approach but it gets the job done.

I create a IPAddressField class which contains multiple JTextField's which use the BoundedNumberDocument. The BoundedNumberDocument uses a DefaultComparator class to determine if the new string is within the bounds. Take it easy on me because this is my first time posting. I hope that some of this code is useful.

BoundedNumberDocument.java

import java.awt.Toolkit;
import java.util.Comparator;

import java.math.*;
import java.text.*;
import javax.swing.text.*;

public class BoundedNumberDocument extends PlainDocument {

  final public static int UNLIMITED_FRACTION_DIGITS = -1;

  protected Number minValue;
  protected Number maxValue;
  protected Comparator comparator;
  protected Number currentValue = null;

  protected int maxFracts = UNLIMITED_FRACTION_DIGITS;
   
  public BoundedNumberDocument(Number minValue,
      Number maxValue) {
    this(minValue,maxValue,new DefaultComparator());
  }

  public BoundedNumberDocument(Number minValue,
      Number maxValue, Comparator comparator) {
    
    if (minValue.getClass() == maxValue.getClass()) {
      this.minValue = minValue;
      this.maxValue = maxValue;
    } else {
      throw new IllegalArgumentException(
        "Bounded values must be of the same class");
    }
    
    setComparator(comparator);
  }

  public Number getValue() throws NumberFormatException,
      BadLocationException {
    return parseNumberFromString(getText(0,getLength()));
  }

  public void setComparator(Comparator comparator) {
    this.comparator = comparator;
  }
  public void setMinimumValue(Number minValue) {
    this.minValue = minValue;
  }
  public void setMaximumValue(Number maxValue) {
    this.maxValue = maxValue;
  }

  public int getMaximumFractionDigits() {
    return maxFracts;
  }
  public void setMaximumFractionDigits(int maxFracts) {
    this.maxFracts = maxFracts;
  }

  public void insertString(int offset, String str, 
    AttributeSet a) throws BadLocationException {

    String curText = getText(0,getLength());

    String preOffset   = curText.substring(0,offset);
    String postOffset  = curText.substring(offset,curText.length());
    String newStr      = preOffset + str + postOffset;

    if (verifyString(newStr)) 
      super.insertString(offset,str,a);
  }

  public void remove(int offset, int len) 
      throws BadLocationException {
    String curText = getText(0,getLength());

    String preOffset  = curText.substring(0,offset);
    String postOffset = curText.substring(len+offset,
      curText.length());
    String newStr     = preOffset + postOffset;
    
    if (newStr.length()!=0) {
      if (verifyString(newStr))
        super.remove(offset,len);

    } else { 
      // this is for erasing all the characters
      super.remove(offset,len);
      currentValue = null;
    }
  }
  
  protected boolean verifyString(String newStr) {
    if (newStr!=null && newStr.length()!=0) {
      try {
	if (!isMaximumFractionDigitsExceeded(newStr,
            getMaximumFractionDigits())) {
	  Number newValue = parseNumberFromString(newStr);
          if ( (comparator.compare(newValue,minValue) >= 0) 
            && (comparator.compare(newValue,maxValue) = 0)) {
	    currentValue = newValue;
	    return true;
	  }
	}
      } catch (NumberFormatException nfe) { }
    } 

    return false;
  }

  public boolean isMaximumFractionDigitsExceeded(String str, 
      int maxDigits) {
    if (str==null || str.length()==0 || 
        maxDigits==UNLIMITED_FRACTION_DIGITS)
      return false;
    else {

      int digits = 0;
      boolean decimalFound = false;

      for (int i=0; i  str.length(); i++) {
	if (!decimalFound) 
	  decimalFound = str.charAt(i) == '.';
	else {
	  if ( Character.isDigit(str.charAt(i))) 
	    digits++;
	}
      }
      return (digits > maxDigits);
    }
  }
 
  public Number parseNumberFromString(String newStr) 
      throws NumberFormatException {
    
    if (minValue instanceof Integer) {
      return Integer.valueOf(newStr);
    } else if (minValue instanceof Double) {
      return Double.valueOf(newStr);
    } else if (minValue instanceof Float) {
      return Float.valueOf(newStr);
    } else if (minValue instanceof BigDecimal) {
      return new BigDecimal(newStr);
    } else if (minValue instanceof BigInteger) {
      return new BigInteger(newStr);
    } else if (minValue instanceof Byte) {
      return Byte.valueOf(newStr);
    } else if (minValue instanceof Long) {
      return Long.valueOf(newStr);
    } else if (minValue instanceof Short) {
      return Short.valueOf(newStr);
    } else {
      throw new NumberFormatException("Unknown Number class");
    }
  }
}

IPAddressPanel.java

import java.awt.*;
import java.awt.geom.*;
import java.net.*;
import javax.swing.*;
import javax.swing.text.*;

public class IPAddressPanel extends JPanel {

  JTextField field0;
  JTextField field1;
  JTextField field2;
  JTextField field3;

  public IPAddressPanel() {
    field0 = createBoundedField(new Integer(1),new Integer(255));
    field1 = createBoundedField(new Integer(0),new Integer(255));
    field2 = createBoundedField(new Integer(0),new Integer(255));
    field3 = createBoundedField(new Integer(0),new Integer(255));
    
    initLayout();
  }

  public void initLayout() {
    Dimension d = new Dimension(2,field0.getPreferredSize().height);

    Component c;

    add(field0);
    c = new DotPanel(2,Color.black);
    c.setSize(d);
    add(c);
    
    add(field1);
    c = new DotPanel(2,Color.black);
    c.setSize(d);
    add(c);

    add(field2);
    c = new DotPanel(2,Color.black);
    c.setSize(d);
    add(c);

    add(field3);
  }

  public JTextField createBoundedField(Number n1, Number n2) {
    Document doc = new BoundedNumberDocument(n1,n2);
    JTextField field = new JTextField(doc,"",3);
    field.setHorizontalAlignment(JTextField.RIGHT);
    return field;
  }


  public InetAddress getAddress() throws UnknownHostException {
    String s = "";

    s+= field0.getText() + ".";
    s+= field1.getText() + ".";
    s+= field2.getText() + ".";
    s+= field3.getText();

    return InetAddress.getByName(s);
  }

  public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);

    field0.setEnabled(enabled);
    field1.setEnabled(enabled);
    field2.setEnabled(enabled);
    field3.setEnabled(enabled);
  }
  
  public static class DotPanel extends Canvas {
    
    int dotWidth;
    Color dotColor;

    public DotPanel(int dotWidth, Color dotColor) {
      this.dotWidth = dotWidth;
      this.dotColor = dotColor;
    }

    public void paint(Graphics g) {
      Graphics2D g2 = (Graphics2D) g;

      int width = getWidth();
      int height = getHeight();

      g2.setColor(dotColor);
      
      int xPos, yPos;

      xPos = (width / 2) - (dotWidth / 2);
      yPos = height - 1 - dotWidth;

      Ellipse2D dot = new Ellipse2D.Float(
        xPos,yPos,dotWidth,dotWidth);
      g2.fill(dot);
    }
  }
}

DefaultComparator.java

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Comparator;
import java.util.Date;

public class DefaultComparator implements Comparator {

  public static final int IGNORE_CASE = 0;
  public static final int CASE_SENSITIVE = 1;

  protected int caseSensitive = CASE_SENSITIVE;

  public int getCaseSensitive() {
    return caseSensitive;
  }

  public void setCaseSensitive(int caseSensitive) {
    if (caseSensitive == 0 || caseSensitive == 1) 
      this.caseSensitive = caseSensitive;
    else
      throw new IllegalArgumentException(
        "Unable to setCaseSensitive. Accepted values are "
         + "IGNORE_CASE or CASE_SENSITIVE");
  }
  
  public int compare(Object o1, Object o2) {
    if (o1 == null || o2 == null) {
      return getNullComparison(o1,o2);
    }
    if (o1 instanceof Boolean && o2 instanceof Boolean) {
      return compare((Boolean)o1,(Boolean)o2);
    } else if (o1 instanceof Number && o2 instanceof Number) {
      return compare((Number)o1,(Number)o2);
    } else if (o1 instanceof Date && o2 instanceof Date) {
      return compare((Date)o1,(Date)o2);
    } else { 
      return this.compare(o1.toString(), o2.toString());
    }
  }
  
  public int compare(String s1, String s2) {
    if (s1 == null || s2 == null ) {
      return getNullComparison(s1,s2);
    } else {
      int result;
      if (caseSensitive==IGNORE_CASE) 
        result = s1.compareToIgnoreCase(s2);
      else // Case Sensitive
        result = s1.compareTo(s2);

      if (result > 0) 
        return 1;
      else if (result  0) 
        return -1;
      else 
        return 0;
    }
  }
  
  public int compare(Number o1, Number o2) {
    if (o1 == null || o2 == null ) {
      return getNullComparison(o1,o2);
    }
    try {
      if (o1 instanceof BigDecimal) {
	return ((BigDecimal)o1).compareTo(o2); 
      } else if (o1 instanceof BigInteger) {
	return ((BigInteger)o1).compareTo(o2); 
      } else if (o1 instanceof Byte) {
	return ((Byte)o1).compareTo(o2); 
      } else if (o1 instanceof Double) {
	return ((Double)o1).compareTo(o2); 
      } else if (o1 instanceof Float) {
	return ((Float)o1).compareTo(o2); 
      } else if (o1 instanceof Integer) {
	return ((Integer)o1).compareTo(o2); 
      } else if (o1 instanceof Long) {
	return ((Long)o1).compareTo(o2); 
      } else if (o1 instanceof Short) {
	return ((Short)o1).compareTo(o2); 
      }
      
    } catch (ClassCastException cce) {} 
    
    double n1 = o1.doubleValue();
    double n2 = o2.doubleValue();
    if (n1  n2) {
      return -1;
    } else if (n1 > n2) {
      return 1;
    } else {
      return 0;
    }
  }
  
  public int compare(Date o1, Date o2) {
    if (o1 == null || o2 == null ) {
      return getNullComparison(o1,o2);
    } else {
      long n1 = o1.getTime();
      long n2 = o2.getTime();
      if (n1  n2) {
        return -1;
      } else if (n1 > n2) {
        return 1;
      } else {
        return 0;
      }
    }
  }

  public int compare(Boolean o1, Boolean o2) {
    if (o1 == null || o2 == null ) {
      return getNullComparison(o1,o2);
    } else {
      boolean b1 = o1.booleanValue();
      boolean b2 = o2.booleanValue();
      if (b1 == b2) {
        return 0;
      } else if (b1) {
        return 1;
      } else {
        return -1;
      }
    }
  }

  private int getNullComparison(Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return 0;
    } else if (o1 == null) {
      return -1;
    } else {
      return 1;
    }
  }
}

 

Ravi Shrivastava provides another answer

You can extend the javax.swing.text.PlainDocument and override the

void insertString( int offs, String str, javax.swing.text.AttributeSet a )

method (dont forget to call super.insertString(..) at the end of your code). You can check for every char that is entered here - to make sure that it forms the correct IP.

Comment and Contribute

 

 

 

 

 


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