In my opinion, when dealing with a text file you want to always make sure you are actually processing a data line especially if your app is not responsible for creating the text file. You should also always be aware of the fact that the data line may not contain all the required data so as to eliminate the possibility of encountering a ArrayIndexOutOfBoundsException when utilizing the String.split() method.
You may also want to allow for a mechanism to handle comment lines within the text file so that some can be added. These lines would of course be ignored as would blank lines. In this case the text file path and file name is hard coded within the method but if the file was to be User selectable via a JFileChooser (or whatever) it would be good if the very first line of the file was a comment line indicating what the file is for, for example:
;MyAppName Login Data
;Real Name, Login Name, Password
John Doe, johnnyboy, cGFzczEyMzQ
Bill Smith, BoperBill, U3VwZXJDb29sMQ
Tracey Johnson, tracey, NzcyMzQ2Ng
Fred Flinstone, PebblesDaddy, V2lsbWEnc19EdWRl
In the example file layout above, lines that start with a semi-colon (;) are considered comment lines. The very first comment is the File Descriptor. When the file is read then this line is checked and if it states what is expected then you know for a fact that it is most likely a correct text file to process otherwise the User supplied or selected a wrong text file.
You will notice that the passwords are encrypted. Not even you should know what they are. Passwords are private to the User only. A simple Base64 Encryption is used here (Java 8+ required) but only for example purposes. It may be good enough for a some applications but definitely not for all, but still, something is better than nothing at all.
To encrypt a password in Base64 in your case you might use (import java.util.Base64 required):
String password = Base64.getEncoder().withoutPadding().
encodeToString(String.valueOf(txfPassword.
getPassword()).getBytes());
Do this before saving the User Password to file.
Here is how your checkLogin() method might look:
public void checkLogin() throws FileNotFoundException, IOException {
// Try with Resources...This will auto-close the BufferReader.
try (BufferedReader br = new BufferedReader(new FileReader("D:\\Login.txt"))) {
// Install code here to validate that txfUsername and txfPassword
// text boxes actually contain something. Exit method if not.
// ................................
String userName = txfUsername.getText();
// Encrypt supplied password and compare to what is in file
String password = Base64.getEncoder().withoutPadding().encodeToString(String.valueOf(txfPassword.getPassword()).getBytes());
if (userName.equals("") || password.equals("")) {
return;
}
String line;
int lineCounter = 0;
boolean loginSuccess = false;
while ((line = br.readLine().trim()) != null) {
lineCounter++;
// Is this the right data file?
if (lineCounter == 1 && !line.equals(";MyAppName Login Data")) {
JOptionPane.showMessageDialog(this, "Wrong Text File Supplied!",
"Invalid Data File", JOptionPane.WARNING_MESSAGE);
return;
}
// Skip blank and comment lines...
if (line.equals("") || line.startsWith(";")) { continue; }
// Split the comma/space delimited data line (", ")
String[] lineSplit = line.split(",\\s+"); // \\s+ means 1 or more spaces
// make sure we have three array elements
if (lineSplit.length == 3 && userName.equals(lineSplit[1]) && password.equals(lineSplit[2])) {
loginSuccess = true;
JFrame frame = new JFrame();
menu = new MainMenu(lineSplit[0]);
this.setVisible(false);
menu.setVisible(true);
break;
}
}
// Can't find login name or password in file.
if (!loginSuccess) {
JOptionPane.showMessageDialog(this, "Invalid User Name or Password!",
"Invalid Login", JOptionPane.WARNING_MESSAGE);
}
}
}