NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
This is a followup to the AbstractValidator we created in
Building a Swing Validation Package with InputVerifier
that shows some examples of validators I built ontop of AbstractValidator. The main validator I want to show is a very powerful one which validates credit card numbers, even down to checking for mistyped digits. But lets start with something simpler just to show how easy it is to build a validator ontop of AbstractValidator.
The NotEmptyValidator
NotEmptyValidator is a very simple validator. All it does is make sure that the
user entered something in the text field. It shows just how easy it is to write
and use actual validators using the validation package we wrote earlier. Here is
the short and simple code for NotEmptyValidator:
package org.javalobby.validation;
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.JDialog;
/**
* A class for performing basic validation on text fields. All it does is make
* sure that they are not null.
*
* @author Michael Urban
*/
publicclass NotEmptyValidator extends AbstractValidator {
public NotEmptyValidator(JDialog parent, JTextField c, String message) {
super(parent, c, message);
}
protectedboolean validationCriteria(JComponent c) {
if (((JTextField)c).getText().equals(""))
returnfalse;
returntrue;
}
}
That's all there is too it. To use the validator on a text field in your
application, all you have to to is something like this:
JTextField textField = new JTextField();
textField.setInputVerifier(new NotEmptyValidator(parent, textField, "Field cannot be null."));
Now lets takes a look at a more complex, but very powerful and useful
validator.
The CreditCardValidator
CreditCardValidator does pre-validation of credit card numbers before actually
sending them off for authrorization. It is a very powerful validator that uses
the Luhn algorithm to catch mistakes in credit card number input, all the way
down to the user simply mistyping a single digit in the card number. As you can
see, validation criteria for a validator package can be arbitrarily complex.
Let's look at the source code for CreditCardValidator:
package org.javalobby.validation;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JTextField;
import java.util.regex.*;
/**
* A class for performing pre-validation on credit cards.
*
* @author Michael Urban
*/
publicclass CreditCardValidator extends AbstractValidator {
publicstaticfinalint MASTERCARD = 0, VISA = 1;
publicstaticfinalint AMEX = 2, DISCOVER = 3, DINERS = 4;
private JDialog parent;
private Object form;
privatestaticfinal String[] messages = {
"Not a valid number for MasterCard.",
"Not a valid number for Visa.",
"Not a valid number for American Express.",
"Not a valid number for Discover.",
"Not a valid number for Diner's Club"
};
public CreditCardValidator(JDialog parent, Object form, JComponent c,
String message)
{
super(parent, c, message);
this.parent = parent;
this.form = form;
}
protectedboolean validationCriteria(JComponent c) {
String number = ((JTextField)c).getText();
if (number.equals("")) {
setMessage("Field cannnot be blank.");
returnfalse;
}
Matcher m = Pattern.compile("[^\\d\\s.-]").matcher(number);
if (m.find()) {
setMessage("Credit card number can only contain numbers, spaces, \"-\", and \".\"");
returnfalse;
}
int type = ((CreditCardValidation)form).validateCreditCardType();
setMessage(messages[type]);
Matcher matcher = Pattern.compile("[\\s.-]").matcher(number);
number = matcher.replaceAll("");
return validate(number, type);
}
// Check that cards start with proper digits for
// selected card type and are also the right length.
privateboolean validate(String number, int type) {
switch(type) {
case MASTERCARD:
if (number.length() != 16 ||
Integer.parseInt(number.substring(0, 2)) < 51 ||
Integer.parseInt(number.substring(0, 2)) > 55)
{
returnfalse;
}
break;
case VISA:
if ((number.length() != 13 && number.length() != 16) ||
Integer.parseInt(number.substring(0, 1)) != 4)
{
returnfalse;
}
break;
case AMEX:
if (number.length() != 15 ||
(Integer.parseInt(number.substring(0, 2)) != 34 &&
Integer.parseInt(number.substring(0, 2)) != 37))
{
returnfalse;
}
break;
case DISCOVER:
if (number.length() != 16 ||
Integer.parseInt(number.substring(0, 5)) != 6011)
{
returnfalse;
}
break;
case DINERS:
if (number.length() != 14 ||
((Integer.parseInt(number.substring(0, 2)) != 36 &&
Integer.parseInt(number.substring(0, 2)) != 38) &&
Integer.parseInt(number.substring(0, 3)) < 300 ||
Integer.parseInt(number.substring(0, 3)) > 305))
{
returnfalse;
}
break;
}
return luhnValidate(number);
}
// The Luhn algorithm is basically a CRC type
// system for checking the validity of an entry.
// All major credit cards use numbers that will
// pass the Luhn check. Also, all of them are based
// on MOD 10.
privateboolean luhnValidate(String numberString) {
char[] charArray = numberString.toCharArray();
int[] number = newint[charArray.length];
int total = 0;
for (int i=0; i < charArray.length; i++) {
number[i] = Character.getNumericValue(charArray[i]);
}
for (int i = number.length-2; i > -1; i-=2) {
number[i] *= 2;
if (number[i] > 9)
number[i] -= 9;
}
for (int i=0; i < number.length; i++)
total += number[i];
if (total % 10 != 0)
returnfalse;
returntrue;
}
}
Because we need to check the credit card type, notice that this validator
requires an additional interface so that our validator can retrieve the credit
card type from the form. That interface is CreditCardValidation:
package org.javalobby.validation;
publicinterface CreditCardValidation {
int validateCreditCardType();
}
Notice that in this validator, we provide context sensitive pop help
messages and check for three different possible problems: Whether the the
user left the credit card field blank; whether the user entered illegal
characters in the credit card field; and whether or not the credit card type
could be a valid credit card number for the card type in question.
CreditCardValidator is mostly just algorithm programming, so I am not going
to go into details about how it works. But suffice it to say, it shows that
the validation criteria we implement can be arbitrarily complex, and that
in CreditCardValidator, all we had to focus on was writing the logic for
our validator. We didn't haven't to worry about presenting validation results
to the user at all. AbstractValidator we wrote earlier takes care of
all those details for us.
Well nice but why U dont use strategy pattern for validation algorithms? If it depends on card type it is the from my point of view the best sollution. Also it is very robust and expandable.
I'm looking for two bogus credit numbers, preferably 16 digits. One that is valid using CRC but not LUHN, and one that is valid using LUHN, but not CRC. Does anyone have any or know where I could find examples?
Credit Card Validation with AbstractValidator
At 6:26 AM on Aug 4, 2005, Michael Urban wrote:
Fresh Jobs for Developers Post a job opportunity
This is a followup to the AbstractValidator we created in Building a Swing Validation Package with InputVerifier that shows some examples of validators I built ontop of AbstractValidator. The main validator I want to show is a very powerful one which validates credit card numbers, even down to checking for mistyped digits. But lets start with something simpler just to show how easy it is to build a validator ontop of AbstractValidator.
The NotEmptyValidator
NotEmptyValidator is a very simple validator. All it does is make sure that the user entered something in the text field. It shows just how easy it is to write and use actual validators using the validation package we wrote earlier. Here is the short and simple code for NotEmptyValidator:
package org.javalobby.validation; import javax.swing.JComponent; import javax.swing.JTextField; import javax.swing.JDialog; /** * A class for performing basic validation on text fields. All it does is make * sure that they are not null. * * @author Michael Urban */ public class NotEmptyValidator extends AbstractValidator { public NotEmptyValidator(JDialog parent, JTextField c, String message) { super(parent, c, message); } protected boolean validationCriteria(JComponent c) { if (((JTextField)c).getText().equals("")) return false; return true; } }That's all there is too it. To use the validator on a text field in your application, all you have to to is something like this:
Now lets takes a look at a more complex, but very powerful and useful validator.
The CreditCardValidator
CreditCardValidator does pre-validation of credit card numbers before actually sending them off for authrorization. It is a very powerful validator that uses the Luhn algorithm to catch mistakes in credit card number input, all the way down to the user simply mistyping a single digit in the card number. As you can see, validation criteria for a validator package can be arbitrarily complex. Let's look at the source code for CreditCardValidator:
package org.javalobby.validation; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JTextField; import java.util.regex.*; /** * A class for performing pre-validation on credit cards. * * @author Michael Urban */ public class CreditCardValidator extends AbstractValidator { public static final int MASTERCARD = 0, VISA = 1; public static final int AMEX = 2, DISCOVER = 3, DINERS = 4; private JDialog parent; private Object form; private static final String[] messages = { "Not a valid number for MasterCard.", "Not a valid number for Visa.", "Not a valid number for American Express.", "Not a valid number for Discover.", "Not a valid number for Diner's Club" }; public CreditCardValidator(JDialog parent, Object form, JComponent c, String message) { super(parent, c, message); this.parent = parent; this.form = form; } protected boolean validationCriteria(JComponent c) { String number = ((JTextField)c).getText(); if (number.equals("")) { setMessage("Field cannnot be blank."); return false; } Matcher m = Pattern.compile("[^\\d\\s.-]").matcher(number); if (m.find()) { setMessage("Credit card number can only contain numbers, spaces, \"-\", and \".\""); return false; } int type = ((CreditCardValidation)form).validateCreditCardType(); setMessage(messages[type]); Matcher matcher = Pattern.compile("[\\s.-]").matcher(number); number = matcher.replaceAll(""); return validate(number, type); } // Check that cards start with proper digits for // selected card type and are also the right length. private boolean validate(String number, int type) { switch(type) { case MASTERCARD: if (number.length() != 16 || Integer.parseInt(number.substring(0, 2)) < 51 || Integer.parseInt(number.substring(0, 2)) > 55) { return false; } break; case VISA: if ((number.length() != 13 && number.length() != 16) || Integer.parseInt(number.substring(0, 1)) != 4) { return false; } break; case AMEX: if (number.length() != 15 || (Integer.parseInt(number.substring(0, 2)) != 34 && Integer.parseInt(number.substring(0, 2)) != 37)) { return false; } break; case DISCOVER: if (number.length() != 16 || Integer.parseInt(number.substring(0, 5)) != 6011) { return false; } break; case DINERS: if (number.length() != 14 || ((Integer.parseInt(number.substring(0, 2)) != 36 && Integer.parseInt(number.substring(0, 2)) != 38) && Integer.parseInt(number.substring(0, 3)) < 300 || Integer.parseInt(number.substring(0, 3)) > 305)) { return false; } break; } return luhnValidate(number); } // The Luhn algorithm is basically a CRC type // system for checking the validity of an entry. // All major credit cards use numbers that will // pass the Luhn check. Also, all of them are based // on MOD 10. private boolean luhnValidate(String numberString) { char[] charArray = numberString.toCharArray(); int[] number = new int[charArray.length]; int total = 0; for (int i=0; i < charArray.length; i++) { number[i] = Character.getNumericValue(charArray[i]); } for (int i = number.length-2; i > -1; i-=2) { number[i] *= 2; if (number[i] > 9) number[i] -= 9; } for (int i=0; i < number.length; i++) total += number[i]; if (total % 10 != 0) return false; return true; } }Because we need to check the credit card type, notice that this validator requires an additional interface so that our validator can retrieve the credit card type from the form. That interface is CreditCardValidation:
package org.javalobby.validation; public interface CreditCardValidation { int validateCreditCardType(); }Notice that in this validator, we provide context sensitive pop help messages and check for three different possible problems: Whether the the user left the credit card field blank; whether the user entered illegal characters in the credit card field; and whether or not the credit card type could be a valid credit card number for the card type in question.
CreditCardValidator is mostly just algorithm programming, so I am not going to go into details about how it works. But suffice it to say, it shows that the validation criteria we implement can be arbitrarily complex, and that in CreditCardValidator, all we had to focus on was writing the logic for our validator. We didn't haven't to worry about presenting validation results to the user at all. AbstractValidator we wrote earlier takes care of all those details for us.
Message was edited by: Michael Urban5 replies so far (
Post your own)
Re: Credit Card Validation with AbstractValidator
That's pretty good. BUT, some newer card numbers are now 19 digits long. So tou may check for that length too.Re: Credit Card Validation with AbstractValidator
Well nice but why U dont use strategy pattern for validation algorithms? If it depends on card type it is the from my point of view the best sollution. Also it is very robust and expandable.Re: Credit Card Validation with AbstractValidator
It is really nice , thank you for the good work .Re: Credit Card Validation with AbstractValidator
Thanks for this.I think there's a bug in the diners if statement. Looks like it blocks all cards not between 300 and 305.
case DINERS:
if (number.length() != 14 ||
((Integer.parseInt(number.substring(0, 2)) != 36 &&
Integer.parseInt(number.substring(0, 2)) != 38) &&
Integer.parseInt(number.substring(0, 3)) Integer.parseInt(number.substring(0, 3)) > 305))
{
return false;
}
break;
}
Re: Credit Card Validation with AbstractValidator
I'm looking for two bogus credit numbers, preferably 16 digits. One that is valid using CRC but not LUHN, and one that is valid using LUHN, but not CRC. Does anyone have any or know where I could find examples?