2

So I started create this project for my PAT Grade 12 task and I hit a speedbump... I have a login screen, using a jFrame, in netbeans. My issue is, that I am using 2 text files to store the data: 1 for usernames and 1 for passwords. They are read in using a Scanner and are being delimited with a #. The point is, I validate the Username using a while loop, but i am unable to validate the password that correspond with that username in the other text file.

So you can imagine 2 text files:

  • Username
  • Password

When the 'Login' button is clicked, it uses a while loop to check to see if username already exists. If it does, continue to the Password, else "Username does not exist". The problem comes in when matching the Password, in the same position, in the other text file.

If anybody can help me, it would make my week and save my project. Please understand that Netbeans only lets you edit certain areas of code. I try my best to keep my code clean and understandable.

Many Thanks, SnowyTheVampire

package Battlefield4;
import javax.swing.*;
import java.util.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Login extends javax.swing.JFrame
{

String Username;
String Password;

public Login()
{
    initComponents();
}
             //Can not edit from here on      
private void initComponents() {

    txtUsername = new javax.swing.JTextField();
    txtPassword = new javax.swing.JTextField();
    lblPassword = new javax.swing.JLabel();
    lblUsername = new javax.swing.JLabel();
    btnLogin = new javax.swing.JButton();
    btnCreate = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setSize(new java.awt.Dimension(854, 480));
    getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
    getContentPane().add(txtUsername, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 150, 210, -1));
    getContentPane().add(txtPassword, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 220, 210, -1));

    lblPassword.setText("Password");
    getContentPane().add(lblPassword, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 200, -1, -1));

    lblUsername.setText("Username");
    getContentPane().add(lblUsername, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 130, -1, -1));

    btnLogin.setText("Login");
    btnLogin.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnLoginActionPerformed(evt);
        }
    });
    getContentPane().add(btnLogin, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 290, -1, -1));

    btnCreate.setText("Create");
    btnCreate.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            btnCreateActionPerformed(evt);
        }
    });
    getContentPane().add(btnCreate, new org.netbeans.lib.awtextra.AbsoluteConstraints(460, 290, -1, -1));

    jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Battlefield4/Batfield/Background/Login (Small).jpg"))); // NOI18N
    jLabel1.setText("jLabel1");
    getContentPane().add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 860, 480));

    pack();
}                        
//Can not edit before this
private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {                                         
    //This is from where Netbeans lets you edit your code.
    try {
        File user = new File("C:\\Users\\John1012\\Documents\\NetBeansProjects\\PATProject\\src\\Battlefield4\\Batfield\\Users\\Username.txt"); //To create a universal file for Input & Output
        File pass = new File("C:\\Users\\John1012\\Documents\\NetBeansProjects\\PATProject\\src\\Battlefield4\\Batfield\\Users\\Password.txt"); //To create a universal file for Input & Output
        user.getParentFile().mkdirs(); //To denote the parent file
        pass.getParentFile().mkdirs(); //To denote the parent file
        Scanner scUser = new Scanner(user).useDelimiter("#"); //To scan the Username file
        Scanner scPass = new Scanner(pass).useDelimiter("#");
        Username = txtUsername.getText(); //This gets the user input
        Password = txtPassword.getText(); //This gets the user input
        int pos = 0; //Indicates the position of the Username in the save file

        while(scUser.hasNext())
        {
            pos = pos + 1;

            if(scUser.equals(Username))
            { //This is where it fails
                for (int i = 0; i <= 5; i++)
                {
                    while(scPass.hasNext())
                    {
                        System.out.print(scPass);
                    }
                }

                if(scPass.equals(Password))
                {
                    new Selection().setVisible(true);
                    this.dispose();
                }
                else
                {
                   JOptionPane.showMessageDialog(null,"Incorrect Password!");
                }
            }//This is where it works from. The above code is sketchy
            else
            {
                JOptionPane.showMessageDialog(null,"User Does Not Exist!");
            }
            scUser.close();
        }
    }
    catch (FileNotFoundException ex)
    {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (IOException ex)
    {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }

}                                        

private void btnCreateActionPerformed(java.awt.event.ActionEvent evt) {                                          
   //Again this is from where Netbeans lets you edit
    try {
        File user = new File("C:\\Users\\John1012\\Documents\\NetBeansProjects\\PATProject\\src\\Battlefield4\\Batfield\\Users\\Username.txt"); //To create a universal file for Input & Output
        File pass = new File("C:\\Users\\John1012\\Documents\\NetBeansProjects\\PATProject\\src\\Battlefield4\\Batfield\\Users\\Password.txt"); //To create a universal file for Input & Output
        user.getParentFile().mkdirs(); //To denote the parent file
        pass.getParentFile().mkdirs(); //To denote the parent file
        Scanner scUser = new Scanner(user); //To scan the Username file
        Username = txtUsername.getText(); //This gets the user input
        Password = txtPassword.getText(); //This gets the user input

        if(scUser.nextLine().contains(Username)) //This reads the entire line and checks for an indexOf of those characters
        {
            JOptionPane.showMessageDialog(null,"User Already Exists!");
            scUser.close(); //Close the Scanner
        }
        else
        {
            scUser.close(); //Close the Scanner
            if("".equals(Password) || " ".equals(Password)) //Checks to see whether or not the user entered a password
            {
                JOptionPane.showMessageDialog(null,"Please Enter A Password!");
            }
            else
            {
               PrintWriter pwUser = new PrintWriter(new FileWriter(user,true)); //To Write to the Username file
               PrintWriter pwPass = new PrintWriter(new FileWriter(pass,true)); //To Write to the Password file
               pwUser.print(Username + "#");
               pwPass.print(Password + "#");
               pwUser.close();
               pwPass.close();

               new Selection().setVisible(true);
               this.dispose();
            }
        }
        scUser.close();
    }
    catch (FileNotFoundException ex)
    {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (IOException ex)
    {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }

}                                         
 //Can no longer edit here
 public static void main(String args[]) {

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Login().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JButton btnCreate;
private javax.swing.JButton btnLogin;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel lblPassword;
private javax.swing.JLabel lblUsername;
private javax.swing.JTextField txtPassword;
private javax.swing.JTextField txtUsername;
// End of variables declaration                   
}
  • Just use one textfile, write both username and password into one line and delimit them with a special character. – Tobi Oct 05 '15 at 19:23
  • What have you tried so far ? Please copy-paste some code, showing where you think it fails – Benoît Oct 05 '15 at 19:24
  • 1
    @Benoît not only `some code` but an [MCVE](http://stackoverflow.com/help/mcve) might be the best option. BTW why are you using 2 text files instead of saving them in a single one with the same `#` to delimit username and password and then retrieving information and using `split("#")` to get data into username and password variables? – Frakcool Oct 05 '15 at 19:26
  • Again check the link I provided and post an [MCVE](http://stackoverflow.com/help/mcve) not only a piece of code. – Frakcool Oct 05 '15 at 20:03
  • The reason I don't use a single text file is due to the fact that i need a 'create' option. I'm not sure which is the better option as I run into problems either way – SnowyTheVampire Oct 05 '15 at 20:05
  • what is the problem with the create option?! – Tobi Oct 05 '15 at 20:13
  • There is no issue with the create option. Works amazingly. Its the login option - need to read the password scanner and get the corresponding position of the username. – SnowyTheVampire Oct 05 '15 at 20:16
  • you can have a create option and a single text file there is no problem. to Read the password to the corresponding username you need a key. So why don't you write username:password#nextusername:nextpassword into your textfile? – Tobi Oct 05 '15 at 20:19
  • 1
    BTW: please read something about clean code. use imports, Constants, correct java conventions (lowercase varnames, brackets, member sorting, ...) – Tobi Oct 05 '15 at 20:21
  • Thanks @Tobi, I will try that out. Copied straight from netbeans, that's how it designs the code. Try to keep my code as clean as possible. Not entirely sure where i went wrong with the conventions though – SnowyTheVampire Oct 05 '15 at 20:43
  • @Tobi if I were to use the "username:password#nextusername:nextpassword" idea in a single text file. How would I delimit that correctly to Scan/extract the one after the other? – SnowyTheVampire Oct 05 '15 at 20:51
  • @SnowyTheVampire related to [Naming Conventions](http://www.oracle.com/technetwork/java/codeconventions-135099.html): `Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. `. – Frakcool Oct 05 '15 at 21:09
  • Possible duplicate of [How can I add a login screen to an existing Java Swing program?](http://stackoverflow.com/questions/15908275/how-can-i-add-a-login-screen-to-an-existing-java-swing-program) – Frakcool Oct 05 '15 at 21:12
  • Also see: [Our first window; Login example](http://www.edu4java.com/en/swing/swing3.html) – Frakcool Oct 05 '15 at 21:13
  • Hi @Frakcool, I looked over all the links that you sent me. Neither of the two has been able to solve my problem. The 'How can i add a login screen to an existing Java Swing program" was very similar, but did not read in from any file... I will look over my naming convenstions, but that won't be my top priority until this program is done. Many thanks, John – SnowyTheVampire Oct 06 '15 at 14:21
  • @SnowyTheVampire my name isn't "John" why do you add a signature as if this was an e-mail? If you want us to know your name is "John" then change your username to "John" else, you're SnowyTheVampire for us. Now for reading from a file [Take a look at this awesome article found on Google](http://stackoverflow.com/questions/4716503/best-way-to-read-a-text-file-in-java) which includes more links. Check them out :) – Frakcool Oct 06 '15 at 14:51
  • Geez dude. Its just called being polite. If people here have an issue with me trying to be formal, then people may need to rethink how they interact with others xD Adding "John" as a formal signature is a pretext to give others the idea of openness and willingness. If you dislike how I write, then I apologize, but I will not change my scholarly writing style, due to the fact that I have a username xD It shows that I am able to speak to others freely, whilst still staying formal and I honestly don't feel bound to my sobriquet. On that note, thank you for your help – SnowyTheVampire Oct 07 '15 at 17:18

2 Answers2

1

Map all users on startup and then just check the map. Use split to separate the username and password. Check that the inputs are not empty before calling onLoginCorrect()

private static final Logger LOG = LogManager.getLogger();
private final Map<String, String> users = new ConcurrentHashMap<>();

public Login() {
    super();
    final InputStream resource = this.getClass().getResourceAsStream("/users.txt");
    final Scanner scanner = new Scanner(resource);
    while (scanner.hasNext()) {
        final String input = scanner.nextLine();
        final String[] userPw = StringUtils.split(input, ':');
        this.users.put(userPw[0], userPw[1]);
    }
    scanner.close();
    IOUtils.closeQuietly(resource);
}

public boolean  isLoginCorrect(final String username,final String password) {
    final boolean result;
    if (StringUtils.equals(this.users.get(username), password)) {
        result = true;
    } else {
        Login.LOG.warn("No such user");
        result = false;
    }
    return result;
}
Tobi
  • 874
  • 1
  • 9
  • 36
0

So I figured out how to do it. Thanks everyone for the help!

I am posting this as a simpler method to @Tobi in hopes to help people that aren't as advanced or need simpler help!

private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {                                         

    try {
        File user = new File("src\\Battlefield4\\Batfield\\Users\\Username.txt"); //To create a universal file for Input & Output
        File pass = new File("src\\Battlefield4\\Batfield\\Users\\Password.txt"); //To create a universal file for Input & Output
        user.getParentFile().mkdirs(); //To denote the parent file
        pass.getParentFile().mkdirs(); //To denote the parent file
        Scanner scUser = new Scanner(user).useDelimiter("#"); //To scan the Username file
        Scanner scPass = new Scanner(pass).useDelimiter("#"); //To scan the password file
        username = txtUsername.getText(); //This gets the user input
        password = txtPassword.getText(); //This gets the user input
        int pos = 0; //Indicates the position of the Username in the save file
        boolean loggedIn = false; //Flag to check if it's logged in

        while(scUser.hasNext() && scPass.hasNext()) //Runs files in congruency
        {
            if(scUser.next().equalsIgnoreCase(username) && scPass.next().equals(password))
            {
                loggedIn = true;
                scUser.close();
                scPass.close();
                new Selection(username).setVisible(true);
                this.dispose();
                break;
            }
        }
        scUser.close();
        scPass.close();
        if(loggedIn == false)
        {
            JOptionPane.showMessageDialog(null,"Incorrect Username or Password!");
        }

    }
    catch (FileNotFoundException ex)
    {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }

}