Empty String validation for Multiple JTextfield - java

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");
}

Related

How to check if JRadioButtons are selected?

I tried
if(jRadioButton1.isSelected() ||(jRadioButton2.isSelected()) {
jGenderGroup.getSelection().getActionCommand();
} else {
jGndrErrorLabel.setText("Select gender.")
}
But controller doesn't stop after highlighted line it does go ahead to final line and throw NullPointerException
customers.setGender(jGenderGroup.getSelection().getActionCommand());
Where customers is POJO class.
How I can get rid of this?
try this :)
jRadioButton1.setActionCommand("Male");
jRadioButton2.setActionCommand("Female");
if(!jGenderGroup.isChecked()){
jLable1.setText("Please Select Gender");
}
if(jRadioButton1.isSelected())
{
//Male
}
else if(jRadioButton2.isSelected())
{
//Female
}
else
{
// no radio button has been selected
}
or alter your code like
if(jGenderGroup.getSelection() != null)
{
customer.setGender(jGenderGroup.getSelection().getActionCommand())
} else {
jGndrErrorLabel.setText("Select gender.")
}
I simply removed ButtonGroup jGenderGroup
and perform conditions for jRadioButton1 and jRadioButton2 at last instead of middle and as I had commented I can not set String gender = new String(); as
gender = jRadioButton1.getActionCommand();
Within conditional block because of POJO
So I just tricked that put it at the end like this :
String gender = new String();
if (jRadioButton1.isSelected()) {
gender = jRadioButton1.getActionCommand();
} else if (jRadioButton2.isSelected()) {
gender = jRadioButton2.getActionCommand();
} else {
jGndrErrorLabel.setText("Select gender.");
jGndrErrorLabel.setForeground(Color.red);
}
That's what I expected
Thanks for all of your time and efforts.

java - making JButton disable when login with different account [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
i'm trying to disable some JButton with different account(something like permissions), here is my code to be more clear question...
try
{
stat = conn.prepareStatement(sql);
rs=stat.executeQuery();
while(rs.next())
{
System.out.println("found");
String _name= rs.getString("name");
String _pass = rs.getString("password");
String _stat = rs.getString("status");
if (_name == name && pass == _pass && _stat == "admin")
{
new SecondFrame().setVisible(true);//all buttons works as admin
}
else if(_name == name && pass == _pass && _stat == "moderator")
{
SecondFrame ob = new SecondFrame();
ob.admin_btn.setEnabled(false);//just user+moderator button works
}
else if(_name == name && pass == _pass && _stat == "user")
{
SecondFrame ob = new SecondFrame();
ob.admin_btn.setEnabled(false);
ob.moderator_btn.setEnabled(false);
// just user button works
}
}
}
catch (SQLException SQLe)
{
System.out.println("not executed"+SQLe);
}
... but i can't disable buttons like this(syntax is wrong), is there a way to make buttons disabled from this class?
thanks for help
1. String comparison error
Your main error is that you compare Strings with == in your code. In Java, this comparator will only work properly with basic types like long, double, boolean etc. therefore : use _stat.equals("moderator").
The reason why == won't work is that it compares the object's memory address instead of the inner values.
here's a code you can use :
try {
stat = conn.prepareStatement(sql);
rs=stat.executeQuery();
while(rs.next()) {
System.out.println("found");
String _name= rs.getString("name");
String _pass = rs.getString("password");
String _stat = rs.getString("status");
if (_name.equals(name) && pass.equals(_pass) && _stat.equals("admin")) {
new User().setVisible(true);//all buttons works as admin
} else if(_name.equals(name) && pass.equals(_pass) && _stat.equals("moderator")) {
SecondFrame ob = new SecondFrame();
ob.admin_btn.setEnabled(false);//just user+moderator button works
} else if(_name.equals(name) && pass.equals(_pass) && _stat.equals("user")) {
SecondFrame ob = new SecondFrame();
ob.admin_btn.setEnabled(false);
ob.moderator_btn.setEnabled(false);
// just user button works
}
}
} catch (SQLException SQLe) {
System.out.println("not executed"+SQLe);
}
2. Access related issue
After that, your code may still not work since you may have an access issue. Check if your SecondFrame class's button attributes are public. If they are not, you would better create a method that will set enabled inside that class for you with the user's access. Something like this :
public void setButtonAccess (String pAccess) {
user_button.setEnabled(false);
moderator_btn.setEnabled(false);
admin_btn.setEnabled(false);
if (pAccess.equals("user")) {
user_btn.setEnabled(true);
} else if (pAccess.equals("moderator")) {
user_btn.setEnabled(true);
moderator_btn.setEnabled(true);
} else if (pAccess.equals("admin")) {
user_button.setEnabled(true);
moderator_btn.setEnabled(true);
admin_btn.setEnabled(true);
}
}
Although the use of an enum would suit this situation pretty well... But for more information, I suggest the following readings :
Enum Types in Java
The switch statement

Java JFileChooser append extension on filter change

I have filters
All
html
txt
Depending on which filter is selected, append the extension to the JFileChooser or disallow the user to enter an extension.
Not after they press save button but while the window is open.
I was looking at addPropertyChangeListener but i can't find anything outside of the file change property.
EDIT: I got this far, i can get the filter to be added but i still have no idea how to fetch the associated filter.
fc.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent evt)
{
**MyFileFilter** filter = (**MyFileFilter**) evt.getNewValue();
String extension = filter.getExtensionByDescription(filter.getDescription());
//String extension = "ext"; // somehow here
fc.setSelectedFile(new File("." + extension));
}
});
SOLUTION
Create a custom class that extends FilerFilter
public String getExtensionByDescription(String description)
{
for (int i = 0 ; i < fileList.size(); i++)
{
if (description.contains(fileList.get(i).getDescription()))
{
return "." + fileList.get(i).getExtension();
}
}
// for (FileType obj : fileList)
// {
// if (description.contains(obj.getDescription()))
// return "." + obj.getExtension();
// }
return "";
}
On a side question, does anyone know why the commented out for loop doesn't work? It returns the wrong Extension but it is logically the same thing as the above loop :S

