How can I make users ONLY input decimal? - java

So I am very new to java and struggling with my class ... here's what I thought would work:
double costPerKiloHr = 0; //sets value to 0
//tests to make sure a number was inputted
try {
costPerKiloHr = Double.parseDouble(
this.costPerKiloHrText.getText());
}
catch (Exception e) {
JOptionPane.showMessageDialog(this, "Please input a dollar amount including cents",
"Error", JOptionPane.ERROR_MESSAGE);
return;
}

You can use regex to check for a match for at least 1 numerical value after the decimal.
String input = scanner.next();
Pattern pattern = Pattern.compile("[0-9]*\\.[0-9]+");
Matcher matcher = pattern.matcher(input);
if(matcher.matches()){
System.out.println("True");
}else{
System.out.println("False");
}
OUTPUT
1.0 True
ASB False
0.25 True
1 False

You cannot make users to input what you want, if you are not a mage or smth. But you can edit the code that accept user input. There can be a huge difference: I don't know what are you using as input. I noticed you're using JOptionPane so I guess you use swing.
In swing there is JTextField and you can control it's content like this:
final JTextField field = new JTextField();
field.addKeyListener(new KeyListener() {
StringBuilder buffer = new StringBuilder();
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (Character.isDigit(c)) {
buffer.append(c);
}
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
field.setText(buffer.toString());
}
});
If you are using InputStream you should interpret byte pairs as chars and then filter out non-digit values. Declaration of delimiters is required that way.

Assuming you are using Swing (a safe bet given the use of JOptionPane), you can have the user type into a javax.swing.JFormattedTextField... This is an extension of the JTextField widget that takes a Formatter object that defines what is and isn't acceptible. It can be configured (through Formatter.setAllowsInvalid(false)) to never let the user type in an invalid string.
So a formatter for an arbitrary regular expression might look something like this:
public class RegExFormatter extends DefaultFormatter {
protected Matcher matcher;
public RegExFormatter(String regex) {
setOverwriteMode(false);
Pattern p = Pattern.compile(regex);
matcher = p.matcher(""); // initial field contents
}
#Override
public Object stringToValue(String string) throws ParseException {
if (string == null || string.trim().equals(""))
return null;
matcher.reset(string);
if (!matcher.matches()) {
throw new ParseException("Input did not match regex", 0);
}
return super.stringToValue(string); // default returns this string; see docs!
}
}
Then you use this in your code like this:
String regex = "^[1-9]*[0-9](\\.\\d*)?$"; // change this to taste!
RegExFormatter ref = new RegExFormatter(regex);
ref.setAllowsInvalid(false);
JFormattedTextField field1 = new JFormattedTextField(ref);

Related

Extracting Operation(...); and sub Operation from String using REGEX

