Link to home
Start Free TrialLog in
Avatar of P1ST0LPETE
P1ST0LPETEFlag for United States of America

asked on

Java Input Validation

Hi all,
I'm pretty new to Java.  What is a quick and dirty way to do input validation in Java?  I need to prevent everything but numbers from being entered into textfields.  Thanks.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

You need a document filter or a custom document on the field. See the following related:

http://forum.java.sun.com/thread.jspa?threadID=780933&messageID=4442038
customize document!

try this,

      class CustomTextField extends JTextField{
            private static final long serialVersionUID = 1L;

            CustomTextField( int column, int limit ){
                  super( column ) ;
                  customize() ;
            }
            
            private void customize(){
                  this.setDocument( new PlainDocument(){
                        
                    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
                        try{
                              Integer.parseInt( str ) ;
                            super.insertString(offs, str, a);
                        }catch( NumberFormatException nfe ){
                            //throw new BadLocationException("Insertion exceeds max size of document", offs);
                        }
                    }
                  }) ;
                  
                  this.addFocusListener( new FocusAdapter(){
                        public void focusGained( FocusEvent e ){
                              CustomTextField.this.selectAll() ;
                        }
                  }) ;
            }
      }
      
Customize as little as possible - the document, not the text field ;-)
>>Customize as little as possible - the document, not the text field ;-)

I think, customizing textfield makes it re-usable and reduce number of lines of code!
No - it increases the number of lines of code and make it *less* reusable since the document can otherwise be used in other JTextComponent ;-)
>>since the document can otherwise be used in other JTextComponent ;-)
>>

Generally, to get the numeric data, just the JTextField is enough... other text components may not be appropriate or used in very very very rare cases! If you encounter that situation, just separate the document from anonymous inner class to a concrete class and just set them in the customized text component as I have done in the previous post!

>>No - it increases the number of lines of code and make it *less* reusable

no it doesn't, see my comments above!
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of P1ST0LPETE

ASKER

Being a newb, I didn't understand all the PlainDocument, AttributeSet, and BadLocation stuff, or even how to implement it into my code.  Anyway, I decided to use Regex to achieve the same result, but am getting hung up here as well.  Attached is an example of what I have so far.

The attached code is working when I only enter numbers, or when I only enter unwanted characters (i.e. anything but numbers).  However, when I enter a combination of both numbers and unwanted characters such as "555hh", then I get the following errors:

at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
private void PercentageWasGas()
   {
	   //Obtain text input, and change to double
	   String inputTravelMoney = txtTravelMoney.getText();
	   String inputGasMoney = txtGasMoney.getText();
	   if(Regex(inputGasMoney) && Regex(inputTravelMoney))
	   {
		   double TravelMoney = Double.valueOf(inputTravelMoney.trim()).doubleValue();
		   double GasMoney = Double.valueOf(inputGasMoney.trim()).doubleValue();
		   
		   //Based on the equation x/100 = Gas_Money/TotalTrip_Money, and then solving for x:
		   //PSoG = Percentage Spent on Gas.
		   double PSoG = (GasMoney * 100) / TravelMoney;
		   NumberFormat formatter = new DecimalFormat("0.00");
		   String strPSoG = formatter.format(PSoG);
		   lbPSoG.setText(strPSoG + "%");
	   }
	   else
	   {
		   lbPSoG.setText("Improper Data Entered.");
	   }
   }
   
   public boolean Regex(String input)
   {
	   String regex = "[0-9]";
	   Pattern p = Pattern.compile(regex);
	   Matcher m = p.matcher(input);
	   boolean result = m.find();
	   return result;
   }

Open in new window

Ok, didn't see your last post CEHJ, trying it now.
Your 'Regex' method (Java methods should begin lower case btw) should be m.matches not m.find, but you could have simplified using the regex methods of String itself:
public boolean regex(String input)
{
           return input.matches("[0-9]+");
}

Open in new window

Thanks for the help.
:-)
I would suggest to avoid regex as much as possible b'cos that is much slower...

in this case, the method I have followed is 3 times faster than regex... Also the regex is a CPU consuming process and which may take much more time in the peak load! This is based on my experience!