I've been trying for a week to make it work but I can not find anything good to help me solve the problem.
I try to make an ATM program, the connection with the database is working but I don't know how to check if what I introduced in the program username and password are the same as what I have in the database, after this is checked I want it to send me a message " Success " and to pop up a new window.
For now is just displaying what I have in the database.
I am sorry if I ask for to much but I am a beginner.
Here is the main code:
import java.beans.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JSeparator;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ProgramBanca2 extends JFrame {
/**
*
*/
private static final long serialVersionUID = -7748785395531780446L;
public static void main(String[] args) {
String jdbcURL = "jdbc:postgresql://localhost:5432/Banca2";
String username = "postgres";
String password = "postgres";
try {
Connection connection = DriverManager.getConnection(jdbcURL, username, password);
System.out.print("Connected to postgres");
ProgramBanca2 window = new ProgramBanca2();
window.setVisible(true);
window.setBounds(200, 200, 450, 400);
String sql = "Select * from login";
java.sql.Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery(sql);
while (result.next()) {
int id = result.getInt("id");
String nume = result.getString("name");
int parola = result.getInt("password");
System.out.printf(" %s - %d\n ", nume, parola);
}
}
connection.close();
}catch (SQLException e){
System.out.print("Cannot connect to postgres");
e.printStackTrace();
}
}
Here is the design:
private JTextField parola;
private JTextField nume;
public ProgramBanca2() {
getContentPane().setBackground(new Color(0, 206, 209));
setBackground(new Color(0, 206, 209));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
setResizable(false);
parola = new JTextField();
parola.setFont(new Font("Sitka Subheading", Font.PLAIN, 18));
parola.setBounds(141, 159, 211, 46);
getContentPane().add(parola);
parola.setColumns(10);
JLabel lblNewLabel = new JLabel("Parola");
lblNewLabel.setFont(new Font("Sitka Small", Font.BOLD, 17));
lblNewLabel.setBounds(15, 156, 130, 50);
getContentPane().add(lblNewLabel);
JLabel lblNewLabel_1 = new JLabel("Nume");
lblNewLabel_1.setFont(new Font("Sitka Small", Font.BOLD, 17));
lblNewLabel_1.setBounds(15, 79, 130, 50);
getContentPane().add(lblNewLabel_1);
nume = new JTextField();
nume.setFont(new Font("Sitka Subheading", Font.PLAIN, 18));
nume.setBounds(141, 82, 211, 46);
getContentPane().add(nume);
nume.setColumns(10);
JButton btnNewButton = new JButton("Login");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnNewButton.setFont(new Font("Sitka Small", Font.PLAIN, 15));
btnNewButton.setBounds(10, 238, 155, 100);
getContentPane().add(btnNewButton);
JButton btnNewButton_1 = new JButton("Reset");
btnNewButton_1.setFont(new Font("Sitka Small", Font.PLAIN, 15));
btnNewButton_1.setBounds(245, 238, 141, 100);
getContentPane().add(btnNewButton_1);
JSeparator separator = new JSeparator();
separator.setBounds(10, 215, 376, 2);
getContentPane().add(separator);
JSeparator separator_1 = new JSeparator();
separator_1.setBounds(15, 65, 376, 2);
getContentPane().add(separator_1);
}
}
CodePudding user response:
So, the core problem is, you're still thinking in a procedural manner, C
follows B
which follows A
, where as most GUIs work in a "event driven" manner, something happens and then you respond to it.
What I mean is, currently you're doing:
- Show window
- Authenticate user
There's no opportunity for the user to input there details before you attempt to authenticate the credentials.
Instead, you need to take a step back and understand how Swing/GUIs work:
It also wouldn't hurt to have and understanding of:
- Observer Pattern
- Delegation; delegation
- Dependency injection (which is also a form of delegation)
- Model-View-Controller (which supports Single Responsibility Principle)
Let's start with some delegation. The login view doesn't care "how" the user is authenticated, all it should care about is, when it needs to, it can request that the user credentials can be authenticated and if they are correct, it will get a some kind of "user" representation back, or an error, for example...
public interface User {
public String getUserName();
}
public interface AuthentationDelegate {
public User authenticateUser(String userName, char[] password) throws Exception;
}
Nice and simple.
Now we have that, we can have a look at the login view...
public class LoginPane extends JPanel {
public interface Observer {
public void didLoginUser(LoginPane source, User user);
public void didCancelLogin(LoginPane source);
}
private JTextField userNameField;
private JPasswordField passwordField;
public LoginPane(Observer observer, AuthentationDelegate authentationDelegate) {
setLayout(new GridBagLayout());
userNameField = new JTextField(10);
passwordField = new JPasswordField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = gbc.LINE_END;
add(new JLabel("User name:"), gbc);
gbc.gridy ;
add(new JLabel("Password:"), gbc);
gbc.gridx ;
gbc.gridy = 0;
gbc.anchor = gbc.LINE_START;
add(userNameField, gbc);
gbc.gridy ;
add(passwordField, gbc);
JPanel actionPanel = new JPanel(new GridLayout(1, 2));
JButton loginButton = new JButton("Login");
JButton cancelButton = new JButton("Cancel");
actionPanel.add(loginButton);
actionPanel.add(cancelButton);
gbc.gridy ;
gbc.gridx = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = gbc.CENTER;
add(actionPanel, gbc);
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
User user = authentationDelegate.authenticateUser(userNameField.getText(), passwordField.getPassword());
if (user != null) {
observer.didLoginUser(LoginPane.this, user);
} else {
JOptionPane.showMessageDialog(LoginPane.this, "Failed to authenticate user", "Error", JOptionPane.ERROR_MESSAGE);
}
} catch (Exception exp) {
JOptionPane.showMessageDialog(LoginPane.this, "Failed to authenticate user", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
observer.didCancelLogin(LoginPane.this);
}
});
}
}
This is pretty basic, it presents fields for the user name and password and when the Login button is clicked, it will attempt to authenticate the user details, via the delegate.
It also provides an observer callback to notify the presenter that some state has changed and that they might like to take some kind of action.
Okay, now lets move onto actually implementing the authentication workflow...
// You probably want to fill this out with some details
// from the database properties
public class DefaultUser implements User {
private String username;
public DefaultUser(String username) {
this.username = username;
}
@Override
public String getUserName() {
return username;
}
}
public class SQLAuthentationDelegate implements AuthentationDelegate {
private Connection connection;
public SQLAuthentationDelegate(Connection connection) {
this.connection = connection;
}
@Override
public User authenticateUser(String userName, char[] password) throws Exception {
try (PreparedStatement stmt = connection.prepareStatement("select * from login where username = ? and password = ?")) {
stmt.setString(1, userName);
stmt.setString(2, new String(password));
try (ResultSet rs = stmt.executeQuery()) {
// It should only have one result
if (rs.next()) {
// I don't know, load some properties which
// are important, like the record key or something
// maybe the display name or other important information
return new DefaultUser(userName);
}
}
}
return null;
}
}
So, this whole classes responsibility is to do just one thing, authenticate the user credentials, it's pretty basic and you'll need to fill it out, but it gives you bit of an idea of how it would work, oh, and you should look at Using Prepared Statements, oh, and you probably also want to take a look at something like Introduction to SQL as well.
And now, let's put it together...
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// Make you connection here...
Connection connection = null;
JFrame frame = new JFrame();
frame.add(new LoginPane(new LoginPane.Observer() {
@Override
public void didLoginUser(LoginPane source, User user) {
// User was authenticated, do something
}
@Override
public void didCancelLogin(LoginPane source) {
SwingUtilities.windowForComponent(source).dispose();
}
}, new SQLAuthentationDelegate(connection)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
But why (go to all this effort)?
Because, in the long run, it's going to make your life easier, for example, when I was testing the interactions of the UI, I created a simple AuthentationDelegate
and with one line change, I was able to switch the workflow, for example...
public class DefaultAuthentationDelegate implements AuthentationDelegate {
@Override
public User authenticateUser(String userName, char[] password) throws Exception {
return new DefaultUser(userName);
}
}
and
JFrame frame = new JFrame();
frame.add(new LoginPane(new LoginPane.Observer() {
@Override
public void didLoginUser(LoginPane source, User user) {
// User was authenticated, do something
JOptionPane.showMessageDialog(null, "All your money is belong to us", "Welcome", JOptionPane.PLAIN_MESSAGE);
SwingUtilities.windowForComponent(source).dispose();
}
@Override
public void didCancelLogin(LoginPane source) {
SwingUtilities.windowForComponent(source).dispose();
}
}, new DefaultAuthentationDelegate()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
and the rest of the code will just continue to work
Runnable example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import java.sql.*;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// Make you connection here...
Connection connection = null;
JFrame frame = new JFrame();
frame.add(new LoginPane(new LoginPane.Observer() {
@Override
public void didLoginUser(LoginPane source, User user) {
// User was authenticated, do something
JOptionPane.showMessageDialog(null, "All your money is belong to us", "Welcome", JOptionPane.PLAIN_MESSAGE);
SwingUtilities.windowForComponent(source).dispose();
}
@Override
public void didCancelLogin(LoginPane source) {
SwingUtilities.windowForComponent(source).dispose();
}
}, new SQLAuthentationDelegate(connection)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface User {
public String getUserName();
}
public interface AuthentationDelegate {
public User authenticateUser(String userName, char[] password) throws Exception;
}
// You probably want to fill this out with some details
// from the database properties
public class DefaultUser implements User {
private String username;
public DefaultUser(String username) {
this.username = username;
}
@Override
public String getUserName() {
return username;
}
}
public class DefaultAuthentationDelegate implements AuthentationDelegate {
@Override
public User authenticateUser(String userName, char[] password) throws Exception {
return new DefaultUser(userName);
}
}
public class SQLAuthentationDelegate implements AuthentationDelegate {
private Connection connection;
public SQLAuthentationDelegate(Connection connection) {
this.connection = connection;
}
@Override
public User authenticateUser(String userName, char[] password) throws Exception {
try (PreparedStatement stmt = connection.prepareStatement("select * from login where username = ? and password = ?")) {
stmt.setString(1, userName);
stmt.setString(2, new String(password));
try (ResultSet rs = stmt.executeQuery()) {
// It should only have one result
if (rs.next()) {
// I don't know, load some properties which
// are important, like the record key or something
// maybe the display name or other important information
return new DefaultUser(userName);
}
}
}
return null;
}
}
public class LoginPane extends JPanel {
public interface Observer {
public void didLoginUser(LoginPane source, User user);
public void didCancelLogin(LoginPane source);
}
private JTextField userNameField;
private JPasswordField passwordField;
public LoginPane(Observer observer, AuthentationDelegate authentationDelegate) {
setLayout(new GridBagLayout());
userNameField = new JTextField(10);
passwordField = new JPasswordField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = gbc.LINE_END;
add(new JLabel("User name:"), gbc);
gbc.gridy ;
add(new JLabel("Password:"), gbc);
gbc.gridx ;
gbc.gridy = 0;
gbc.anchor = gbc.LINE_START;
add(userNameField, gbc);
gbc.gridy ;
add(passwordField, gbc);
JPanel actionPanel = new JPanel(new GridLayout(1, 2));
JButton loginButton = new JButton("Login");
JButton cancelButton = new JButton("Cancel");
actionPanel.add(loginButton);
actionPanel.add(cancelButton);
gbc.gridy ;
gbc.gridx = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = gbc.CENTER;
add(actionPanel, gbc);
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
User user = authentationDelegate.authenticateUser(userNameField.getText(), passwordField.getPassword());
if (user != null) {
observer.didLoginUser(LoginPane.this, user);
} else {
JOptionPane.showMessageDialog(LoginPane.this, "Failed to authenticate user", "Error", JOptionPane.ERROR_MESSAGE);
}
} catch (Exception exp) {
JOptionPane.showMessageDialog(LoginPane.this, "Failed to authenticate user", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
observer.didCancelLogin(LoginPane.this);
}
});
}
}
}