4
\$\begingroup\$

I was requested to make a Sign-in program for the LGBTA Center at my university. They wanted something where anyone that came by and visited could leave their name and email, but also so that no one that came behind them could see who else has come in, like an Excel sheet or regular piece of paper would do.

The program takes an email (which is checked to see if it contains an '@' and ends with the five most common extensions) and a name, generates the exact time and date it was submitted, and writes all that information to a .txt file. If that .txt file does not exist, a new one is created with that day's date as the file name; otherwise, it appends to the correct file.

I've tried to make it as user-friendly as possible, such as pressing enter in the text field for name requests focus on the text field for email. Pressing enter in the text field for email will check if everything is valid, and if so, writes to the file.

Right now, the files are saved in the same location as the .jar file I package it in, but this is only because the program is going on a university computer where anyone (the computer it is going on is used for work study by different students) that signs in might need access to it. I'm not sure if there's a better way to do this as I'm not that familiar with the file system of a Mac.

CenterSignIn.java (main)

import javax.swing.JFrame;

public class CenterSignIn 
{   
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Center Sign In");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new CenterGUI());
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

CenterGUI

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    import javax.swing.border.EmptyBorder;
    import java.util.Date;
    import java.text.SimpleDateFormat;

    public class CenterGUI extends JPanel
    {
        private static final long serialVersionUID = 1L; //only there because it gives me a warning otherwise
        private JTextField name = new JTextField("");
        private JTextField email = new JTextField("");
        private Date date = new Date();
        private BufferedWriter out;
        private JLabel err1 = new JLabel("", JLabel.CENTER);
        private JLabel err2 = new JLabel("", JLabel.CENTER);

        public void initFile() throws IOException
        {
            File file = new File(new SimpleDateFormat("MM.dd.yyyy").format(date) + ".txt");     
            if(!file.exists())
            {
                file.createNewFile();
                out = new BufferedWriter(new FileWriter(file));
                out.write("Visitors this day:");
                out.flush();
            }
            else
                out = new BufferedWriter(new FileWriter(file, true));
        }

        public CenterGUI()
        {
            try {
                initFile();
            } catch ( IOException e ) {}

            JPanel panel = new JPanel();
            panel.setBorder(new EmptyBorder(0, 10, 10, 10));
            panel.setPreferredSize(new Dimension(450, 250));
            panel.setLayout(new GridLayout(4, 1, 10, 10));
                JPanel p1 = new JPanel();
                    JLabel title = new JLabel("<html><font color=red>L</font><font color=orange>G</font><font color=yellow>B</font><font color=green>T</font><font color=blue>A</font><font color=purple>+</font> Center Sign In</html>", JLabel.CENTER);
                    title.setFont(new Font("SansSerif", Font.PLAIN, 32));
                    p1.add(title);
                JPanel p2 = new JPanel();
                p2.setLayout(new GridLayout(2, 2, 10, 10));
                    JLabel l1 = new JLabel("Please enter your name:", JLabel.CENTER);
                    l1.setFont(new Font("Serif", Font.PLAIN, 18));
                    p2.add(l1);
                    name.addKeyListener(new listener());
                    name.setFont(new Font("Serif", Font.PLAIN, 18));
                    p2.add(name);
                    err1.setFont(new Font("Serif", Font.PLAIN, 18));
                    err1.setForeground(Color.RED);
                    p2.add(err1);
                JPanel p3 = new JPanel();
                p3.setLayout(new GridLayout(2, 2, 10, 10));
                    JLabel l2 = new JLabel("Please enter your email:", JLabel.CENTER); 
                    l2.setFont(new Font("Serif", Font.PLAIN, 18));
                    p3.add(l2);
                    email.setFont(new Font("Serif", Font.PLAIN, 18));
                    email.addKeyListener(new listener());
                    p3.add(email);
                    err2.setFont(new Font("Serif", Font.PLAIN, 18));
                    err2.setForeground(Color.RED);
                    p3.add(err2);
                JPanel p4 = new JPanel();
                    JButton submit = new JButton("Submit");
                    submit.setPreferredSize(new Dimension(100, 40));
                    submit.setFont(new Font("SansSerif", Font.PLAIN, 20));
                    submit.addActionListener(new listener());
                    p4.add(submit);
                panel.add(p1);
                panel.add(p2);
                panel.add(p3);
                panel.add(p4);
            add(panel);
        }