I have an issue with a Regex in java for Android.
i would like to retreive the first operation (and each sub operations) like in the following samples:
"OPERATION(ASYNC_OPERATION,_RFID_ITEM_SERIAL);"
"OPERATION(CONCAT,~1261,01,OPERATION(ASYNC_OPERATION,_RFID_ITEM_ID);,21,OPERATION(ASYNC_OPERATION,_RFID_ITEM_SERIAL););"
As you can see each Operation can have sub Operations... And that's where i'm getting problems.
Actually i am using this Regex: ^\s*(OPERATION\s*\(\s*)(.*)(\);)
but the index of ");" returned is always the last index, and in case of two sub operations, inside of a "Main" operation, this is wrong...
private static Pattern operationPattern=Pattern.compile("^\\s*(OPERATION\\s*\\(\\s*)(.*)(\\);)",Pattern.CASE_INSENSITIVE);
public Operation(String text){
parseOperationText(text);
}
private void parseOperationText(String text){
String strText = text.replace("#,", "§");
Matcher matcher=operationPattern.matcher(strText);
if(matcher.find()) {
//This is an OPERATION
subOperations=new ArrayList<>();
String strChain = matcher.group(2);//Should only contain the text between "OPERATION(" and ");"
int commaIdx = strChain.indexOf(",");
if (commaIdx == -1) {
//Operation without parameter
operationType = strChain;
} else {
//Operation with parameters
operationType = strChain.substring(0, commaIdx);
strChain = strChain.substring(commaIdx + 1);
while (strChain.length()>0) {
matcher = operationPattern.matcher(strChain);
if (matcher.find()) {
String subOpText=matcher.group(0);
strChain=StringUtils.stripStart(strChain.substring(matcher.end())," ");
if(strChain.startsWith(",")){
strChain=strChain.substring(1);
}
subOperations.add(new Operation(subOpText));
}
else{
commaIdx = strChain.indexOf(",");
if(commaIdx==-1)
{
subOperations.add(new Operation(strChain));
strChain="";
}
else{
subOperations.add(new Operation(strChain.substring(0,commaIdx)));
strChain=strChain.substring(commaIdx+1);
}
}
}
}
}
else {
//Not an operation
//...
}
}
It works for sample 1 but for Sample 2, after finding the "Main" operation (CONCAT in the sample), the second match returns this:
OPERATION(ASYNC_OPERATION,_RFID_ITEM_ID);,21,OPERATION(ASYNC_OPERATION,_RFID_ITEM_SERIAL);
What i would like to retrieve is this:
"CONCAT,~1261,01,OPERATION(ASYNC_OPERATION,_RFID_ITEM_ID);,21,OPERATION(ASYNC_OPERATION,_RFID_ITEM_SERIAL);"
"ASYNC_OPERATION,_RFID_ITEM_ID"
"ASYNC_OPERATION,_RFID_ITEM_SERIAL"
Could use this
"(?s)(?=OPERATION\\s*\\()(?:(?=.*?OPERATION\\s*\\((?!.*?\\1)(.*\\)(?!.*\\2).*))(?=.*?\\)(?!.*?\\2)(.*)).)+?.*?(?=\\1)(?:(?!OPERATION\\s*\\().)*(?=\\2$)"
to find the balanced OPERATION( ) string in group 0.
https://regex101.com/r/EsaDtC/1
Then use this
(?s)^OPERATION\((.*?)\)$
on that last matched string to get the inner contents of the
operation, which is in group 1.
Finally i'm using two different REGEX :
//First Regex catches main operation content (Group 2):
\s*(OPERATION\s*\(\s*)(.*)(\);)
//Second Regex catches next full sub "OPERATION(...);" (Group 0):
^(?:\s*(OPERATION\s*\(\s*))(.*)(?:\)\s*\;\s*)(?=\,)|^(?:\s*(OPERATION\s*\(\s*))(.*)(?:\)\s*\;\s*)$
Then i can use Fisst Regex to detect if this is an operation (match.find()), catch it's content in Group(2) and then for each param (separated by comma) i can check if it's a sub operation with second regex. If it's a sub Operation i call recursively the same function that uses First Regex again... and so on.
private static Pattern operationPattern=Pattern.compile("^\\s*(OPERATION\\s*\\(\\s*)(.*)(\\);)",Pattern.CASE_INSENSITIVE);
private static Pattern subOperationPattern=Pattern.compile("^(?:\\s*(OPERATION\\s*\\(\\s*))(.*)(?:\\)\\s*\\;\\s*)(?=\\,)|^(?:\\s*(OPERATION\\s*\\(\\s*))(.*)(?:\\)\\s*\\;\\s*)$",Pattern.CASE_INSENSITIVE);
private void parseOperationText(String strText ){
Matcher matcher=operationPattern.matcher(strText);
if(matcher.find()) {
//This is an OPERATION
subOperations=new ArrayList<>();
String strChain = matcher.group(2);
int commaIdx = strChain.indexOf(",");
if (commaIdx == -1) {
//Operation without parameter
operationType = strChain;
} else {
//Operation with parameters
operationType = strChain.substring(0, commaIdx);
strChain = strChain.substring(commaIdx + 1);
while (strChain.length()>0) {
matcher = subOperationPattern.matcher(strChain);
if (matcher.find()) {
String subOpText=matcher.group(0);
strChain=StringUtils.stripStart(strChain.substring(matcher.end())," ");
if(strChain.startsWith(",")){
strChain=strChain.substring(1);
}
subOperations.add(new Operation(subOpText));
}
else{
commaIdx = strChain.indexOf(",");
if(commaIdx==-1)
{
subOperations.add(new Operation(strChain));
strChain="";
}
else{
subOperations.add(new Operation(strChain.substring(0,commaIdx)));
strChain=strChain.substring(commaIdx+1);
}
}
}
}
}
else {
//Fixed value: we store the value as is
fieldValue = strText;
operationType = OperationType.NONE;
}
}
public Operation(String text){
parseOperationText(text);
}