reducing number of return statements in a method

I have a java code in which there are multiple return statements in a single method. But for code cleaning purpose, I can have only one return statement per method. What can be done to overcome this.
Here is a method from my code:-
public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Kill any old sessions
//request.getSession().invalidate();
DynaValidatorForm dynaform = (DynaValidatorForm)form;
// validate the form
ActionErrors errors = form.validate(mapping, request);
if(!errors.isEmpty()) {
this.saveErrors(request, errors);
return mapping.getInputForward();
}
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// no input errors detected
String resumekey = null;
// check for valid login
ObjectFactory objFactory = ObjectFactory.getInstance();
DataAccessor dataAccessor = objFactory.getDataAccessor();
request.setCharacterEncoding("UTF-8");
String testcode = dynaform.getString("testcode").trim();
String studentname = dynaform.getString("yourname").trim();
String password = dynaform.getString("password").trim();
// 4/3/07 - passwords going forward are ALL lower case
if (!CaslsUtils.isEmpty(password)) {
password = password.toLowerCase();
}
try{
resumekey = new String(studentname.getBytes("ISO-8859-1"),"UTF-8");
} catch (Exception e) {
log_.error("Error converting item content data to UTF-8 encoding. ",e);
}
String hashWord = CaslsUtils.encryptString(password);
// Make sure this is short enough to fit in the db
if (hashWord.length() > ConstantLibrary.MAX_PASSWORD_LENGTH) {
hashWord = hashWord.substring(0, ConstantLibrary.MAX_PASSWORD_LENGTH);
}
Login login = dataAccessor.getLogin(testcode, hashWord, false);
if (login == null || !login.getUsertype().equals(Login.USERTYPE_SUBJECT)) {
request.setAttribute("errormessage", "Incorrect test code or password.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the login has expired
if (login.getLoginexpires() != null && login.getLoginexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the password has expired
if (login.getPasswordexpires() != null && login.getPasswordexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login password has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
HttpSession session = request.getSession();
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_STUDENTNAME, studentname);
List<Testtaker> testtakers = null;
try {
//invalidate the old session if the incoming user is already logged in.
synchronized(this){
invalidateExistingSessionOfCurrentUser(request, studentname, testcode);
testtakers = dataAccessor.getTesttakersByResumeKey(studentname, login);// Adding this code to call getTesttakersByResumeKey instead of getTesttakers to improve the performance of the application during student login
}
} catch (Exception e) {
log.error("Exception when calling getTesttakers");
CaslsUtils.outputLoggingData(log_, request);
throw e;
}
session = request.getSession();
if(testtakers!=null)
{
if(testtakers.size() == 0) {
// new student -> start fresh
log_.debug("starting a fresh test");
// if this is a demo test, skip the consent pages and dump them directly to the select test page
if (login.getTestengine().equals(Itemmaster.TESTENGINE_DEMO)) {
return mapping.findForward("continue-panel");
}
}
// send them to fill out the profile
// check for custom profiles
String[] surveynames = new String[4];
List<Logingroup> logingroups = dataAccessor.getLoginGroupsByLogin(login.getLoginid());
for(Logingroup logingroup : logingroups) {
Groupmaster group = logingroup.getGroupmaster();
log_.debug(String.format("group: {groupid: %d, grouptype: %s, groupname: %s}", new Object[] {group.getGroupid(), group.getGrouptype(), group.getName()}));
Set<Groupsurvey> surveys = group.getGroupsurveys();
if(surveys.size() > 0) {
// grab the first (and only) one
Groupsurvey survey = surveys.toArray(new Groupsurvey[0])[0];
if(group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_CLASS)) {
surveynames[0] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_SCHOOL)){
surveynames[1] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_DISTRICT)){
surveynames[2] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_STATE)){
surveynames[3] = survey.getSurveyname();
}
}
}
// match the most grandular survey
for(int i=0; i < surveynames.length; ++i) {
if(surveynames[i] != null) {
saveToken(request);
return mapping.findForward("student-profile-"+surveynames[i]);
}
}
// no custom profile, send them to the default
saveToken(request);
return mapping.findForward("student-profile");
}
// get the set of availible panels
Set<Panel> availiblePanels = dataAccessor.getAvailiblePanels(login, studentname);
if(availiblePanels.size() == 0) {
// no panels availible. send to all done!
log_.debug(String.format("No panels availible for Login:%s with resumekey:%s", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
//Eventum #427 - Prevent test takers from retaking a finished test.
TestSubjectResult testSubjecResult=dataAccessor.getTestSubjectResult(login, resumekey);
if(testSubjecResult != null){
if(testSubjecResult.getRdscore() != null && testSubjecResult.getWrscore() != null && testSubjecResult.getLsscore() != null && testSubjecResult.getOlscore() != null){
if(testSubjecResult.getRdscore().getFinishtime() != null && testSubjecResult.getWrscore().getFinishtime() != null && testSubjecResult.getLsscore().getFinishtime() != null && testSubjecResult.getOlscore().getFinishtime() != null){
log_.debug(String.format("Already completed all the Skill Tests.", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
}
}
// get a list of resumeable testtakers
List<Testtaker> resumeableTesttakers = new ArrayList<Testtaker>();
for(Testtaker testtaker : testtakers) {
if(testtaker.getPhase().equals(ConstantLibrary.PHASE_GOODBYE)) {
// testtaker is done with test. skip.
continue;
}
if(testtaker.getCurrentpanelid() == null) {
// testtaker is the profile testtaker
continue;
}
resumeableTesttakers.add(testtaker);
}
// sort them from least recent to latest
Collections.sort(resumeableTesttakers, new Comparator<Testtaker>() {
#Override
public int compare(Testtaker o1, Testtaker o2) {
// TODO Auto-generated method stub
//return 0;
return new CompareToBuilder()
.append(o1.getLasttouched(), o2.getLasttouched())
.toComparison();
}
});
if(resumeableTesttakers.size() == 0 && availiblePanels.size() > 0) {
// nobody is resumeable but there are panels left to take
// send them to the panel choice
// TODO: This is probably a misuse of Struts.
log_.info("No resumeable testtakers. Sending to panel select");
saveToken(request);
ActionForward myForward = (new ActionForward("/do/capstartpanel?capStartPanelAction=retest&lasttesttakerid="
+ testtakers.get(0).getTesttakerid(), true));
return myForward;// mapping.findForward(ConstantLibrary.FWD_CONTINUE + "-panel");
} else {
// grab the one most recently created and take their test
log_.info(String.format("Resuming with choice of %d testtakers", resumeableTesttakers.size()));
// we're forwarding to resume at this point, so we should do the some of the initialization
// that would have happened if we were still using getTesttaker() instead of getTesttakers() above.
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_TESTTAKER, resumeableTesttakers.get(resumeableTesttakers.size()-1));
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_RESUME);
}
}
It's not a worth changing multiple returns to a single return statement per method. Actually, that will unnecessarily increase the burden of storing the result in a local variable and then making the return finally,
ActionForward result = null;
//scenario 1
result = ...
//scenario 2
result = ...
//scenario 3
result = ...
//finally
return result;
Hope this helps, but, it doesn't make much sense to me
As pointed out by others, having a single return statement does not necessarily make your code cleaner. However, in this case splitting up the method in smaller pieces probably makes the code more readable.
For example, this part:
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
could be replaced by introducing two methods and using those to write:
If(tokenNotSet() || formHasErrors()){
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
By doing this on multiple places the structure of the algorithm becomes more clear, possibly giving you more insight in how this code could be refactored to adhere to your coding guidelines.
I would set a an action forward variable at the start of the method.
ActionForward actionForwardToReturn = null;
Then replace each of these two lines
return mapping.getInputForward();
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
with these two lines :
actionForwardToReturn = mapping.getInputForward()
actionForwardToReturn = mapping.findForward(ConstantLibrary.FWD_CONTINUE);
finally return the variable.
return actionForwardToReturn;
This shouldn't be too difficult :)
On a side note... (actually the orginal answer to the question) :
Multiple return statements can make it hard to debug code.
I personally would have just one action object that you return at the end of the method. The benefit of this, is that i can put a break point right on the return statement and look at exactly what that object is.
Any logging or other cross cutting concern I would want to add later, would only have to be done at one point. Otherwise I would have to add a log statement to every line where you are returning.
The complexity added to a method in an attempt to remove multiple return statements is many a times not worth it, especially in a method such as yours.There's nothing wrong with using them in this case.
Like user3580294 there's nothing wrong with multiple return statements. However you could combine the last two if statements since they are essentially returning the same thing.
Use #Octopus 's method if you absolutely have to have one return statement

Login jframe password control with text file

I have a login frame, That has two different login mode, "User" and "Admin".
My problem is in admin mode (when select admin from jcombobox),
When i select admin, my first textfield should fill with "Administration" automatically and did, And in my jpasswordfiled, It should search it's password number from text file (that is 2).
But, Not accept in admin mode:
public class LoginFrame extends javax.swing.JFrame implements ActionListener {
private String username;
private char[] Password;
...
private void LoginButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
username = String.valueOf(jTextField1.getText());
Password = jPasswordField1.getPassword();
if (jComboBox1.getSelectedIndex() == 2) {
if (adminCanGoNext2()) {
goAdminMainPage(); // Execute work
} else {
ErrorMessageLabel.setText("Did Not Match");
}
}
} catch (Exception e) {
ErrorMessageLabel.setText("Enter Correct Input");
}
public boolean adminCanGoNext2() throws IOException {
FileReader fr = new FileReader("LoginInformation.txt");
BufferedReader br = new BufferedReader(fr);
String line;
while( (line = br.readLine())!= null ){
if(line.startsWith("Admin")){
char[] charedPass=line.toCharArray(); // char password that read from file
System.out.println("readed password is: "+ charedPass.toString());
if(Arrays.equals(charedPass, Password)){
return true;
}
}
}
return false;
}
public void goAdminMainPage() {
System.out.println("Go ");
}
...
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jComboBox1) {
if (jComboBox1.getSelectedIndex() == 2) {
jTextField1.setText("Administration");
}
}
}
}
Login Information.txt file:
Admin 2
271 tes tt Male 2013/05/30
458 tttt uuuu Female 2013/05/30
Now, When i select admin mode, my jtextfield1 text is "Administration" perfectly,
But when i try number "2" for passwordfield, and clicked to login button, make no change!
You are comparing a String with a character array (and they are always found non-equal obviously).
You have to convert the password read from the file into a character array using toCharArray() and then compare the resulting array with the character array returned by JPasswordFields gePassword() method. For easy comparing of arrays you can use the utility methods of java.util.Arrays.
See, also, this short demo.
EDIT:
Please note, that storing passwords in String variables is not advisable due to security concerns. (Of course storing passwords in files in clear-text is probably an even greater security risk.)
The "How to Use Password Fields" section of the Java Tutorials might be a good source of info and directions to get you started.

Categories