4
\$\begingroup\$

In GUI that provided with the right username and password lets you open up an address book like GUI where you have crud like operations. I'm still very inexperienced with swing facilities especially with layout managers and placing my components on a panel/frame. I'd like some feedback about how to properly structure these GUI type programs and/or better ways of designing these types of programs.

The program opens up a connection to the MySQL database where a previously made table is being accessed. Then compares against the values of the table and actions are decided from there.

Log-In GUI:

import javax.swing.*;
import javax.swing.SpringLayout.Constraints;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.sql.*;

public class Login implements ActionListener{

    //declare instance variables
    private JFrame frame;
    Container pane;
    JPanel Master, centerInfo, buttonInfo;
    JLabel jlb_username, jlb_password, jlb_email;
    JTextField jtf_username,jtf_email;
    JPasswordField jtf_password;
    JButton jb_login, jb_signup;
    Connection conn;
    private String username, password;


    public void init_connection(){
        //open connection to database
    try
    {conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/world", "root", "root");
    } catch(SQLException ex) { System.err.println(ex); }
}


    public void start_gui(){
        //setup frame, pane, and panels. put panels into pane
        frame = new JFrame("Login to Client");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pane = new Container();
        pane = frame.getContentPane();
        Master = new JPanel();
        centerInfo = new JPanel(new GridBagLayout());
        buttonInfo = new JPanel(new FlowLayout(FlowLayout.LEADING,10,5));
        Master.add(centerInfo, BorderLayout.CENTER);
        Master.add(buttonInfo, BorderLayout.SOUTH);
        pane.add(Master);
        laycomponents();
        frame.setSize(300, 150);
        frame.setVisible(true);
    }


    private void laycomponents(){
        //put components in panels: two labels, two textfields, two buttons
        //create constraints
        GridBagConstraints topComponents = new GridBagConstraints();
        GridBagConstraints centerComponents = new GridBagConstraints();

        //initialize
        jlb_username = new JLabel("Username");
        jlb_password = new JLabel("Password");
        jtf_username = new JTextField(15);
        jtf_password = new JPasswordField(15);
        jb_login     = new JButton("Login");
        jb_signup    = new JButton("Sign up");

        //insert into panels
        topComponents.insets = new Insets(50,5,5,5);    //username components
        topComponents.gridx = 0;
        topComponents.gridy = 2;
        centerInfo.add(jlb_username, centerComponents);
        topComponents.gridx = 1;
        topComponents.gridy = 2;
        centerInfo.add(jtf_username, centerComponents);
        centerComponents.insets = new Insets(10,10,10,10);  //password components
        centerComponents.gridx = 0;
        centerComponents.gridy = 3;
        centerInfo.add(jlb_password, centerComponents);
        centerComponents.gridx = 1;
        centerComponents.gridy = 3;
        centerInfo.add(jtf_password, centerComponents);
        buttonInfo.add(jb_login);
        buttonInfo.add(jb_signup);

        //add action listener

        jb_login.addActionListener(this);
        jb_signup.addActionListener(this);
        jtf_username.addActionListener(this);
        jtf_password.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        username = jtf_username.getText();
        password = new String(jtf_password.getPassword());
        if(e.getSource() == jb_login)
        {
            checkforLogin();
        }
        else if(e.getSource() == jb_signup)
        {
            //
        }


    }

    private void checkforLogin()
    {
        try
        {
            String instr = "SELECT *FROM login_info WHERE username = ? AND password = ?";
            PreparedStatement ps = conn.prepareStatement(instr);
            ps.setString(1, username);
            ps.setString(2, password);
            System.out.println(username + " " + password);
            ResultSet rset = ps.executeQuery();
            if(!rset.next()) JOptionPane.showMessageDialog(frame, "Incorrect username or password, please try again","Access Error",JOptionPane.ERROR_MESSAGE);
            else startAddressBook();

        }catch(Exception e) { System.err.println("checking for login "+ e);}
    }

    private void startAddressBook() throws SQLException
    {
        //close previous gui db connection
        conn.close();
        frame.dispose();
        AddressBook a = new AddressBook();
        a.init_connection();
        a.start_gui();
    }

}

Address Book GUI:

/*
 * Address book gui has CRUD operations and mysql database access
 * use interface for gui's? 
 */


import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;

public class AddressBook implements ActionListener{