Check if String token contains string char and String number value

1)I need to check if String contains a String characters what will be the corect way how to do it ?
2) Are some ways how to corectly transform String to number and then compare theese two number s? Like String = "House":1234 is equal to "House":1234 but no to "house":123
Priview:
String token ="123"; False
String token = "ā123"; or other characters True utc.
if(isChars(token)){
Long value = toLong(token);
}
THANKS!
//EDIT
public BigDecimal eval() {
Stack<BigDecimal> stack = new Stack<BigDecimal>();
for (String token : getRPN()) {
if (operators.containsKey(token)) {
BigDecimal v1 = stack.pop();
BigDecimal v2 = stack.pop();
stack.push(operators.get(token).eval(v2, v1));
} else if (variables.containsKey(token)) {
stack.push(variables.get(token).round(mc));
} else if (functions.containsKey(token.toUpperCase())) {
Function f = functions.get(token.toUpperCase());
ArrayList<BigDecimal> p = new ArrayList<BigDecimal>(f.getNumParams());
for (int i = 0; i < f.numParams; i++) {
p.add(0, stack.pop());
}
BigDecimal fResult = f.eval(p);
stack.push(fResult);
} else if (isDate(token)) {
Long date = null;
try {
date = SU.sdf.parse(token).getTime();
} catch (ParseException e) {/* IGNORE! */
}
// mylog.pl("LONG DATE : "+new BigDecimal(date, mc));
stack.push(new BigDecimal(date, mc));
}//TODO HERE
else if (isChar(token)){
Long cha = toLong(token);
stack.push(new BigDecimal(cha, mc));
//TODO ENDS HERE
}
else {
// mylog.pl("Token : "+ token);
stack.push(new BigDecimal(token, mc));
}
}
return stack.pop().stripTrailingZeros();
}
Another way for determing whether string contains any chars is nice class StringUtils from apache-commons-lang library.
It contains several methods for analyzing string's contents. It seems that in your case you can use StringUtils.isAlphanumeric(CharSequence cs) or negation of StringUtils.isNumeric(CharSequence cs)'s result.
What about second part of your question, so I do not see here necessety of extracting numbers from string. You can compare strings "House":1234 and "house":123 using standard String.equals() method.
Long l;
try{
l = Long.parseLong(token);
} catch(NumberFormatException e){
//contains non-numeric character(s)
}
As for "transforming varchar into Long" - that sounds rather impossible, we do not have universally accepted way of doing that, and you did not provide one. However if I guess correctly that what you want is the number within the string disregarding the characters - you want regular expressions. The code you want could look like:
if (!StringUtils.isNumeric(token)){
String stripped = token.replaceAll("\\D","");
Long l = Long.parseLong(stripped);
}

How to limit JTextFiled to accept only numbers less then 10?