        private class listener implements ActionListener, KeyListener
        {
            public void keyPressed(KeyEvent e)
            {
                if(e.getSource() == name && e.getKeyCode() == KeyEvent.VK_ENTER)
                    email.requestFocus();
                else if(e.getSource() == email && e.getKeyCode() == KeyEvent.VK_ENTER)
                    actionPerformed(null);
            }

            public void actionPerformed(ActionEvent event)
            {
                err1.setText("");
                err2.setText("");
                String n = name.getText();
                String e = email.getText();

                if(!e.contains("@") || (!e.endsWith(".com") && !e.endsWith(".org") && !e.endsWith(".edu") && !e.endsWith(".gov") && !e.endsWith(".net")))
                    err2.setText("Invalid email.");

                if(n.isEmpty() || e.isEmpty() || err2.getText() == "Invalid email.")
                {
                    if(n.isEmpty())
                        err1.setText("This field is required.");
                    if(e.isEmpty())
                        err2.setText("This field is required.");
                }
                else
                {
                    try {
                        out.newLine();
                        SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mma 'on' MM/dd/yyyy");
                        String output = n + " - " + e + " - " + dateFormat.format(date);
                        out.write(output);
                        out.flush();
                    } catch (IOException e1) {}
                    name.setText("");
                    email.setText("");
                    name.requestFocus();
                }
            }

            @Override
            public void keyReleased( KeyEvent e ) {}
            @Override
            public void keyTyped( KeyEvent e ) {}
        }
    }
}

My main goal of optimizing it is to make it as user-friendly as possible and to make it as resource-light as I can get it. I'm also not quite sure about optimizing Java on a Mac. I've tested it on the Mac and it works, but I don't know if there are any optimizations that can be made to make it run better on a Mac.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Composition over inheritance

In GUI, specially Swing, prefer composition over inheritance. You don't need to override any of the normal behaviour, so just create a normal JPanel and just remove the extends.

Extending just make things weird since now your class is a lot of things it should be. A normal JPanel doesn't have field for specific things in it.

Use braces

I always suggest the use of {} even when you have only one line. It lower the number of changes if you add another line of code, it leave the code in a consistent state (braces everywhere) and you eliminate a possible bug in future code.

Exception

If you don't want to deal with IOExcpetion and just swallow the exception, why do you declare the method with throws IOException ?

        try {
            initFile();
        } catch ( IOException e ) {}

The method declare a new file if the file doesn't exist, so you could just remove the checked exception and just deal with the error in the method directly.

Constant

Always look for duplicated piece when you're done with your code. Is there some String content that I could refactored in a constant? Are there repetitive piece of code that I could create a method ?

Here you have new Font("Serif", Font.PLAIN, 18) that is re-declared almost everywhere for each label. Why don't you declare a constant, so when you want to change the font you only have one change to do :)?

Naming

Please follow the official naming convention of Java, private class listener implements ActionListener, KeyListener should be private class Listener implements ActionListener, KeyListener.

Naming is hard too, Listener is so generic that it could be anything at that point. In your code that class has a very specific role, it deal with the action done in this view. It could be named CenterGUIListener or something more specific.

Named condition

When I deal with multiple || and && in a condition, I like to make a method out of the complicated condition.

if(!e.contains("@") || (!e.endsWith(".com") && !e.endsWith(".org") && !e.endsWith(".edu") && !e.endsWith(".gov") && !e.endsWith(".net")))

Here you could have the method called isEmailAndHaveValidExtensions. Most of the time, I prefer to have a named method that will tell me what it validate and if needed I'll check the method to see how it enforce that validation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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