    JFrame frame;
    JPanel Master, centerInfo, buttonInfo;
    GridBagConstraints constraints;
    GridBagConstraints topconstraint;
    JLabel jlb_firstName, jlb_lastName, jlb_phoneNum, jlb_searchInfo;
    JTextField jtf_firstName, jtf_lastName, jtf_phoneNum;
    JTextArea jta_searchInfo;
    JButton jb_add, jb_search, jb_share, jb_delete;
    Container pane;

    Connection conn;
    String firstName, lastName, phoneNum;



    public void init_connection()
    {
        try
        {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/addressbook", "root", "root");
        }
        catch(SQLException ex)
        {
            ex.printStackTrace();
        }
    }

    public void start_gui()
    {   
        JFrame frame = new JFrame("Address Book");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container pane = new Container();
        pane = frame.getContentPane();
        layComponents(pane);
        //frame.setSize(400, 400);
        frame.setSize(400,400);
        frame.setVisible(true);

    }

    private void layComponents(Container contentPane)
    {
        //PANELS,CONTENTPANE,CONSTRAINTS
        JPanel Master = new JPanel();
        JPanel centerInfo = new JPanel(new GridBagLayout());
        JPanel buttonInfo = new JPanel(new FlowLayout(FlowLayout.LEADING,10,5));
        Master.add(centerInfo, BorderLayout.CENTER);
        Master.add(buttonInfo, BorderLayout.SOUTH);
        contentPane.add(Master);                        //set style of layout for GUI
        GridBagConstraints constraints = new GridBagConstraints();      //layout constraints
        GridBagConstraints topconstraint = new GridBagConstraints();    //constraint against top of GUI

        constraints.insets = new Insets(5,5,10,10);
        //components: firstName, lastName, phoneNum, info, Add, Search(need to add oracle sql db)

        //LABELS
        jlb_firstName = new JLabel("First Name");
        topconstraint.gridx =1;
        topconstraint.gridy =0;
        topconstraint.insets = new Insets(20,5,10,10);                  //Insets(top,left,right,down)
        centerInfo.add(jlb_firstName, topconstraint);
        jlb_lastName = new JLabel("Last Name");
        constraints.gridx =1;
        constraints.gridy =2;
        centerInfo.add(jlb_lastName,constraints);
        jlb_phoneNum = new JLabel("Phone Number");
        constraints.gridx =1;
        constraints.gridy =4;
        centerInfo.add(jlb_phoneNum,constraints);
        jlb_searchInfo = new JLabel("Search Info");
        constraints.gridx =1;
        constraints.gridy =6;
        centerInfo.add(jlb_searchInfo, constraints);

        //TEXTFIELDS
        jtf_firstName = new JTextField("Enter New First Name");     //to clear textfield when clicked need actionlisteners
        topconstraint.gridx =3;
        topconstraint.gridy =0;
        centerInfo.add(jtf_firstName,topconstraint);
        jtf_lastName = new JTextField("Enter New Last Name");
        constraints.gridx =3;
        constraints.gridy =2;
        centerInfo.add(jtf_lastName, constraints);
        jtf_phoneNum = new JTextField("Enter in ###-###-#### format");
        constraints.gridx =3;
        constraints.gridy =4;
        centerInfo.add(jtf_phoneNum, constraints);

        //TEXTAREA
        Border loweredetched;
        loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
        jta_searchInfo = new JTextArea(10,20);
        jta_searchInfo.append("click me");
        jta_searchInfo.setEditable(true);

        jta_searchInfo.setBorder(loweredetched);
        constraints.gridx =3;
        constraints.gridy =6;
        centerInfo.add(jta_searchInfo, constraints);

        //buttons will use flowlayout
        //BUTTONS
        jb_add = new JButton("Add");
        buttonInfo.add(jb_add);
        jb_search = new JButton("Search");
        buttonInfo.add(jb_search);
        jb_share = new JButton("Share");
        buttonInfo.add(jb_share);                               //share info with ppl. need a new share gui
        jb_delete = new JButton("delete");
        buttonInfo.add(jb_delete);

        //Listen for any component actions performed
        jb_add.addActionListener(this);
        jb_delete.addActionListener(this);
        jb_search.addActionListener(this);
        jb_share.addActionListener(this);   
    }