How to restrict a JTextFiled to accept only numbers less then 10, no words, no spaces or any other special characters?
The easiest would be to use a component designed for this:
JSpinner spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(0, null, 10, 1));
Technically JSpinner is not derived from JTextField, it uses one internally for the editor part and thus looks like one (plus it has additional buttons to change the number with mouse clicks).
Again, a DocumentFilter is one way to solve this:
import javax.swing.*;
import javax.swing.text.*;
#SuppressWarnings("serial")
public class DocFilterExample extends JPanel{
JTextField textfield = new JTextField(5);
public DocFilterExample() {
PlainDocument doc = (PlainDocument) textfield.getDocument();
doc.setDocumentFilter(new MaxNumberDocFilter(10));
add(textfield);
}
private class MaxNumberDocFilter extends DocumentFilter {
private int maxNumber;
public MaxNumberDocFilter(int maxnumber) {
this.maxNumber = maxnumber;
}
private boolean verifyText(String text) {
if (text.isEmpty()) {
return true; // allow for a blank text field
}
int value = 0;
try {
value = Integer.parseInt(text);
if (value >= 0 && value < maxNumber) {
return true; // if it's a number in range, it passes
}
} catch (NumberFormatException e) {
return false; // if it's not a number, it fails.
}
return false;
}
#Override
public void insertString(FilterBypass fb, int offset, String string,
AttributeSet attr) throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.insert(offset, string);
if (verifyText(sb.toString())) {
super.insertString(fb, offset, string, attr);
}
}
#Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.replace(offset, offset + length, text);
if (verifyText(sb.toString())) {
super.replace(fb, offset, length, text, attrs);
}
}
#Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.replace(offset, offset + length, "");
if (verifyText(sb.toString())) {
super.remove(fb, offset, length);
}
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Eg");
frame.getContentPane().add(new DocFilterExample());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Advantages:
no error messages are needed. Instead it simply prevents input of bad input.
It works for cut and paste just fine.
Disadvantages:
no error messages are given, and so the user won't know why his text is not accepted.
it's a bit long and bulky.
it's not easy "chaining" -- using multiple filters at once, something Rob Camick has done some work on.
Try This :-
JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
//do stuff here when enter pressed
String text = textField.getText();
if(text!=null && !text.equals("")){
char c = evt.getKeyChar();
int val=Integer.parseInt(c);
if(val>=48 && val<=57){
if(Integer.parseInt(text)<=10){
//Its valid and allowed
}else{
//Its invalid, show error message here
}
}else{
//Show message only numbers are allowed
return false;
}
}
}
});
Hope it will help you.
Use Swing Javabuilders, where you can define your GUI in YML (below), including Text Field validation.
You declare in your gui in a yaml file, here is an example for Person.java, called Person.Yaml:
JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose):
- JButton(name=save, text=button.save, onAction=[$validate,save,done])
- JButton(name=cancel, text=button.cancel, onAction=[$confirm,cancel])
- MigLayout: |
[pref] [grow,100] [pref] [grow,100]
"label.firstName" txtFirstName "label.lastName" txtLastName
"label.email" txtEmail+*
>save+*=1,cancel=1
bind:
- txtFirstName.text: person.firstName
- txtLastName.text: person.lastName
- txtEmail.text: person.emailAddress
validate:
- txtFirstName.text: {mandatory: true, label: label.firstName}
- txtLastName.text: {mandatory: true, label: label.lastName}
- txtEmail.text: {mandatory: true, emailAddress: true, label: label.email}
The three blocks above are as follows:
The Swing Classes (JFrame, and JButton) as well as the Layout Manager, with embedded JLabels (label.firstName and label.lastName) which are recognised by the 'label' part of their declaration and the JTextFields (txtLastName,txtFirstName and txtEmail ) which are recognised by the txt part of their name.
The Data Binding: This binds JTextArea.text to class.fieldName so that when data is entered into the JTextField it is mapped to the fields.
Validation: Here is where the text is validated. Notice that the JButton with the name Save has in the onAction section has the entry $validate which runs the in-built validate method. This reads the kind of validation in from the validate block:
txtFirstName.text: {mandatory: true, label: label.firstName}
Which declares the field has to be filled in (mandatory: true) and txtEmail must be filled with a valid email address (emailAddress: true). More validation is outlined below.
Once you've declared the GUI, you just run it like so, from within your java file.
private BuildResult result;
.....
public methodName(){
.....
result = SwingJavaBuilder.build(this).setVisible(true);
}
This method (build(this)) references a .yml file of the same name (so your gui is in person.yml and is paired with person.java).
There's more validation available in the documentation :
validate:
- mandatory.text: {label: Mandatory Field, mandatory: true}
- date.text: {label: Date Field, dateFormat: "yyyy/mm/dd"}
- email.text: {label: E-Mail, email: true}
- minmax.text: {label: Min/Max Length, minLength: 5, maxLength: 10}
- regex.text: {label: Regex, regex: "[a-zA-Z0-9]+"}
- regex2.text: {label: Regex, regex: "[a-zA-Z0-9]+",
regexMessage: "''{0}'' must be a number or letter"}
- long.text: {label: Min/Max Long, minValue: 5, maxValue: 50, mandatory: true}
So you would want to use the last one long.text with this specification:
myValidNumberField{label: Number less than ten, maxValue: 10, mandatory: true}`
There's more information on the github page, about setting your GUI up like this.

Fetch all the hyperlinks from a webpage and recursively doing that in java

1 .Fetch all contents from a Webpage
2. fetch hyperlinks from the webpage.
3. Repeat the 1 & 2 from the fetched hyperlink
4. repeat the process untill 200 hyperlinks regietered or no more hyperlink to fetch.
I wrote a sample programs but due to poor understanding of recursion , my loop became an infinite loop.
Suggest me to solve the code matching the expectation.
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Content
{
private static final String HTML_A_HREF_TAG_PATTERN =
"\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))";
Pattern pattern;
public Content ()
{
pattern = Pattern.compile(HTML_A_HREF_TAG_PATTERN);
}
private void fetchContentFromURL(String strLink) {
String content = null;
URLConnection connection = null;
try {
connection = new URL(strLink).openConnection();
Scanner scanner = new Scanner(connection.getInputStream());
scanner.useDelimiter("\\Z");
content = scanner.next();
}catch ( Exception ex ) {
ex.printStackTrace();
return;
}
fetchURL(content);
}
private void fetchURL ( String content )
{
Matcher matcher = pattern.matcher( content );
while(matcher.find()) {
String group = matcher.group();
if(group.toLowerCase().contains( "http" ) || group.toLowerCase().contains( "https" )) {
group = group.substring( group.indexOf( "=" )+1 );
group = group.replaceAll( "'", "" );
group = group.replaceAll( "\"", "" );
System.out.println("lINK "+group);
fetchContentFromURL(group);
}
}
System.out.println("DONE");
}
/**
* #param args
*/
public static void main ( String[] args )
{
new Content().fetchContentFromURL( "http://www.google.co.in" );
}
}
I am open for any other solution as well but want to stick with core java Api only no 3rd party.
One possible option here is to remember all visited links to avoid cyclic paths. Here's how to archive it with additional Set storage for already visited links:
public class Content {
private static final String HTML_A_HREF_TAG_PATTERN =
"\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))";
private Pattern pattern;
private Set<String> visitedUrls = new HashSet<String>();
public Content() {
pattern = Pattern.compile(HTML_A_HREF_TAG_PATTERN);
}
private void fetchContentFromURL(String strLink) {
String content = null;
URLConnection connection = null;
try {
connection = new URL(strLink).openConnection();
Scanner scanner = new Scanner(connection.getInputStream());
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
content = scanner.next();
visitedUrls.add(strLink);
fetchURL(content);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void fetchURL(String content) {
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
String group = matcher.group();
if (group.toLowerCase().contains("http") || group.toLowerCase().contains("https")) {
group = group.substring(group.indexOf("=") + 1);
group = group.replaceAll("'", "");
group = group.replaceAll("\"", "");
System.out.println("lINK " + group);
if (!visitedUrls.contains(group) && visitedUrls.size() < 200) {
fetchContentFromURL(group);
}
}
}
System.out.println("DONE");
}
/**
* #param args
*/
public static void main(String[] args) {
new Content().fetchContentFromURL("http://www.google.co.in");
}
}
I also fixed some other issues in fetching logic, now it works as expected.
inside the fetchContentFromURL method you should record which url u r currently fetching, and if that url has already be fetched then skip it. otherwise two page A, B, which has a link point to each other will cause your code keep fetching.
In addition to JK1's answer, for achieving target 4 of your question, you might want to maintain the count of hyperlinks as instance variable. A rough pseudo code might be(you can adjust the exact count. Also as an alternate, you can use HashSet length to know the number of Hyperlinks your program has parsed till now):
if (!visitedUrls.contains(group) && noOfHyperlinksVisited++ < 200) {
fetchContentFromURL(group);
}
However, I was not sure whether you want a total of 200 hyperlinks OR want to traverse to a depth of 200 links from starting page. In case it is later, you might wish to explore Breadth First Search, which will let you know when you have reached your target depth.

Empty String validation for Multiple JTextfield

Is there a way to validate a number of JTextfields in java without the if else structure. I have a set of 13 fields, i want an error message when no entry is given for any of the 13 fields and to be able to set focus to that particular textbox. this is to prevent users from entering empty data into database. could someone show me how this can be achieved without the if else structure like below.
if (firstName.equals("")) {
JOptionPane.showMessageDialog(null, "No data entered");
} else if (lastName.equals("")) {
JOptionPane.showMessageDialog(null, "No data entered");
} else if (emailAddress.equals("")) {
JOptionPane.showMessageDialog(null, "No data entered");
} else if (phone.equals("")) {
JOptionPane.showMessageDialog(null, "No data entered");
} else {
//code to enter values into MySql database
the above code come under the actionperformed method a of a submit registration button. despite setting fields in MySQL as NOT NULL, empty string were being accepted from java GUI. why is this? i was hoping perhaps an empty string exception could be thrown from which i could customise a validation message but was unable to do so as empty field were being accepted.
Thanks
Just for fun a little finger twitching demonstrating a re-usable validation setup which does use features available in core Swing.
The collaborators:
InputVerifier which contains the validation logic. Here it's simply checking for empty text in the field in verify. Note that
verify must not have side-effects
shouldYieldFocus is overridden to not restrict focus traversal
it's the same instance for all text fields
a commit action that checks the validity of all children of its parent by explicitly invoking the inputVerifier (if any) and simply does nothing if any is invalid
a mechanism for a very simple though generally available error message taking the label of the input field
Some code snippets
// a reusable, shareable input verifier
InputVerifier iv = new InputVerifier() {
#Override
public boolean verify(JComponent input) {
if (!(input instanceof JTextField)) return true;
return isValidText((JTextField) input);
}
protected boolean isValidText(JTextField field) {
return field.getText() != null &&
!field.getText().trim().isEmpty();
}
/**
* Implemented to unconditionally return true: focus traversal
* should never be restricted.
*/
#Override
public boolean shouldYieldFocus(JComponent input) {
return true;
}
};
// using MigLayout for lazyness ;-)
final JComponent form = new JPanel(new MigLayout("wrap 2", "[align right][]"));
for (int i = 0; i < 5; i++) {
// instantiate the input fields with inputVerifier
JTextField field = new JTextField(20);
field.setInputVerifier(iv);
// set label per field
JLabel label = new JLabel("input " + i);
label.setLabelFor(field);
form.add(label);
form.add(field);
}
Action validateForm = new AbstractAction("Commit") {
#Override
public void actionPerformed(ActionEvent e) {
Component source = (Component) e.getSource();
if (!validateInputs(source.getParent())) {
// some input invalid, do nothing
return;
}
System.out.println("all valid - do stuff");
}
protected boolean validateInputs(Container form) {
for (int i = 0; i < form.getComponentCount(); i++) {
JComponent child = (JComponent) form.getComponent(i);
if (!isValid(child)) {
String text = getLabelText(child);
JOptionPane.showMessageDialog(form, "error at" + text);
child.requestFocusInWindow();
return false;
}
}
return true;
}
/**
* Returns the text of the label which is associated with
* child.
*/
protected String getLabelText(JComponent child) {
JLabel labelFor = (JLabel) child.getClientProperty("labeledBy");
return labelFor != null ? labelFor.getText() : "";
}
private boolean isValid(JComponent child) {
if (child.getInputVerifier() != null) {
return child.getInputVerifier().verify(child);
}
return true;
}
};
// just for fun: MigLayout handles sequence of buttons
// automagically as per OS guidelines
form.add(new JButton("Cancel"), "tag cancel, span, split 2");
form.add(new JButton(validateForm), "tag ok");
There are multiple ways to do this, one is
JTextField[] txtFieldA = new JTextField[13] ;
txtFieldFirstName.setName("First Name") ; //add name for all text fields
txtFieldA[0] = txtFieldFirstName ;
txtFieldA[1] = txtFieldLastName ;
....
// in action event
for(JTextField txtField : txtFieldA) {
if(txtField.getText().equals("") ) {
JOptionPane.showMessageDialog(null, txtField.getName() +" is empty!");
//break it to avoid multiple popups
break;
}
}
Also please take a look at JGoodies Validation that framework helps you validate user input in Swing applications and assists you in reporting validation errors and warnings.
Take an array of these three JTextField, I am giving an overview
JTextField[] fields = new JTextField[13]
field[0] = firstname;
field[1] = lastname; //then add remaining textfields
for(int i = 0; i < fields.size(); ++i) {
if(fields[i].getText().isEmpty())
JOptionPane.showMessageDialog(null, "No data entered");
}
Correct me if i'm wrong, I am not familiar with Swing or awt.HTH :)
Here is one way to do it:
public static boolean areAllNotEmpty(String... texts)
{
for(String s : texts) if(s == null || "".equals(s)) return false;
return true;
}
// ...
if(areAllNotEmpty(firstName, lastName, emailAddress, phone))
{
JOptionPane.showMessageDialog(null, "No data entered");
}

Categories