Check multiple Boolean condition in java [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a scenario in which I have to check whether the template exists already in the database. If it exists I have to return a message based on the existing template.
I have several templates: Email, Letter, SMS. If all of them exist I have to return "All template exist already."
If only the Email template exists I have to return that only the email template exists, same for Letter and Sms templates.
Code:
for (EventVO eventVO: eventModuleList) {
List <EmailTemplateMaster> emailTemplateList = communicationDAO
.checkEmailTemplateExist(eventVO.getEventCode());
if (CollectionUtils.isNotEmpty(emailTemplateList)) {
emailTemplateExist = true;
}
List <LetterTemplateMaster> letterTemplateList = communicationDAO
.checkLetterTemplateExist(eventVO.getEventCode());
if (CollectionUtils.isNotEmpty(letterTemplateList)) {
letterTemplateExist = true;
}
List <SmsTemplateMaster> smsTemplateList = communicationDAO
.checkSmsTemplateExist(eventVO.getEventCode());
if (CollectionUtils.isNotEmpty(smsTemplateList)) {
smsTemplateExist = true;
}
if (emailTemplateExist && letterTemplateExist && smsTemplateExist) {
templateExist = CommunicationConstants.ALL_TEMPLATE_EXIST;
}
if (emailTemplateExist || !letterTemplateExist && !smsTemplateExist) {
templateExist = CommunicationConstants.EMAIL_TEMPLATE_EXIST;
}
if (!emailTemplateExist && letterTemplateExist && !smsTemplateExist) {
templateExist = CommunicationConstants.LETTER_TEMPLATE_EXIST;
}
if (!emailTemplateExist && !letterTemplateExist && smsTemplateExist) {
templateExist = CommunicationConstants.SMS_TEMPLATE_EXIST;
}
}
Can I know the easiest way to check the Boolean value of exit template exist.
Based on exit, I have to sent the corresponding message.
public static final String ALL_TEMPLATE_EXIST = "Email, Letter and Sms Template already exist for the selected event.";
public static final String EMAIL_TEMPLATE_EXIST = "Email Template already exist for the selected event.";
public static final String SMS_TEMPLATE_EXIST = "Sms Template already exist for the selected event.";
public static final String LETTER_TEMPLATE_EXIST = "Email Letter Template already exist for the selected event.";
public static final String EMAIL_SMS_TEMPLATE_EXIST = "Email and Sms Template already exist for the selected event.";
public static final String EMAIL_LETTER_TEMPLATE_EXIST = "Email and Letter Template already exist for the selected event.";
public static final String SMS_LETTER_TEMPLATE_EXIST = "Sms and Letter Template already exist for the selected event.";

You could "prepare" the mapping between the booleans and the messages in the CommunicationConstants class:
public class CommunicationConstants
{
private static final Map<List<Boolean>, String> CONSTANTS = new HashMap<>();
static
{
CONSTANTS.put(Arrays.asList(true, true, true), "Email, Letter and Sms Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(true, true, false), "Email and Sms Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(true, false, true), "Email and Letter Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(false, true, true), "Sms and Letter Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(true, false, false), "Email Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(false, true, false), "Sms Template already exist for the selected event.");
CONSTANTS.put(Arrays.asList(false, false, true), "Letter Template already exist for the selected event.");
}
public static String getMessage(boolean emailExists, boolean smsExists, boolean letterExists)
{
return CONSTANTS.get(Arrays.asList(emailExists, smsExists, letterExists));
}
}
The code to retrieve it will be a one-liner then:
System.out.println(CommunicationConstants.getMessage(true, false, true));

If it's possible to you to change your DataBase model, do following changes:
1- Change all booleans into Template type which is VARCHAR() with following allowed values => ALL_TEMPLATE_EXIST, EMAIL_TEMPLATE_EXIST, LETTER_TEMPLATE_EXIST, SMS_TEMPLATE_EXIST
2- After reading the value from data base use only one line code to set your values:
templateExist = CommunicationConstants.valueOf(thePropertyValueYouReadFromDataBase);
Edit
By this change, taking decision of which template already exist would be up to the business code which insert template, reading part only read value of what really inserted

I would do it this way. I find it clearer but obviously every body's mind is different.
if (emailTemplateExist) {
templateExist = letterTemplateExist && smsTemplateExist ? CommunicationConstants.ALL_TEMPLATE_EXIST: CommunicationConstants.EMAIL_TEMPLATE_EXIST;
}
else{
if (letterTemplateExist && !smsTemplateExist)
templateExist = CommunicationConstants.LETTER_TEMPLATE_EXIST;
else if (!letterTemplateExist && smsTemplateExist)
templateExist = CommunicationConstants.SMS_TEMPLATE_EXIST;
}
// There is a possiblity that you will end up with a null value in templateExist so you should initialize it with some default.

In my opinion, you are missing several cases… However, you can do it by nesting if statements. Please note that I added a value to the enum that represents the case of no template existing in the database. With this approach, you will need additional enum values for email and sms, email and letter and letter and sms. If you are sure those cases will never happen, then this approach covers too much.
public static void main(String[] args) {
boolean emailTemplateExist = true;
boolean letterTemplateExist = true;
boolean smsTemplateExist = true;
CommunicationConstants templateExist = CommunicationConstants.NO_TEMPLATE_EXIST;
if (emailTemplateExist) {
if (letterTemplateExist) {
if (smsTemplateExist) {
// email exists, letter exists, sms exists ==> 3/3
templateExist = CommunicationConstants.ALL_TEMPLATE_EXIST;
} else {
// email exists, letter exists, sms does not exist ==> 2/3
// what to do here?
/*
* what to do in this case? The enum has no value for that...
*/
}
} else {
if (smsTemplateExist) {
// email exists, letter does not exist, sms exists ==> 2/3
/*
* what to do in this case? The enum has no value for that...
*/
} else {
// email exists, letter does not exist, sms does not exist ==> 1/3
}
}
} else {
if (letterTemplateExist) {
if (smsTemplateExist) {
// email does not exist, letter exists, sms exists ==> 2/3
/*
* what to do in this case? The enum has no value for that...
*/
} else {
// email does not exist, letter exists, sms does not exist ==> 1/3
templateExist = CommunicationConstants.LETTER_TEMPLATE_EXIST;
}
} else {
if (smsTemplateExist) {
// email does not exist, letter does not exist, sms exists ==> 1/3
templateExist = CommunicationConstants.SMS_TEMPLATE_EXIST;
} else {
// email does not exist, letter does not exist, sms does not exist ==> 0/3
/*
* by initializing the return value with something like "NO_TEMPLATE_EXIST",
* you can omit this else block entirely
*/
templateExist = CommunicationConstants.NO_TEMPLATE_EXIST;
}
}
}
System.out.println(templateExist.toString());
}
enum CommunicationConstants {
ALL_TEMPLATE_EXIST,
EMAIL_TEMPLATE_EXIST,
LETTER_TEMPLATE_EXIST,
SMS_TEMPLATE_EXIST,
NO_TEMPLATE_EXIST
}
Just play around with the initial values (currently, they all are true).

Below code generates all combinations with single template:
public class Main {
enum TemplateType {
Email, Sms, Letter
}
private static final String MSG_EXISTS = "%s Template%s already exist%s for the selected event.";
private static int testCounter;
public static void main(String[] args) {
// Generates all combinations
for (testCounter = 0; testCounter < 8; testCounter++) {
System.out.println(testCounter + ". " + evaluate());
}
}
private static String evaluate() {
List<String> templateList = Arrays.stream(TemplateType.values())
.filter(Main::checkExistence)
.map(TemplateType::name)
.collect(Collectors.toList());
if (templateList.isEmpty()) {
return null;
}
int size = templateList.size();
String arg1 = prettyPrintListJoiner(templateList);
return String.format(MSG_EXISTS, arg1, size == 1 ? "" : "s", size == 1 ? "s" : "");
}
private static String prettyPrintListJoiner(List<String> templateList) {
int size = templateList.size();
if (size == 1) {
return templateList.get(0);
}
StringJoiner joiner = new StringJoiner(", ");
if (size > 2) {
joiner.add(String.join(", ", templateList.subList(0, size - 2)));
}
return joiner.add(String.join(" and ", templateList.subList(size - 2, size))).toString();
}
// To generate all possibilities with help of testCounter
private static boolean checkExistence(TemplateType type) {
switch (type) {
case Email:
return ((testCounter >> 2) & 1) == 1;
case Sms:
return ((testCounter >> 1) & 1) == 1;
case Letter:
return ((testCounter) & 1) == 1;
}
throw new IllegalArgumentException();
}
}
Test Output:
0. null
1. Letter Template already exists for the selected event.
2. Sms Template already exists for the selected event.
3. Sms and Letter Templates already exist for the selected event.
4. Email Template already exists for the selected event.
5. Email and Letter Templates already exist for the selected event.
6. Email and Sms Templates already exist for the selected event.
7. Email, Sms and Letter Templates already exist for the selected event.

Related

EditText validation not working as expected

I have developed android application and in there I have front end validation to a EditText field where its accept only three alpha and 4 digits.
It is tested in staging environment and front end validation is working perfectly (We don’t have back end validation). But after some time when we check
On our live database. We found some data with only digits relevant to above mentioned field. It seems somehow validation will not effect in some device
And we have received data with only digits. Is it possible or what can be the reason that we received invalid data.
// Check for id is valid format like "ABC1234".
String alphaLen = getResources().getString(R.string.rokaIdAlphaLen);
String numLen = getResources().getString(R.string.rokaIdNumericLen);
if (rokaId.length() > 0 && !Validate.validateRokaId(rokaId, alphaLen, numLen)) {
etRokaid.setError(getString(R.string.error_incorrect_format));
focusView = etRokaid;
cancel = true;
}
public static boolean validateRokaId(String params, String alphaLen, String numLen) {
boolean success = false;
int alphaLength = 0;
int numericLength = 0;
alphaLength = Integer.parseInt(alphaLen.trim());
numericLength = Integer.parseInt(numLen.trim());
if (params.length() == alphaLength + numericLength) {
if (params.substring(0, alphaLength).matches("[a-zA-Z]*")) {
if (params.substring(alphaLength, alphaLength+numericLength).matches("[0-9]*")) {
success = true;
} else {
success = false;
}
} else {
success = false;
}
} else {
success = false;
}
return success;
}
First of all you need to set Edit Text property android:digits in XML file for more security so no other special character to be inserted by the user even if you checked in validation.
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
Now for your format which is 3 character and 4 digit we create a Regex expression. You can create your own Regex Expression and test it from this site. I create this Regex from this site:
[A-Z]{3}\d{4}
public final static Pattern NAME_PATTERN = Pattern.compile("^[A-Z]{3}[0-9]{4}$");
Now just match this pattern.
if (NAME_PATTERN.matcher(edtText.getText().toString().trim()).matches())
{
// Write your logic if pattern match
}
else
{
// Write your logic if pattern not match
}

Issue with variable in a if/else loop in Java

import java.util.HashMap;
public class Driver {
public static void main(String[] args) {
// TODO Auto-generated method stub
String location = "memes more memes Virginia";
String test = createStateMap(location);
System.out.println(test);
}
public static String createStateMap(String loc) {
loc = loc.toUpperCase();
String secondLast; // Retrieves potential second to last value
String lastWord; // Retrieves last value
String state = "failed";
String trimmed = loc.trim(); // Take off spaces at the end of String
String o = trimmed.substring(0, trimmed.lastIndexOf(" ")); // Remove last Word in String EX. "SOUTH CAROLINA" = "SOUTH"
String otrim = o.trim(); // Take off spaces at the end of String
if (trimmed.contains("/")){
secondLast = otrim.substring(otrim.lastIndexOf("/")+1);
lastWord = trimmed.substring(trimmed.lastIndexOf("/")+1);
} else {
secondLast = otrim.substring(otrim.lastIndexOf(" ")+1);
lastWord = trimmed.substring(trimmed.lastIndexOf(" ")+1);
}
HashMap<String,String> names = new HashMap<String,String>();
names.put("ALABAMA", "AL");
names.put("ALASKA", "AK");
names.put("ARIZONA", "AZ");
names.put("ARKANSAS", "AR");
names.put("CALIFORNIA", "CA");
names.put("COLORADO", "CO");
names.put("CONNECTICUT", "CT");
names.put("DELAWARE", "DE");
names.put("FLORIDA", "FL");
names.put("GEORGIA", "GA");
names.put("HAWAII", "HI");
names.put("IDAHO", "ID");
names.put("ILLINOIS", "IL");
names.put("INDIANA", "IN");
names.put("IOWA", "IA");
names.put("KANSAS", "KS");
names.put("KENTUCKY", "KY");
names.put("LOUISIANA", "LA");
names.put("MAINE", "ME");
names.put("MARYLAND", "MD");
names.put("MASSACHUSETTS", "MA");
names.put("MICHIGAN", "MI");
names.put("MINNESOTA", "MN");
names.put("MISSISSIPPI", "MS");
names.put("MISSOURI", "MO");
names.put("MONTANA", "MT");
names.put("NEBRASKA", "NE");
names.put("NEVADA", "NV");
names.put("NEWHAMPSHIRE", "NH");
names.put("JERSEY", "NJ");
names.put("MEXICO", "NM");
names.put("YORK", "NY");
names.put("CAROLINA", "NC");
names.put("DAKOTA", "ND");
names.put("OHIO", "OH");
names.put("OKLAHOMA", "OK");
names.put("OREGON", "OR");
names.put("PENNSYLVANIA", "PA");
names.put("RHODEISLAND ", "RI");
names.put("CAROLINA", "SC");
names.put("DAKOTA", "SD");
names.put("TENNESSEE", "TN");
names.put("TEXAS", "TX");
names.put("UTAH", "UT");
names.put("VERMONT", "VT");
names.put("VIRGINIA", "VA");
names.put("WASHINGTON", "WA");
names.put("VIRGINIA", "WV");
names.put("WISCONSIN", "WI");
names.put("WYOMING", "WY");
System.out.println(secondLast);
if (names.containsValue(lastWord)){
state = lastWord;
}
if (names.containsKey(lastWord)){
if (names.get(lastWord).equals("CAROLINA")){ // Differentiate NC and SC
if (secondLast.equals("North")){
state = "NC";
} else { state = "SC"; }
} if (names.get(lastWord).equals("DAKOTA")) { // Differentiate ND and SD
if (secondLast.equals("North")){
state = "ND";
} else { state = "SD"; }
} if (names.get(lastWord).equals("VIRGINIA")) { // Differentiate WV and VA
if (secondLast.equals("West")){
state = "WV";
} else { state = "VA"; }
} else { state = names.get(lastWord); }
}
return state;} }
I am currently having issues with my code that assigns a state's abbreviations to a variable depending on the String passed into the parameter of the createStateMap method. When the lastWord String is either Virginia, Dakota, or Carolina they will always be assigned WV, ND, or NC- even if the secondLast is not North or West.
Any help would be much appreciated, I have been stuck on this one for a while.
names.get(lastWord) already returns "SC" for key "CAROLINA", so your
names.get(lastWord).equals("CAROLINA")
condition will always return false.
It also makes no sense to put the same key twice in the Map, since the second value will overwrite the first value having the same key.
Why not put the full name of the state as key?
names.put("SOUTH CAROLINA", "SC");
names.put("NORTH CAROLINA", "NC");
In that case
state = names.get(fullStateName);
will always work and you can eliminate all of those conditions, as long as fullStateName contains the full name of the state (either a single word or two words).
If you don't know whether you should search for the last word or the last two words in the Map, you can search for the last two words, and if not found, search for the last word :
state = names.get(secondLast + " " + lastWord);
if (state == null) {
state = names.get(lastWord);
}
So, just as an fyi,
names.put("VIRGINIA", "VA");
names.put("WASHINGTON", "WA");
names.put("VIRGINIA", "WV");
You're working with a HashMap here, so you can only have 1 value per key. This means the only value you'll get when you extract VIRGINIA is WV (the last one to be entered). Just put in the full state name, as Eran suggested. I mean, you're already putting in NEWHAMPSHIRE, which is technically two words, so I don't see why you don't want to do the same thing for the Carolinas, Dakotas, and Virginias.

Reading a text file with boolean values into an array list as objects

I am trying to read a file of string int and boolean values into an array list as object blocks. The string values go into the array list just fine, its the boolean values I'm having trouble with. Every time I encounter the variable 'active'there is a mismatch exception. Please help! The text file for if the block is a wizard goes in this order
name (string)
location (string)
active (boolean) ... the one I'm having issues with
skill level (int)
friendliness (int)
I included the driver class as well as the Witch class which contains the
variable 'active' originally.
Driver class that adds objects to the array list based on what the scanner
reads from the file
package project2;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
public class Project2 {
public static void main(String[] args) {
Scanner inputFileScanner1 = null;
//file name
String listFile = "list.txt";
// Check to see if file exists
try {
inputFileScanner1 = new Scanner(new File(listFile));
} catch (FileNotFoundException e) {
System.out.println("Error opening file.");
System.exit(1);
}
//create Individuals arraylist and Location arraylist
ArrayList < Individual > Individual = new ArrayList < > ();
ArrayList < String > Location = new ArrayList < > ();
//declare variables to read file contents into the arraylist
String wizName, witchName, individualName, location, position,
profession = null, line = null;
int wizLevel, witchSkillLevel, friendliness;
boolean active;
//while there is a next line, if the line equals Wizard, the next four lines
// are wizard name, location, position and level
while (inputFileScanner1.hasNext()) {
line = inputFileScanner1.nextLine();
if (line.trim().equals("Wizard")) {
wizName = inputFileScanner1.nextLine().trim();
location = inputFileScanner1.nextLine().trim();
position = inputFileScanner1.nextLine().trim();
wizLevel = inputFileScanner1.nextInt();
//create wizard object
Individual wizard = new Wizard(wizName, location, position, profession, wizLevel);
//fill arraylist with wizard objects
Individual.add(wizard);
Location.add(location);
} //if the next line is Witch, the next five lines are
// witch name, location, yes/no active, skill level, and friendliness
//in that order
else if (line.trim().equals("Witch")) {
witchName = inputFileScanner1.nextLine().trim();
location = inputFileScanner1.nextLine().trim();
active = inputFileScanner1.nextBoolean();
witchSkillLevel = inputFileScanner1.nextInt();
friendliness = inputFileScanner1.nextInt();
//create witch object
Individual witch = new Witch(witchName, location, profession, witchSkillLevel, friendliness, active);
//fill the arraylist with witch objects
Individual.add(witch);
Location.add(location);
} else {
profession = line.trim();
individualName = inputFileScanner1.nextLine().trim();
location = inputFileScanner1.nextLine().trim();
Individual i = new Individual(profession, individualName, location);
Individual.add(i);
Location.add(location);
}
java.util.Collections.sort(Individual);
java.util.Collections.sort(Location);
}
System.out.println("List of friends and possible allies: " + Location);
inputFileScanner1.close();
}
}
//Witch class which holds values that are in the text file. active is the boolean value Im having trouble with
package project2;
public class Witch extends Individual implements Magical {
private int skill;
private int friendly;
//Constructor with witch parameters
public Witch(String name, String location, String profession,
int skill, int friendly, boolean active) {
}
//default constructor
public Witch() {
this("", "", "", 0, 0, false);
}
//overridden abstract method from magical interface
#Override
public void assess() {
System.out.print(this.friendly + " " + this.skill + " " + super.toString());
}
}
<!-- end snippet -->
Text file :
enter image description here
When you pull in your boolean variable do something like this.
if(inputFileScanner1.nextLine().trim().equals("yes"))
{
active = true;
}
else
{
active = false;
}
Okay, the problem is that the file contains the strings yes and no, that are not directly parsable as booleans (should be true or false).
If you can change the original data file somehow, I would suggest to use the two true and false keywords, otherwise, the #Sendrick Jefferson solution will do the job (at your own risk: every typo, as for instance "ye", will be translated into false).

Accessing string template rule names from ANTLR base listener

Working on a pretty printer. Based on my understanding of ANTLR and StringTemplate so far, if I want to match all my grammar rules to templates and apply the template each time the grammar rule is invoked, I can create my templates with names matching my grammar rules.
[Side question: Is this how I should approach it? It seems like ANTLR should being doing the work of matching the parsed text to the output templates. My job will be to make sure the parser rules and templates are complete/correct.]
I think ANTLR 3 allowed directly setting templates inside of the ANTLR grammar, but ANTLR 4 seems to have moved away from that.
Based on the above assumptions, it looks like the MyGrammarBaseListener class that ANTLR generates is going to be doing all the work.
I've been able to collect the names of the rules invoked while parsing the text input by converting this example to ANTLR 4. I ended up with this for my enterEveryRule():
#Override public void enterEveryRule(ParserRuleContext ctx) {
if (builder.length() > 0) {
builder.append(' ');
}
if (ctx.getChildCount() > 0) {
builder.append('(');
}
int ruleIndex = ctx.getRuleIndex();
String ruleName;
if (ruleIndex >= 0 && ruleIndex < ruleNames.length) {
ruleName = ruleNames[ruleIndex];
System.out.println(ruleName); // this part works as intended
}
else {
ruleName = Integer.toString(ruleIndex);
}
builder.append(ruleName);
// CONFUSION HERE:
// get template names (looking through the API to figure out how to do this)
Set<String> templates = (MyTemplates.stg).getTemplateNames()
// or String[] for return value? Java stuff
// for each ruleName in ruleNames
// if (ruleName == templateName)
// run template using rule children as parameters
// write pretty-printed version to file
}
The linked example applies the changes to create the text output in exitEveryRule() so I'm not sure where to actually implement my template-matching algorithm. I'll experiment with both enter and exit to see what works best.
My main question is: How do I access the template names in MyTemplates.stg? What do I have to import, etc.?
(I'll probably be back to ask about matching up rule children to template parameters in a different question...)
Following demonstrates a simple way of dynamically accessing and rendering named StringTemplates. Intent is to build varMap values in the listener (or visitor) in its corresponding context, keyed by parameter name, and call the context dependent named template to incrementally render the content of the template.
public class Render {
private static final String templateDir = "some/path/to/templates";
private STGroupFile blocksGroup;
private STGroupFile stmtGroup;
public Render() {
blocksGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Blocks.stg"));
stmtGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Statements.stg"));
}
public String gen(GenType type, String name) {
return gen(type, name, null);
}
/**
* type is an enum, identifying the group template
* name is the template name within the group
* varMap contains the named values to be passed to the template
*/
public String gen(GenType type, String name, Map<String, Object> varMap) {
Log.debug(this, name);
STGroupFile stf = null;
switch (type) {
case BLOCK:
stf = blocksGroup;
break;
case STMT:
stf = stmtGroup;
break;
}
ST st = stf.getInstanceOf(name);
if (varMap != null) {
for (String varName : varMap.keySet()) {
try {
st.add(varName, varMap.get(varName));
} catch (NullPointerException e) {
Log.error(this, "Error adding attribute: " + name + ":" + varName + " [" + e.getMessage() + "]");
}
}
}
return st.render();
}
}

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