    public void actionPerformed(ActionEvent e) {

        firstName = jtf_firstName.getText().toLowerCase();
        lastName = jtf_lastName.getText().toLowerCase();
        phoneNum = jtf_phoneNum.getText();

        if(e.getSource() == jb_add)
        {
            AddtoRecord();
        }
        else if(e.getSource() == jb_delete)
        {
            deletefromRecord(); 
        }
        else if(e.getSource() == jb_search)
        {

        }
        else if(e.getSource() == jb_share)
        {

        }
    }


    private void AddtoRecord()
    {   
        try
        {
            System.out.println(firstName + " " + lastName + " " + phoneNum);

            String instruction = "Insert into address (firstName, lastName, phonNum)" + "VALUES(?,?,?)";
            PreparedStatement preparedStatement = conn.prepareStatement(instruction);
            preparedStatement.setString(1, firstName);
            preparedStatement.setString(2, lastName);
            preparedStatement.setString(3, phoneNum);
            preparedStatement.executeUpdate();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            firstName = "";
            lastName = "";
            phoneNum = "";
        }

    }


    private void deletefromRecord()
    {
        //find then remove. require at least first name
        if(firstName.equals(null) || lastName.equals(null))
        {
            System.out.println("Enter first or last Name");
        }
        else
        {
        try
        {

            String instr = "DELETE FROM address WHERE firstName=? OR lastName=?";
            PreparedStatement ps = conn.prepareStatement(instr);
            ps.setString(1, firstName);
            ps.setString(2, lastName);
            ps.executeUpdate();

        }catch(Exception e){ System.err.println(e + "delete");}
        }
    }


    private void searchfromRecord()
    {
        try
        {
            String instr = "SELECT firstName, lastName, phonNum WHERE firstName='%" +firstName+"%'";
            Statement s = conn.createStatement();
            ResultSet rset = s.executeQuery(instr);
            while(rset.next())
            {
                jta_searchInfo.setText(rset.getString("firstName"));
                jta_searchInfo.setText(rset.getString("lastName"));
                jta_searchInfo.setText(rset.getString("phonNum"));
            }
        } catch(Exception e){System.err.println(e + "search");}

    }

}

Integrate GUI:

public class integrate_Gui {

        //change db stuff
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Login login = new Login();
        login.init_connection();
        login.start_gui();
    }

}
\$\endgroup\$
3
\$\begingroup\$

Login and Address Book GUI

  • Please follow the Java code conventions, e.g. no snake_case
  • Hungarian notation is a bad idea (especially for GUI elements)
  • Try to reduce the number of instance variables. E.g. there should be no reason to have a JLabel as instance variable, it can be local
  • Implementing listeners in top-level classes is bad, as this is an implementation detail the user of the class shouldn't see. Use anonymous classes or - when Java 8 is available - lambdas
  • GridBagLayout is a PITA. You can reduce code size substantially if you use something sane (FormLayout, TableLayout, MigLayout... - all not included in Swing, but free)
  • hard-coding connection data == bad idea
  • JFrames should be started with invokeAndWait or invokeLater (see e.g. http://en.wikibooks.org/wiki/Java_Swings/Swing_Layouts ). Most people don't follow this advice, but it's the "official" way. Just sayin'

Especially for Adress Book GUI

  • Separate the GUI from DB access (follow e.g. MVC-Pattern, DAO-Pattern)
  • Of course this means you need an Address class, too
  • Let me stress this: Separate the GUI from DB access
  • Consider higher-level abstractions than JDBC (e.g. JPA...)
  • Prepared statements are made to prepare a query. Don't recreate them every time. Make them once, store them in instance variables, and set only the values before executing them
  • Don't forget to separate the GUI from DB access
\$\endgroup\$
  • \$\begingroup\$ Thanks for the comprehensive review! So if I was to follow a MVC design pattern would the views consists of startgui/laycomponents for a login view and a addressbookview? and the models be users which contain fields for username and password and person which has fields for name, phonenumber, and address. The controller controls data flow between the two but my question is where should I allow access to the database and actions when it's open? Is that done in the controller or models? \$\endgroup\$ – user3043051 Feb 3 '15 at 6:35
  • \$\begingroup\$ I think (but this is only my private opinion) this depends on your use case, especially whether the access privileges are stored in the DB or not. If the DB contains these data, they are part of the model, and it would be fine to enforce them on model side. But there are scenarios where the model doesn't (or even shoudn't) know about users and rights, e.g. when these information come from another source like LDAP. In that case I think it is better when the controller restricts access. \$\endgroup\$ – Landei Feb 4 '15 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.