appointmentList = new JList<>(ApplicationController.appointmentListModel);
14 | private JScrollPane appointmentScroll = new JScrollPane(appointmentList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
15 | JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
16 |
17 | public ViewAppointmentsScreen() {
18 |
19 | getBackButton().setVisible(false);
20 | setBackground(new Color(162, 176, 177));
21 |
22 | titleLabel.setBounds(0, 0, 1600, 900);
23 | add(titleLabel);
24 |
25 | appointmentList.setFont(new Font("Tahoma", Font.PLAIN, 20));
26 | appointmentScroll.setBounds(100, 130, 1400, 600);
27 | add(appointmentScroll);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/model/Account.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class Account {
4 |
5 | // Fields
6 | private String firstName;
7 | private String lastName;
8 | private String email;
9 | private String password;
10 | private String phoneNumber;
11 | private String UUID;
12 |
13 | // Constructor
14 | public Account(String firstName, String lastName, String email, String password, String phoneNumber, String UUID) {
15 | this.firstName = firstName;
16 | this.lastName = lastName;
17 | this.email = email;
18 | this.password = password;
19 | this.phoneNumber = phoneNumber;
20 | this.UUID = UUID;
21 | }
22 |
23 | // Getters
24 | public String getFirstName() { return firstName; }
25 |
26 | public String getLastName() {
27 | return lastName;
28 | }
29 |
30 | public String getEmail() {
31 | return email;
32 | }
33 |
34 | public String getPhoneNumber() {
35 | return phoneNumber;
36 | }
37 |
38 | public String getUUID() { return UUID; }
39 |
40 | // toString method
41 | @Override
42 | public String toString() {
43 | return firstName + ", " + lastName + ", " + email + ", " + password + ", " + phoneNumber + ", " + UUID;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/controller/AccountController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.Account;
4 |
5 | import java.io.File;
6 | import java.io.FileNotFoundException;
7 | import java.util.Scanner;
8 |
9 | public class AccountController {
10 |
11 | // Reading the registration.txt file and adding the accounts to an ArrayList
12 | public void importAccounts(String fileName) {
13 | try {
14 | Scanner input = new Scanner(new File(fileName));
15 | input.useDelimiter(",");
16 |
17 | // For all lines in the registration text file
18 | while (input.hasNextLine()) {
19 |
20 | // Store account information
21 | String[] accountInformation = new String[6];
22 |
23 | // Get values from text file to array
24 | for (int x = 0; x < 6 && input.hasNext(); x++)
25 | accountInformation[x] = input.next();
26 |
27 | // Add information to accounts ArrayList
28 | ApplicationController.accounts.add(new Account(accountInformation[0],
29 | accountInformation[1], accountInformation[2],
30 | accountInformation[3], accountInformation[4], accountInformation[5]));
31 | }
32 |
33 | input.close(); // Close input
34 |
35 | } catch (FileNotFoundException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Book With Me
2 |
3 | Barber Booking Application
4 |
5 |
6 | 
7 |
8 | ---
9 | The following application simulates the process of users booking haircutting services with my barber shop.
10 | It consists of creating or logging into an account, booking an appointment by selecting the styles they want done,
11 | calculating the cost and time for the haircut, and viewing previous appointments.
12 | This information is saved and written to text files as a local database.
13 |
14 | Note: This application requires the JCalendar 1.4 library to run properly
15 |
16 | # Images 📷
17 | ###### Login Screen
18 | 
19 | ###### Register Screen
20 | 
21 | ###### Home Screen
22 | 
23 | ###### Booking Screen
24 | 
25 | ###### View Appointments Screen
26 | 
27 | ###### Profile Screen
28 | 
29 |
--------------------------------------------------------------------------------
/src/view/Screen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import com.toedter.calendar.JCalendar;
4 |
5 | import javax.swing.*;
6 | import java.util.Date;
7 |
8 | public abstract class Screen extends JPanel {
9 |
10 | // Fields
11 | private JButton backButton;
12 | private JButton backToHomeButton;
13 | private JCalendar calendar = new JCalendar();
14 | private Date today = new Date();
15 |
16 | public Screen() {
17 |
18 | setLayout(null); // Absolute positioning
19 | setBounds(0, 0, DefaultScreen.WIDTH, DefaultScreen.HEIGHT); // Screen size
20 |
21 | // Create back buttons
22 | ImageIcon backImage = new ImageIcon("images/backButton.png");
23 | backButton = new JButton(backImage);
24 | backButton.setBounds(1540,20, backImage.getIconWidth(), backImage.getIconHeight());
25 | backButton.setContentAreaFilled(false);
26 | backButton.setBorderPainted(false);
27 | add(backButton);
28 |
29 | backToHomeButton = new JButton(backImage);
30 | backToHomeButton.setBounds(1540,20, backImage.getIconWidth(), backImage.getIconHeight());
31 | backToHomeButton.setContentAreaFilled(false);
32 | backToHomeButton.setBorderPainted(false);
33 | add(backToHomeButton);
34 |
35 | }
36 |
37 | // Create JCalendar
38 | public void enableCalendar() {
39 | calendar.setBounds(1075, 260, 400, 350);
40 | calendar.setMinSelectableDate(today);
41 | add(calendar);
42 |
43 | }
44 |
45 | public JButton getBackButton() { return backButton; }
46 |
47 | public JButton getBackToHomeButton() { return backToHomeButton; }
48 |
49 | public JCalendar getCalendar() { return calendar; }
50 | }
51 |
--------------------------------------------------------------------------------
/src/view/ProfileScreen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | public class ProfileScreen extends Screen {
7 |
8 | // Fields
9 | private JLabel profileTitleLabel = new JLabel(new ImageIcon("images/profileTitle.png"));
10 | private JLabel nameLabel = new JLabel("Name: ");
11 | private JLabel passwordLabel = new JLabel("Password: •••••••");
12 | private JLabel emailLabel = new JLabel("Email: ");
13 | private JLabel phoneNumberLabel = new JLabel("Phone Number: ");
14 | private JLabel icons = new JLabel(new ImageIcon("images/profileIcons.png"));
15 |
16 | private static final Font FONT = new Font("Tahoma", Font.PLAIN, 30);
17 |
18 | public ProfileScreen() {
19 |
20 | getBackButton().setVisible(false);
21 |
22 | profileTitleLabel.setBounds(600, 0, 1600, 900);
23 | add(profileTitleLabel);
24 |
25 | nameLabel.setBounds(625, 230, 500, 50);
26 | nameLabel.setFont(FONT);
27 | add(nameLabel);
28 |
29 | passwordLabel.setBounds(625, 330, 500, 50);
30 | passwordLabel.setFont(FONT);
31 | add(passwordLabel);
32 |
33 | emailLabel.setBounds(625, 430, 500, 50);
34 | emailLabel.setFont(FONT);
35 | add(emailLabel);
36 |
37 | phoneNumberLabel.setBounds(625, 530, 500, 50);
38 | phoneNumberLabel.setFont(FONT);
39 | add(phoneNumberLabel);
40 |
41 | icons.setBounds(0, -5, 1600, 900);
42 | add(icons);
43 |
44 | }
45 |
46 | public JLabel getNameLabel() { return nameLabel; }
47 |
48 | public JLabel getEmailLabel() { return emailLabel; }
49 |
50 | public JLabel getPhoneNumberLabel() { return phoneNumberLabel; }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/view/HomeScreen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | public class HomeScreen extends Screen {
7 |
8 | private JLabel welcomeLabel = new JLabel("Welcome to Barber Booker");
9 | private JButton appointmentButton = new JButton("Book an
appointment");
10 | private JButton viewAppointmentButton = new JButton("View previous
appointments");
11 | private JButton profileButton = new JButton("Your Profile");
12 |
13 | private static final Font FONT = new Font("Tahoma", Font.PLAIN, 30);
14 |
15 | public HomeScreen() {
16 |
17 | getBackToHomeButton().setVisible(false);
18 | setBackground(new Color(113, 146, 172));
19 |
20 | welcomeLabel.setBounds(70, 50, 700, 100);
21 | welcomeLabel.setFont(new Font("Calibri", Font.BOLD, 50));
22 | welcomeLabel.setForeground(Color.WHITE);
23 | add(welcomeLabel);
24 |
25 | appointmentButton.setBackground(new Color(30, 75, 135));
26 | appointmentButton.setForeground(Color.WHITE);
27 | appointmentButton.setFont(FONT);
28 | appointmentButton.setBorder(null);
29 | appointmentButton.setBounds(300, 400, 250, 125);
30 | add(appointmentButton);
31 |
32 | viewAppointmentButton.setBackground(new Color(30, 75, 135));
33 | viewAppointmentButton.setForeground(Color.WHITE);
34 | viewAppointmentButton.setFont(FONT);
35 | viewAppointmentButton.setBorder(null);
36 | viewAppointmentButton.setBounds(700, 400, 250, 125);
37 | add(viewAppointmentButton);
38 |
39 | profileButton.setBackground(new Color(30, 75, 135));
40 | profileButton.setForeground(Color.WHITE);
41 | profileButton.setFont(FONT);
42 | profileButton.setBorder(null);
43 | profileButton.setBounds(1100, 400, 250, 125);
44 | add(profileButton);
45 |
46 | }
47 |
48 | public JLabel getWelcomeLabel() { return welcomeLabel; }
49 |
50 | public JButton getAppointmentButton() { return appointmentButton; }
51 |
52 | public JButton getViewAppointmentButton() { return viewAppointmentButton; }
53 |
54 | public JButton getProfileButton() { return profileButton; }
55 | }
56 |
--------------------------------------------------------------------------------
/src/application/BarberApplication.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Book With Me - A Barber Booking Application
3 | * The following application simulates the process of users booking haircutting services with my barber shop.
4 | * It consists of creating or logging into an account, booking an appointment by selecting the styles they want done,
5 | * calculating the cost and time for the haircut, and viewing previous appointments.
6 | * This information is saved and written to text files as a local database.
7 | *
8 | * Sample login information with pre-tested appointments:
9 | * Email - admin@email.com
10 | * Password - password
11 | *
12 | * Features:
13 | * - Create an account with first and last name, email, password, phone number. A unique UUID is generated per account.
14 | * - Login to an account with an email and password
15 | * - Logging out of an account
16 | * - Booking appointments by selecting what top length they would like to cut, if they want a taper or fade,
17 | * the side style, and if they request any additional haircutting services
18 | * - Viewing previously booked appointments for user-specific accounts
19 | * - Viewing profile information (name, email, phone number)
20 | * - Navigate through login, register, home, booking, view appointments, profile screen with buttons and back buttons
21 | *
22 | * Major Skills:
23 | * - Modular Programming (Model-View-Controller)
24 | * - Object Oriented Programming
25 | * - String, int, double, boolean
26 | * - Arrays, ArrayLists, DefaultListModel
27 | * - For loops, If/Else/Else If, Break, While, Try-catch
28 | * - Text-file Database:
29 | * - Reading text files to retrieve account data and appointments
30 | * - Writing to text files to save data for an account
31 | * - Java Swing Objects (Jlist, JButton, JComboBox, JSlider, JRadioButton, JLabel...)
32 | * - ActionListener
33 | * - Use of methods to handle tasks
34 | * - Use of external library (JCalendar)
35 | *
36 | * @author Brandon Vo
37 | */
38 |
39 | package application;
40 |
41 | import controller.ApplicationController;
42 |
43 | public class BarberApplication {
44 |
45 | public static void main(String[] args) {
46 |
47 | new ApplicationController(); // Create ApplicationController
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.ScreenType;
4 | import view.HomeScreen;
5 |
6 | import java.awt.event.ActionEvent;
7 | import java.awt.event.ActionListener;
8 |
9 | public class HomeController implements ActionListener {
10 |
11 | private HomeScreen homeScreen; // Access home screen
12 |
13 | // Constructor
14 | public HomeController(HomeScreen homeScreen) {
15 | this.homeScreen = homeScreen;
16 | setupListeners();
17 | }
18 |
19 | // Welcome label with accounts first name
20 | public void setupLabel() {
21 | homeScreen.getWelcomeLabel().setText("Welcome, " + ApplicationController.currentFirstName);
22 | }
23 |
24 | // Set up listeners
25 | public void setupListeners() {
26 | homeScreen.getAppointmentButton().addActionListener(this);
27 | homeScreen.getViewAppointmentButton().addActionListener(this);
28 | homeScreen.getProfileButton().addActionListener(this);
29 | }
30 |
31 | @Override
32 | public void actionPerformed(ActionEvent e) {
33 | if (e.getSource() == homeScreen.getAppointmentButton()) { // Book appointment button
34 | ApplicationController.switchScreen // Switch to booking screen
35 | (ApplicationController.screens[ScreenType.BOOKING_SCREEN.getValue()]);
36 | ApplicationController.bookingController.bookingScreen.enableCalendar(); // Enable calendar
37 | } else if (e.getSource() == homeScreen.getViewAppointmentButton()) { // View appointments button
38 | ApplicationController.switchScreen // Switch to view appointments screen
39 | (ApplicationController.screens[ScreenType.VIEW_APPOINTMENTS_SCREEN.getValue()]);
40 | ApplicationController.appointmentListModel.clear(); // Clear initial list
41 | ApplicationController.appointmentListModel.addAll
42 | (ApplicationController.currentAppointments); // Add appointments to list
43 | } else if (e.getSource() == homeScreen.getProfileButton()) // Profile button
44 | ApplicationController.switchScreen // Switch to profile screen
45 | (ApplicationController.screens[ScreenType.PROFILE_SCREEN.getValue()]);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/view/LoginScreen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | public class LoginScreen extends Screen {
7 |
8 | private JLabel loginTitleLabel = new JLabel(new ImageIcon("images/loginTitle.png"));
9 | private JTextField emailField = new JTextField();
10 | private JPasswordField passwordField = new JPasswordField();
11 | private JCheckBox showPassword;
12 | private JButton registerButton = new JButton("REGISTER");
13 | private JButton loginButton = new JButton("LOGIN");
14 | private JLabel emailLabel = new JLabel("Email");
15 | private JLabel passwordLabel = new JLabel("Password");
16 |
17 | public static final Font FONT = new Font("Tahoma", Font.PLAIN, 16);
18 |
19 | public LoginScreen() {
20 |
21 | // Disable back buttons on login screen
22 | getBackButton().setVisible(false);
23 | getBackToHomeButton().setVisible(false);
24 |
25 | // Background colour
26 | setBackground(new Color(102, 153, 204));
27 |
28 | // Title
29 | loginTitleLabel.setBounds(0, 0, 1600, 900);
30 | add(loginTitleLabel);
31 |
32 | // Email field
33 | emailField.setForeground(Color.GRAY);
34 | emailField.setBounds(525, 340, 540, 50);
35 | add(emailField);
36 | emailField.setColumns(10);
37 |
38 | // Password Field
39 | passwordField.setForeground(Color.GRAY);
40 | passwordField.setBounds(525, 440, 540, 50);
41 | add(passwordField);
42 | passwordField.setColumns(10);
43 |
44 | // Email Label
45 | emailLabel.setForeground(Color.WHITE);
46 | emailLabel.setFont(FONT);
47 | emailLabel.setBounds(525, 315, 92, 17);
48 | add(emailLabel);
49 |
50 | // Password Label
51 | passwordLabel.setFont(FONT);
52 | passwordLabel.setForeground(new Color(255, 255, 255));
53 | passwordLabel.setBounds(525, 415, 80, 17);
54 | add(passwordLabel);
55 |
56 | // Show password checkbox
57 | showPassword = new JCheckBox("Show Password");
58 | showPassword.setForeground(Color.WHITE);
59 | showPassword.setBackground(new Color( 102, 153, 204));
60 | showPassword.setBounds(525, 500, 139, 23);
61 | add(showPassword);
62 |
63 | // Login button
64 | loginButton.setBackground(new Color(48, 114, 163));
65 | loginButton.setForeground(Color.WHITE);
66 | loginButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
67 | loginButton.setBorder(null);
68 | loginButton.setBounds(605, 540, 150, 40);
69 | add(loginButton);
70 |
71 | // Register button
72 | registerButton.setBackground(new Color(204, 204, 204));
73 | registerButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
74 | registerButton.setBorder(null);
75 | registerButton.setBounds(835, 540, 150, 40);
76 | add(registerButton);
77 |
78 | }
79 |
80 | public JTextField getEmailField() { return emailField; }
81 |
82 | public JPasswordField getPasswordField() { return passwordField; }
83 |
84 | public JButton getLoginButton() { return loginButton; }
85 |
86 | public JButton getRegisterButton() { return registerButton; }
87 |
88 | public JCheckBox getShowPassword() { return showPassword; }
89 | }
90 |
--------------------------------------------------------------------------------
/src/controller/AppointmentController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.Appointment;
4 |
5 | import java.io.File;
6 | import java.io.FileNotFoundException;
7 | import java.util.Arrays;
8 | import java.util.Scanner;
9 |
10 | public class AppointmentController {
11 |
12 | public void importAppointments(String fileName) {
13 | try {
14 | Scanner input = new Scanner(new File(fileName));
15 | input.useDelimiter(",");
16 |
17 | // For all lines in the appointments text file
18 | while (input.hasNextLine()) {
19 |
20 | // Store appointment information
21 | String[] appointmentInformation = new String[13];
22 |
23 | // Get values from text file to array
24 | for (int x = 0; x < 13 && input.hasNext(); x++)
25 | appointmentInformation[x] = input.next();
26 |
27 | // Add information to appointments ArrayList
28 | ApplicationController.appointments.add(new Appointment(appointmentInformation[0],
29 | appointmentInformation[1], appointmentInformation[2],
30 | appointmentInformation[3], appointmentInformation[4], appointmentInformation[5]
31 | , appointmentInformation[6], appointmentInformation[7], appointmentInformation[8]
32 | , appointmentInformation[9], appointmentInformation[10], appointmentInformation[11]
33 | , appointmentInformation[12]));
34 |
35 | }
36 |
37 | // Store current appointment information
38 | Appointment currentAppointmentInformation;
39 |
40 | // Remove last row in the appointments ArrayList which is all null
41 | ApplicationController.appointments.remove(ApplicationController.appointments.size() - 1);
42 |
43 | // Search through all appointments and match the current ID to appointments with the same ID
44 | // Add current appointment information to the current appointment ArrayList
45 | for (int index = 0; index < ApplicationController.appointments.size(); index++) {
46 | if (ApplicationController.appointments.get(index)
47 | .getUniqueID().equals(ApplicationController.currentID)) {
48 | // Create appointment for current appointment information
49 | currentAppointmentInformation = new Appointment(
50 | ApplicationController.appointments.get(index).getTopLength(),
51 | ApplicationController.appointments.get(index).getBuzzCut(),
52 | ApplicationController.appointments.get(index).getThinOut(),
53 | ApplicationController.appointments.get(index).getFadeType(),
54 | ApplicationController.appointments.get(index).getTaperType(),
55 | ApplicationController.appointments.get(index).getSideType(),
56 | ApplicationController.appointments.get(index).getDesign(),
57 | ApplicationController.appointments.get(index).getBeard(),
58 | ApplicationController.appointments.get(index).getLineUp(),
59 | ApplicationController.appointments.get(index).getAppointmentDate(),
60 | ApplicationController.appointments.get(index).getTime(),
61 | ApplicationController.appointments.get(index).getCost(),
62 | ApplicationController.appointments.get(index).getUniqueID());
63 | // Add information to ArrayList
64 | ApplicationController.currentAppointments.addAll(Arrays.asList(currentAppointmentInformation));
65 | }
66 | }
67 |
68 | input.close(); // Close input
69 |
70 | } catch (FileNotFoundException e) {
71 | e.printStackTrace();
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/model/Appointment.java:
--------------------------------------------------------------------------------
1 | package model;
2 |
3 | public class Appointment {
4 |
5 | // Fields
6 | private String topLength;
7 | private String buzzCut;
8 | private String thinOut;
9 | private String fadeType;
10 | private String taperType;
11 | private String sideType;
12 | private String design;
13 | private String beard;
14 | private String lineUp;
15 | private String appointmentDate;
16 | private String time;
17 | private String cost;
18 | private String uniqueID;
19 |
20 | // Constructor
21 | public Appointment(String topLength, String buzzCut, String thinOut, String fadeType,
22 | String taperType, String sideType, String design, String beard, String lineUp,
23 | String appointmentDate, String time, String cost, String uniqueID) {
24 | this.topLength = topLength;
25 | this.buzzCut = buzzCut;
26 | this.thinOut = thinOut;
27 | this.fadeType = fadeType;
28 | this.taperType = taperType;
29 | this.sideType = sideType;
30 | this.design = design;
31 | this.beard = beard;
32 | this.lineUp = lineUp;
33 | this.appointmentDate = appointmentDate;
34 | this.time = time;
35 | this.cost = cost;
36 | this.uniqueID = uniqueID;
37 | }
38 |
39 | // Getters
40 | public String getTopLength() { return topLength; }
41 |
42 | public String getBuzzCut() { return buzzCut; }
43 |
44 | public String getThinOut() { return thinOut; }
45 |
46 | public String getFadeType() { return fadeType; }
47 |
48 | public String getTaperType() { return taperType; }
49 |
50 | public String getSideType() { return sideType; }
51 |
52 | public String getDesign() { return design; }
53 |
54 | public String getBeard() { return beard; }
55 |
56 | public String getLineUp() { return lineUp; }
57 |
58 | public String getAppointmentDate() { return appointmentDate; }
59 |
60 | public String getTime() { return time; }
61 |
62 | public String getCost() { return cost; }
63 |
64 | public String getUniqueID() { return uniqueID; }
65 |
66 | // Getting only relevant data for the appointment (all null is ignored)
67 | private String getAppointment() {
68 | String appointments = "";
69 |
70 | if (!this.topLength.contains("null")) {
71 | appointments += "Top Length: " + this.topLength + " inches, ";
72 | }
73 | if (!this.buzzCut.contains("null")) {
74 | appointments += this.buzzCut + ", ";
75 | }
76 | if (!this.thinOut.contains("null")) {
77 | appointments += this.thinOut + ", ";
78 | }
79 | if (!this.fadeType.contains("null")) {
80 | appointments += this.fadeType + ", ";
81 | }
82 | if (!this.taperType.contains("null")) {
83 | appointments += this.taperType + ", ";
84 | }
85 | if (!this.sideType.contains("null")) {
86 | appointments += this.sideType + ", ";
87 | }
88 | if (!this.design.contains("null")) {
89 | appointments += this.design + ", ";
90 | }
91 | if (!this.beard.contains("null")) {
92 | appointments += this.beard + ", ";
93 | }
94 | if (!this.lineUp.contains("null")) {
95 | appointments += this.lineUp + ", ";
96 | }
97 | if (!this.appointmentDate.contains("null")) {
98 | appointments += "Date: " + this.appointmentDate + ", ";
99 | }
100 | if (!this.time.contains("null")){
101 | appointments += "Time: " + this.time + ", ";
102 | }
103 | if (!this.cost.contains("null")) {
104 | appointments += "Cost: " + this.cost + " ";
105 | }
106 | return appointments;
107 | }
108 |
109 | // toString method
110 | @Override
111 | public String toString() {
112 | String appointments = getAppointment();
113 | return appointments;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/controller/ApplicationController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.Account;
4 | import model.Appointment;
5 | import model.ScreenType;
6 | import view.*;
7 |
8 | import javax.swing.*;
9 | import java.util.ArrayList;
10 | import java.util.HashSet;
11 |
12 | public class ApplicationController {
13 |
14 | private static DefaultScreen defaultScreen; // Access DefaultScreen
15 |
16 | public static Screen[] screens = new Screen[ScreenType.values().length]; // All screens
17 | public static LoginController loginController; // Access LoginController
18 | public static HomeController homeController; // Access HomeController
19 | public static BookingController bookingController; // Access BookingController
20 | public static ProfileController profileController; // Access ProfileController
21 |
22 | public static String currentEmail; // Logged in users email
23 | public static String currentFirstName; // Logged in users first name
24 | public static String currentLastName; // Logged in users last name
25 | public static String currentPhoneNumber; // Logged in users phone number
26 | public static String currentID; // Logged in users ID
27 |
28 | public static AccountController accountImport = new AccountController(); // Import accounts
29 | public static AppointmentController appointmentImport = new AppointmentController(); // Import appointments
30 |
31 | public static ArrayList accounts = new ArrayList(); // Store accounts into ArrayList
32 | public static ArrayList appointments = new ArrayList(); // Store appointments into ArrayList
33 | public static ArrayList currentAppointments = new ArrayList(); // Store appointments for current user
34 |
35 | public static DefaultListModel appointmentListModel = new DefaultListModel<>();
36 |
37 | public ApplicationController() {
38 |
39 | // Import account data
40 | accountImport.importAccounts("accounts/registration.txt");
41 |
42 | // Create default screen object
43 | defaultScreen = new DefaultScreen();
44 |
45 | // Create all screens
46 | screens[ScreenType.LOGIN_SCREEN.getValue()] = new LoginScreen();
47 | screens[ScreenType.REGISTER_SCREEN.getValue()] = new RegisterScreen();
48 | screens[ScreenType.HOME_SCREEN.getValue()] = new HomeScreen();
49 | screens[ScreenType.BOOKING_SCREEN.getValue()] = new BookingScreen();
50 | screens[ScreenType.VIEW_APPOINTMENTS_SCREEN.getValue()] = new ViewAppointmentsScreen();
51 | screens[ScreenType.PROFILE_SCREEN.getValue()] = new ProfileScreen();
52 |
53 | // Create controllers
54 | loginController = new LoginController((LoginScreen) screens[ScreenType.LOGIN_SCREEN.getValue()]);
55 | new RegisterController((RegisterScreen) screens[ScreenType.REGISTER_SCREEN.getValue()]);
56 | homeController = new HomeController((HomeScreen) screens[ScreenType.HOME_SCREEN.getValue()]);
57 | bookingController = new BookingController((BookingScreen) screens[ScreenType.BOOKING_SCREEN.getValue()]);
58 | profileController = new ProfileController((ProfileScreen) screens[ScreenType.PROFILE_SCREEN.getValue()]);
59 |
60 | // Setup back buttons
61 | setupBackButton();
62 |
63 | // Login screen set to initial screen
64 | defaultScreen.add(screens[ScreenType.LOGIN_SCREEN.getValue()]);
65 | defaultScreen.setVisible(true);
66 |
67 | System.out.println("Start Application");
68 |
69 | }
70 |
71 | // Setting up back buttons
72 | public void setupBackButton() {
73 | for (int x = 0; x < ScreenType.values().length; x++) {
74 | // Switching to login screen
75 | screens[x].getBackButton().addActionListener(e ->
76 | switchScreen(screens[ScreenType.LOGIN_SCREEN.getValue()])
77 | );
78 | // Switching to home screen
79 | screens[x].getBackToHomeButton().addActionListener(e ->
80 | switchScreen(screens[ScreenType.HOME_SCREEN.getValue()])
81 | );
82 | }
83 | }
84 |
85 | // Method to switch screens
86 | public static void switchScreen(JPanel newScreen) {
87 | defaultScreen.getContentPane().removeAll();
88 | defaultScreen.getContentPane().repaint();
89 | defaultScreen.getContentPane().add(newScreen);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/view/RegisterScreen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | public class RegisterScreen extends Screen {
7 |
8 | // Fields
9 | private JLabel registerTitleLabel = new JLabel(new ImageIcon("images/registerTitle.png"));
10 | private JTextField firstNameField = new JTextField();
11 | private JTextField lastNameField = new JTextField();
12 | private JTextField emailField = new JTextField();
13 | private JPasswordField passwordField = new JPasswordField();
14 | private JPasswordField confirmPasswordField = new JPasswordField();
15 | private JTextField phoneNumberField = new JTextField();
16 |
17 | private JLabel firstNameLabel = new JLabel("First Name");
18 | private JLabel lastNameLabel = new JLabel("Last Name");
19 | private JLabel emailLabel = new JLabel("Email");
20 | private JLabel passwordLabel = new JLabel("Password");
21 | private JLabel confirmPasswordLabel = new JLabel("Confirm Password");
22 | private JLabel phoneNumberLabel = new JLabel("Phone Number");
23 |
24 | private JCheckBox showPassword = new JCheckBox("Show password");
25 |
26 | private JButton signUpButton = new JButton("SIGN UP");
27 |
28 | private static final Font FONT = new Font("Tahoma", Font.PLAIN, 16);
29 | private static final Color COLOUR = new Color(128, 128, 128);
30 |
31 | public RegisterScreen() {
32 |
33 | setBackground(new Color(211, 211, 211));
34 |
35 | // Title
36 | registerTitleLabel.setBounds(0, 0, 1600, 900);
37 | add(registerTitleLabel);
38 |
39 | // First Name Field
40 | firstNameField.setForeground(COLOUR);
41 | firstNameField.setBounds(525, 228, 254, 33);
42 | add(firstNameField);
43 | firstNameField.setColumns(10);
44 |
45 | // Last Name Field
46 | lastNameField.setForeground(COLOUR);
47 | lastNameField.setColumns(10);
48 | lastNameField.setBounds(825, 228, 249, 33);
49 | add(lastNameField);
50 |
51 | // Email Field
52 | emailField.setForeground(COLOUR);
53 | emailField.setBounds(525, 305, 550, 33);
54 | emailField.setColumns(10);
55 | add(emailField);
56 |
57 | // Password Field
58 | passwordField.setForeground(COLOUR);
59 | passwordField.setColumns(10);
60 | passwordField.setBounds(525, 379, 254, 33);
61 | add(passwordField);
62 |
63 | // Confirm Password Field
64 | confirmPasswordField.setForeground(COLOUR);
65 | confirmPasswordField.setColumns(10);
66 | confirmPasswordField.setBounds(825, 379, 247, 33);
67 | add(confirmPasswordField);
68 |
69 | // Phone Number Field
70 | phoneNumberField.setForeground(COLOUR);
71 | phoneNumberField.setColumns(10);
72 | phoneNumberField.setBounds(525, 480, 255, 33);
73 | add(phoneNumberField);
74 |
75 | // First Name Label
76 | firstNameLabel.setFont(FONT);
77 | firstNameLabel.setBounds(525, 197, 100, 20);
78 | add(firstNameLabel);
79 |
80 | // Last name label
81 | lastNameLabel.setFont(FONT);
82 | lastNameLabel.setBounds(825, 197, 100, 20);
83 | add(lastNameLabel);
84 |
85 | // Email label
86 | emailLabel.setFont(FONT);
87 | emailLabel.setBounds(525, 280, 127, 14);
88 | add(emailLabel);
89 |
90 | // Password label
91 | passwordLabel.setFont(FONT);
92 | passwordLabel.setBounds(525, 356, 101, 14);
93 | add(passwordLabel);
94 |
95 | // Confirm password label
96 | confirmPasswordLabel.setFont(FONT);
97 | confirmPasswordLabel.setBounds(825, 355, 153, 14);
98 | add(confirmPasswordLabel);
99 |
100 | // Phone number label
101 | phoneNumberLabel.setFont(FONT);
102 | phoneNumberLabel.setBounds(525, 455, 114, 14);
103 | add(phoneNumberLabel);
104 |
105 | // Show password checkbox
106 | showPassword.setBackground(new Color(211, 211, 211));
107 | showPassword.setBounds(525, 415, 129, 23);
108 | add(showPassword);
109 |
110 | // Sign up button
111 | signUpButton.setBackground(new Color(100, 149, 237));
112 | signUpButton.setFont(new Font("Tahoma", Font.PLAIN, 17));
113 | signUpButton.setBounds(690, 550, 210, 50);
114 | add(signUpButton);
115 | }
116 |
117 | public JTextField getFirstNameField() { return firstNameField; }
118 |
119 | public JTextField getLastNameField() { return lastNameField; }
120 |
121 | public JTextField getEmailField() { return emailField; }
122 |
123 | public JTextField getPhoneNumberField() { return phoneNumberField; }
124 |
125 | public JPasswordField getPasswordField() { return passwordField; }
126 |
127 | public JPasswordField getConfirmPasswordField() { return confirmPasswordField; }
128 |
129 | public JCheckBox getShowPassword() { return showPassword; }
130 |
131 | public JButton getSignUpButton() { return signUpButton; }
132 | }
133 |
--------------------------------------------------------------------------------
/src/controller/RegisterController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.ScreenType;
4 | import view.RegisterScreen;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.*;
8 | import java.io.File;
9 | import java.io.FileWriter;
10 | import java.util.Scanner;
11 | import java.util.UUID;
12 |
13 | public class RegisterController implements ActionListener {
14 |
15 | private RegisterScreen registerScreen; // Get access to register screen
16 |
17 | // Constructor
18 | public RegisterController(RegisterScreen registerScreen) {
19 | this.registerScreen = registerScreen;
20 | setupListeners();
21 | }
22 |
23 | // Setup listeners
24 | public void setupListeners() {
25 | registerScreen.getSignUpButton().addActionListener(this);
26 | registerScreen.getShowPassword().addActionListener(this);
27 | }
28 |
29 | @Override
30 | public void actionPerformed(ActionEvent e) {
31 | if (e.getSource() == registerScreen.getSignUpButton())
32 | createAccount();
33 | else if (e.getSource() == registerScreen.getShowPassword())
34 | showPassword();
35 | }
36 |
37 | // Write account to a text file
38 | private void createAccount() {
39 | // Fields to get input values
40 | String firstName = registerScreen.getFirstNameField().getText();
41 | String lastName = registerScreen.getLastNameField().getText();
42 | String email = registerScreen.getEmailField().getText().toLowerCase();
43 | String password = registerScreen.getPasswordField().getText();
44 | String cPassword = registerScreen.getConfirmPasswordField().getText();
45 | String phoneNumber = registerScreen.getPhoneNumberField().getText();
46 | String uniqueID = UUID.randomUUID().toString();
47 |
48 | // Check if first name and last name fields are empty
49 | if (firstName.length() == 0 || lastName.length() == 0) {
50 | JOptionPane.showMessageDialog(null, "Please fill in your name",
51 | "Error", JOptionPane.ERROR_MESSAGE);
52 | return;
53 | // Check if the email is less than 3 characters long and contains the @ symbol
54 | } else if (email.length() < 3 && !email.contains("@")) {
55 | JOptionPane.showMessageDialog(null, "Please enter a valid email address",
56 | "Error", JOptionPane.ERROR_MESSAGE);
57 | return;
58 | // Check if passwords match and if the password is atleast 8 characters long
59 | } else if (!password.equals(cPassword) || password.length() < 8) {
60 | JOptionPane.showMessageDialog(null, "Please enter a valid password",
61 | "Error", JOptionPane.ERROR_MESSAGE);
62 | registerScreen.getPasswordField().setText(""); // Set password field to blank
63 | registerScreen.getConfirmPasswordField().setText(""); // Set confirm password field to blank
64 | return;
65 | // Check if phone number is less than 3 characters long
66 | } else if (phoneNumber.length() < 3) {
67 | JOptionPane.showMessageDialog(null, "Please enter a valid phone number",
68 | "Error", JOptionPane.ERROR_MESSAGE);
69 | return;
70 | }
71 |
72 | try {
73 |
74 | // Read registration text file
75 | Scanner input = new Scanner(new File("accounts/registration.txt"));
76 |
77 | // Check if an account already has the same email as inputted
78 | while (input.hasNextLine()) {
79 | String line = input.nextLine();
80 | if (line.contains(email)) {
81 | JOptionPane.showMessageDialog(null, "An account with this email has already"
82 | + " been created!",
83 | "Error", JOptionPane.ERROR_MESSAGE);
84 | return;
85 | }
86 | }
87 |
88 | // Write account information to registration text file
89 | FileWriter Writer = new FileWriter("accounts/registration.txt", true);
90 | Writer.write("" + firstName + "," + lastName + "," + email + "," + password + ","
91 | + phoneNumber + "," + uniqueID + ",");
92 | Writer.write(System.getProperty("line.separator"));
93 | Writer.close(); // Close writer
94 | ApplicationController.accountImport.importAccounts("accounts/registration.txt"); // Reload imports
95 | JOptionPane.showMessageDialog(null, "Hello " + firstName +
96 | "! Your account has been created");
97 |
98 | // Switch to login screen
99 | ApplicationController.switchScreen(ApplicationController.screens[ScreenType.LOGIN_SCREEN.getValue()]);
100 |
101 | } catch (Exception e) {
102 | System.err.println("An error occurred: " + e);
103 | }
104 | }
105 |
106 | // Show and hide password
107 | private void showPassword() {
108 | if (registerScreen.getShowPassword().isSelected()) {
109 | registerScreen.getPasswordField().setEchoChar((char) 0);
110 | registerScreen.getConfirmPasswordField().setEchoChar((char) 0);
111 | } else {
112 | registerScreen.getPasswordField().setEchoChar('•');
113 | registerScreen.getConfirmPasswordField().setEchoChar('•');
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/controller/LoginController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.Account;
4 | import model.ScreenType;
5 | import view.LoginScreen;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 | import java.awt.event.ActionListener;
10 | import java.io.File;
11 | import java.io.FileNotFoundException;
12 | import java.util.Scanner;
13 |
14 | public class LoginController implements ActionListener {
15 |
16 | private LoginScreen loginScreen; // Access login screen
17 | private String emailInput; // Get email input
18 |
19 | // Constructor
20 | public LoginController(LoginScreen loginScreen) {
21 | this.loginScreen = loginScreen;
22 | setupListeners();
23 |
24 | }
25 |
26 | // Setup listeners
27 | public void setupListeners() {
28 | loginScreen.getLoginButton().addActionListener(this);
29 | loginScreen.getRegisterButton().addActionListener(this);
30 | loginScreen.getShowPassword().addActionListener(this);
31 | }
32 |
33 | @Override
34 | public void actionPerformed(ActionEvent e) {
35 | if (e.getSource() == loginScreen.getLoginButton()) { // User clicked login button
36 | loginAccount(); // Call loginAccount method
37 | } else if (e.getSource() == loginScreen.getRegisterButton()) { // User clicked register button
38 | // Switch to register screen
39 | ApplicationController.switchScreen(ApplicationController.screens[ScreenType.REGISTER_SCREEN.getValue()]);
40 | } else if (e.getSource() == loginScreen.getShowPassword()) // User checked show password box
41 | showPassword();
42 | }
43 |
44 | // Logging into account by reading file
45 | // Check if the inputted account exists and set the account information to the current account
46 | private void loginAccount() {
47 | boolean accountFound = false; // Mark when an account is logged in
48 | emailInput = loginScreen.getEmailField().getText().toLowerCase(); // Get email input
49 | String passwordInput = loginScreen.getPasswordField().getText(); // Get password input
50 |
51 | try {
52 | // Read from registration.txt file
53 | Scanner input = new Scanner(new File("accounts/registration.txt"));
54 |
55 | // Reads through the lines of the text file until an account is found
56 | while (input.hasNextLine() && !accountFound) {
57 | String str = input.nextLine();
58 | String[] strArray = str.split(",");
59 |
60 | // Check if the user input matches the registration file information
61 | if (emailInput.equals(strArray[2]) && passwordInput.equals(strArray[3])) {
62 | accountFound = true; // Found account login
63 |
64 | // Switch to home screen
65 | ApplicationController.switchScreen(ApplicationController.screens[ScreenType.HOME_SCREEN.getValue()]);
66 |
67 | ApplicationController.currentAppointments.clear(); // Clear current appointments
68 | ApplicationController.appointments.clear(); // Clear appointments
69 |
70 | // Search through all accounts in the Arraylist
71 | for (int index = 0; index < ApplicationController.accounts.size()-1; index++) {
72 | Account account = ApplicationController.accounts.get(index);
73 |
74 | // Set the account information to the logged in account
75 | if (account.toString().contains(emailInput)) {
76 | ApplicationController.currentFirstName = account.getFirstName();
77 | ApplicationController.currentLastName = account.getLastName();
78 | ApplicationController.currentEmail = account.getEmail();
79 | ApplicationController.currentPhoneNumber = account.getPhoneNumber();
80 | ApplicationController.currentID = account.getUUID();
81 | ApplicationController.homeController.setupLabel();
82 | ApplicationController.profileController.setupLabel();
83 | }
84 | }
85 |
86 | // Reload imports
87 | ApplicationController.appointmentImport.importAppointments("accounts/appointments.txt");
88 |
89 | // Show login prompt
90 | JOptionPane.showMessageDialog(null, "Login successful",
91 | "Welcome", JOptionPane.INFORMATION_MESSAGE);
92 |
93 | // Otherwise, the users input does not match an email and password
94 | } else {
95 | loginScreen.getPasswordField().setText("");
96 | accountFound = false;
97 | }
98 | }
99 |
100 | // Show error message if an account is not found
101 | if (accountFound == false) {
102 | JOptionPane.showMessageDialog(null, "Invalid login" +
103 | " \nPlease check your email and password", "Error", JOptionPane.ERROR_MESSAGE);
104 | input.close(); // Close input
105 | }
106 |
107 | } catch (FileNotFoundException e) {
108 | System.err.println("An error occurred: " + e);
109 | }
110 | }
111 |
112 | // Show and hide password
113 | private void showPassword() {
114 | if (loginScreen.getShowPassword().isSelected())
115 | loginScreen.getPasswordField().setEchoChar((char) 0);
116 | else
117 | loginScreen.getPasswordField().setEchoChar('•');
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/src/view/BookingScreen.java:
--------------------------------------------------------------------------------
1 | package view;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.util.Hashtable;
6 |
7 | public class BookingScreen extends Screen {
8 |
9 | // Fields
10 | private JLabel bookAppointmentLabel = new JLabel(new ImageIcon("images/bookAppointmentTitle.png"));
11 | private JLabel selectDateLabel = new JLabel("Select a date");
12 | private JLabel selectCutLabel = new JLabel("Select your haircut ($20)");
13 | private JLabel additionalLabel = new JLabel("Additional");
14 | private JLabel topLabel = new JLabel("Top (inches)");
15 | private JLabel sideLabel = new JLabel("Side");
16 | private Hashtable lengthTable = new Hashtable();
17 | private JSlider topLengthSlider = new JSlider(JSlider.HORIZONTAL, 0, 10, 0);
18 | private JCheckBox buzzCutCheckBox = new JCheckBox("Buzz Cut", false);
19 | private JCheckBox thinOutCheckBox = new JCheckBox("Thin Out", false);
20 | private JRadioButton fadeButton = new JRadioButton("Fade", false);
21 | private JRadioButton taperButton = new JRadioButton("Taper", false);
22 | private JCheckBox skinFadeCheckBox = new JCheckBox("Skin Fade/Taper");
23 | private ButtonGroup sideType = new ButtonGroup();
24 | private JComboBox haircutSelect = new JComboBox();
25 | private JLabel sideToLabel = new JLabel("to");
26 | private JComboBox sideOneSelect = new JComboBox();
27 | private JComboBox sideTwoSelect = new JComboBox();
28 | private JCheckBox designCheckBox = new JCheckBox("Design (+$0 - $10)", false);
29 | private JCheckBox beardCheckBox = new JCheckBox("Beard (+$5)", false);
30 | private JCheckBox lineUpCheckBox = new JCheckBox("Front Line Up", false);
31 | private JButton bookNowButton = new JButton("BOOK NOW");
32 | private JLabel guardLabel = new JLabel("Highest Guard Lowest Guard");
33 | private String[] guardOptions = new String[] {
34 | "- Select -", "0", "0.5", "1.0", "1.5", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0",
35 | };
36 | private JLabel bookingHeader = new JLabel(new ImageIcon("images/bookingHeader.png"));
37 |
38 | public BookingScreen() {
39 |
40 | getBackButton().setVisible(false);
41 | setBackground(new Color(176, 196, 219));
42 |
43 | sideType.add(taperButton);
44 | sideType.add(fadeButton);
45 |
46 | bookAppointmentLabel.setBounds(0, 0, 1600, 900);
47 | add(bookAppointmentLabel);
48 |
49 | bookingHeader.setBounds(0, 0, 1600, 900);
50 | add(bookingHeader);
51 |
52 | selectCutLabel.setBounds(75, 170, 500, 100);
53 | selectCutLabel.setFont(new Font("Tahoma", Font.BOLD, 25));
54 | add(selectCutLabel);
55 |
56 | selectDateLabel.setBounds(1075, 170, 500, 100);
57 | selectDateLabel.setFont(new Font("Tahoma", Font.BOLD, 25));
58 | add(selectDateLabel);
59 |
60 | topLabel.setBounds(160, 220, 520, 100);
61 | topLabel.setFont(new Font("Tahoma", Font.BOLD, 20));
62 | add(topLabel);
63 |
64 | sideLabel.setBounds(550, 220, 520, 100);
65 | sideLabel.setFont(new Font("Tahoma", Font.BOLD, 20));
66 | add(sideLabel);
67 |
68 | fadeButton.setBounds(450, 280, 170, 50);
69 | fadeButton.setBackground(new Color(176, 196, 219));
70 | fadeButton.setFont(new Font("Tahoma", Font.PLAIN, 17));
71 | add(fadeButton);
72 |
73 | taperButton.setBounds(620, 280, 170, 50);
74 | taperButton.setBackground(new Color(176, 196, 219));
75 | taperButton.setFont(new Font("Tahoma", Font.PLAIN, 17));
76 | add(taperButton);
77 |
78 | haircutSelect.setBounds(450, 340, 250, 30);
79 | haircutSelect.setBackground(new Color (172, 181, 182));
80 | haircutSelect.setFont(new Font("Tahoma", Font.PLAIN, 17));
81 | haircutSelect.setEnabled(false);
82 | haircutSelect.addItem("Please select a haircut!");
83 | add(haircutSelect);
84 |
85 | // Hashtable values to allow decimal values on slider
86 | lengthTable.put(0, new JLabel("0"));
87 | lengthTable.put(1, new JLabel("0.5"));
88 | lengthTable.put(2, new JLabel("1"));
89 | lengthTable.put(3, new JLabel("1.5"));
90 | lengthTable.put(4, new JLabel("2"));
91 | lengthTable.put(5, new JLabel("2.5"));
92 | lengthTable.put(6, new JLabel("3"));
93 | lengthTable.put(7, new JLabel("3.5"));
94 | lengthTable.put(8, new JLabel("4"));
95 | lengthTable.put(9, new JLabel("4.5"));
96 | lengthTable.put(10, new JLabel("5"));
97 | topLengthSlider.setLabelTable(lengthTable);
98 |
99 | topLengthSlider.setBounds(80, 290, 300, 75);
100 | topLengthSlider.setBackground(new Color(176, 196, 219));
101 | topLengthSlider.setMajorTickSpacing(5);
102 | topLengthSlider.setPaintTicks(true);
103 | topLengthSlider.setPaintLabels(true);
104 | add(topLengthSlider);
105 |
106 | skinFadeCheckBox.setBounds(450, 370, 150, 50);
107 | skinFadeCheckBox.setBackground(new Color(176, 196, 219));
108 | skinFadeCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
109 | skinFadeCheckBox.setEnabled(false);
110 | add(skinFadeCheckBox);
111 |
112 | guardLabel.setBounds(450, 420, 270, 30);
113 | guardLabel.setFont(new Font("Tahoma", Font.PLAIN, 15));
114 | add(guardLabel);
115 |
116 | sideOneSelect.setBounds(450, 450, 90, 30);
117 | sideOneSelect.setEnabled(false);
118 | sideOneSelect.setBackground(new Color (172, 181, 182));
119 | sideOneSelect.setFont(new Font("Tahoma", Font.PLAIN, 10));
120 | sideOneSelect.addItem("Highest Guard");
121 | sideOneSelect.setModel(new DefaultComboBoxModel(guardOptions));
122 | add(sideOneSelect);
123 |
124 | sideTwoSelect.setBounds(610, 450, 90, 30);
125 | sideTwoSelect.setEnabled(false);
126 | sideTwoSelect.setBackground(new Color (172, 181, 182));
127 | sideTwoSelect.setFont(new Font("Tahoma", Font.PLAIN, 10));
128 | sideTwoSelect.addItem("Lowest Guard");
129 | sideTwoSelect.setModel(new DefaultComboBoxModel(guardOptions));
130 | add(sideTwoSelect);
131 |
132 | sideToLabel.setBounds(565, 450, 90, 30);
133 | sideToLabel.setBackground(new Color(176, 196, 219));
134 | sideToLabel.setFont(new Font("Tahoma", Font.PLAIN, 17));
135 | add(sideToLabel);
136 |
137 | buzzCutCheckBox.setBounds(100, 350, 150, 50);
138 | buzzCutCheckBox.setBackground(new Color(176, 196, 219));
139 | buzzCutCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
140 | add(buzzCutCheckBox);
141 |
142 | thinOutCheckBox.setBounds(250, 350, 150, 50);
143 | thinOutCheckBox.setBackground(new Color(176, 196, 219));
144 | thinOutCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
145 | add(thinOutCheckBox);
146 |
147 | additionalLabel.setBounds(75, 475, 500, 100);
148 | additionalLabel.setFont(new Font("Tahoma", Font.BOLD, 25));
149 | add(additionalLabel);
150 |
151 | designCheckBox.setBounds(100, 550, 200, 50);
152 | designCheckBox.setBackground(new Color(176, 196, 219));
153 | designCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
154 | add(designCheckBox);
155 |
156 | beardCheckBox.setBounds(100, 600, 150, 50);
157 | beardCheckBox.setBackground(new Color(176, 196, 219));
158 | beardCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
159 | add(beardCheckBox);
160 |
161 | lineUpCheckBox.setBounds(100, 650, 150, 50);
162 | lineUpCheckBox.setBackground(new Color(176, 196, 219));
163 | lineUpCheckBox.setFont(new Font("Tahoma", Font.PLAIN, 17));
164 | add(lineUpCheckBox);
165 |
166 | bookNowButton.setBackground(new Color(30, 75, 135));
167 | bookNowButton.setForeground(Color.WHITE);
168 | bookNowButton.setFont(new Font("Tahoma", Font.PLAIN, 30));
169 | bookNowButton.setBorder(null);
170 | bookNowButton.setBounds(700, 700, 250, 100);
171 | add(bookNowButton);
172 |
173 | }
174 |
175 | public JSlider getTopLengthSlider() { return topLengthSlider; }
176 |
177 | public JCheckBox getBuzzCutCheckBox() { return buzzCutCheckBox; }
178 |
179 | public JCheckBox getThinOutCheckBox() { return thinOutCheckBox; }
180 |
181 | public JRadioButton getFadeButton() { return fadeButton; }
182 |
183 | public JRadioButton getTaperButton() { return taperButton; }
184 |
185 | public JComboBox getHaircutSelect() { return haircutSelect; }
186 |
187 | public JCheckBox getDesignCheckBox() { return designCheckBox; }
188 |
189 | public JCheckBox getBeardCheckBox() { return beardCheckBox; }
190 |
191 | public JCheckBox getLineUpCheckBox() { return lineUpCheckBox; }
192 |
193 | public JButton getBookNowButton() { return bookNowButton; }
194 |
195 | public JCheckBox getSkinFadeCheckBox() { return skinFadeCheckBox; }
196 |
197 | public JComboBox getSideOneSelect() { return sideOneSelect; }
198 |
199 | public JComboBox getSideTwoSelect() { return sideTwoSelect; }
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/src/controller/BookingController.java:
--------------------------------------------------------------------------------
1 | package controller;
2 |
3 | import model.ScreenType;
4 | import view.BookingScreen;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 | import java.awt.event.ActionListener;
9 | import java.io.FileWriter;
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | public class BookingController implements ActionListener {
15 |
16 | public BookingScreen bookingScreen; // Access booking screen
17 |
18 | // Fields to get time and cost
19 | private int timeMin; // Minutes
20 | private int timeMax; // Minutes
21 | private double costMin = 20; // Dollars
22 | private double costMax = 20; // Dollars
23 |
24 | // Constructor
25 | public BookingController(BookingScreen bookingScreen) {
26 | this.bookingScreen = bookingScreen;
27 | setupListeners();
28 | }
29 |
30 | // Set up Listeners
31 | private void setupListeners() {
32 | bookingScreen.getBuzzCutCheckBox().addActionListener(this);
33 | bookingScreen.getFadeButton().addActionListener(this);
34 | bookingScreen.getTaperButton().addActionListener(this);
35 | bookingScreen.getHaircutSelect().addActionListener(this);
36 | bookingScreen.getSkinFadeCheckBox().addActionListener(this);
37 | bookingScreen.getSideOneSelect().addActionListener(this);
38 | bookingScreen.getSideTwoSelect().addActionListener(this);
39 | bookingScreen.getBookNowButton().addActionListener(this);
40 | bookingScreen.getHaircutSelect().addActionListener(this);
41 | }
42 |
43 | @Override
44 | public void actionPerformed(ActionEvent e) {
45 |
46 | // Check top style selection
47 | if (bookingScreen.getBuzzCutCheckBox().isSelected())
48 | bookingScreen.getTopLengthSlider().setEnabled(false);
49 | else if (!bookingScreen.getBuzzCutCheckBox().isSelected())
50 | bookingScreen.getTopLengthSlider().setEnabled(true);
51 |
52 | // Check side style selection
53 | if (bookingScreen.getFadeButton().isSelected()) {
54 | changeHaircutSelection(1);
55 | bookingScreen.getSideOneSelect().setEnabled(true);
56 | bookingScreen.getSideTwoSelect().setEnabled(true);
57 | bookingScreen.enableCalendar();
58 | } else if (bookingScreen.getTaperButton().isSelected()) {
59 | changeHaircutSelection(2);
60 | bookingScreen.getSideOneSelect().setEnabled(true);
61 | bookingScreen.getSideTwoSelect().setEnabled(true);
62 | bookingScreen.enableCalendar();
63 | } else if (!bookingScreen.getTaperButton().isSelected() && !bookingScreen.getFadeButton().isSelected()){
64 | changeHaircutSelection(0);
65 | }
66 |
67 | // Check if skin fade is selected
68 | if (bookingScreen.getSkinFadeCheckBox().isSelected()) {
69 | bookingScreen.getSideOneSelect().setEnabled(false);
70 | bookingScreen.getSideTwoSelect().setEnabled(false);
71 | } else if (!bookingScreen.getSkinFadeCheckBox().isSelected()
72 | && !bookingScreen.getSkinFadeCheckBox().isEnabled()) {
73 | bookingScreen.getSideOneSelect().setEnabled(true);
74 | bookingScreen.getSideTwoSelect().setEnabled(true);
75 | }
76 |
77 | // Book now button
78 | if (e.getSource() == bookingScreen.getBookNowButton())
79 | checkInputs();
80 | }
81 |
82 | // Method for haircut dropdown options
83 | private void changeHaircutSelection(int type) {
84 | bookingScreen.getHaircutSelect().setEnabled(true); // Allow user to select haircut
85 | bookingScreen.getSkinFadeCheckBox().setEnabled(true); // Allow user to choose skin fade or taper
86 | List sideOptions = new ArrayList<>();
87 |
88 | if (type == 1) { // User selected fade
89 | if (!bookingScreen.getHaircutSelect().getItemAt(0).toString().contains("Fade")) {
90 | String [] optionList = new String[] {"- Select Fade-", "Low Fade", "Mid Fade", "High Fade"};
91 | sideOptions.addAll(Arrays.asList(optionList));
92 | bookingScreen.getHaircutSelect().setModel
93 | (new DefaultComboBoxModel(sideOptions.toArray(new String[0])));
94 | }
95 | } else if (type == 2) { // User selected taper
96 | if (!bookingScreen.getHaircutSelect().getItemAt(0).toString().contains("Taper")) {
97 | String[] optionList = new String[]{"- Select Taper -", "Low Taper", "Mid Taper", "High Taper"};
98 | sideOptions.addAll(Arrays.asList(optionList));
99 | bookingScreen.getHaircutSelect().setModel
100 | (new DefaultComboBoxModel(sideOptions.toArray(new String[0])));
101 | }
102 | } else { // User does not have any haircut type selected
103 | bookingScreen.getHaircutSelect().setEnabled(false);
104 | bookingScreen.getHaircutSelect().addItem("Please select a haircut");
105 | }
106 | }
107 |
108 | // Method to check if user inputs are valid
109 | private void checkInputs() {
110 | int firstSideValue = bookingScreen.getSideOneSelect().getSelectedIndex();
111 | int secondSideValue = bookingScreen.getSideTwoSelect().getSelectedIndex();
112 |
113 | // Check if side types have not been selected
114 | if (!bookingScreen.getFadeButton().isSelected() && !bookingScreen.getTaperButton().isSelected()) {
115 | JOptionPane.showMessageDialog(null, "Please select a side type!",
116 | "Error", JOptionPane.ERROR_MESSAGE);
117 | return;
118 | }
119 | else if (bookingScreen.getHaircutSelect().getSelectedIndex() == 0) {
120 | JOptionPane.showMessageDialog(null, "Please select a side style!",
121 | "Error", JOptionPane.ERROR_MESSAGE);
122 | return;
123 | }
124 | // Check if side lengths are inputted properly by user
125 | else if (firstSideValue < secondSideValue) {
126 | JOptionPane.showMessageDialog(null, "Please select a proper side length order!",
127 | "Error", JOptionPane.ERROR_MESSAGE);
128 | return;
129 | }
130 | // Check if a side length has not been inputted
131 | else if (!bookingScreen.getSkinFadeCheckBox().isSelected()) {
132 | if (bookingScreen.getSideTwoSelect().getSelectedIndex() == 0 ||
133 | bookingScreen.getSideTwoSelect().getSelectedIndex() == 0) {
134 | JOptionPane.showMessageDialog(null, "Please select a side length!",
135 | "Error", JOptionPane.ERROR_MESSAGE);
136 | return;
137 | }
138 | }
139 |
140 | bookAppointment(); // Call bookAppointment method
141 | ApplicationController.appointments.clear(); // Clear appointments
142 | ApplicationController.currentAppointments.clear(); // Clear appointments
143 | ApplicationController.appointmentImport.importAppointments("accounts/appointments.txt"); // Reload imports
144 | }
145 |
146 | // Method to write user input information to the appointments.txt file
147 | public void bookAppointment() {
148 | // Fields to get input values
149 | double selectedLengthValue = (double) bookingScreen.getTopLengthSlider().getValue() / 2;
150 | boolean selectedBuzzCut = bookingScreen.getBuzzCutCheckBox().isSelected();
151 | boolean selectedThinOut = bookingScreen.getThinOutCheckBox().isSelected();
152 | boolean selectedFade = bookingScreen.getFadeButton().isSelected();
153 | boolean selectedTaper = bookingScreen.getTaperButton().isSelected();
154 | boolean selectedSkinFade = bookingScreen.getSkinFadeCheckBox().isSelected();
155 | String firstSideValue = bookingScreen.getSideOneSelect().getSelectedItem().toString();
156 | String secondSideValue = bookingScreen.getSideTwoSelect().getSelectedItem().toString();
157 | boolean selectedDesign = bookingScreen.getDesignCheckBox().isSelected();
158 | boolean selectedBeard = bookingScreen.getBeardCheckBox().isSelected();
159 | boolean selectedLineUp = bookingScreen.getLineUpCheckBox().isSelected();
160 | String uniqueID = ApplicationController.currentID;
161 | int month = bookingScreen.getCalendar().getDate().getMonth();
162 | int date = bookingScreen.getCalendar().getDate().getDate();
163 | int year = bookingScreen.getCalendar().getDate().getYear() + 1900;
164 | String topLength;
165 | String buzzCut = null;
166 | String thinOut = null;
167 | String fadeType = null;
168 | String taperType = null;
169 | String sideType = null;
170 | String design = null;
171 | String beard = null;
172 | String lineUp = null;
173 | String appointmentDate;
174 | String time;
175 | String cost;
176 |
177 | // Skin fade
178 | if (bookingScreen.getSideOneSelect().getSelectedIndex() == 0)
179 | firstSideValue = "";
180 | if (bookingScreen.getSideTwoSelect().getSelectedIndex() == 0)
181 | secondSideValue = "";
182 |
183 | calculateTimeAndCost(); // Calculate time and cost
184 |
185 | // Setting variable text
186 | time = "" + timeMin + " min - " + timeMax + " min";
187 | cost = "$" + costMin;
188 | topLength = selectedLengthValue + "";
189 | if (selectedDesign)
190 | cost = "$" + costMin + " - $" + costMax;
191 | if (selectedBuzzCut) {
192 | buzzCut = "Buzz Cut";
193 | topLength = null;
194 | } if (selectedThinOut)
195 | thinOut = "Thin Out Top";
196 | if (selectedFade)
197 | fadeType = bookingScreen.getHaircutSelect().getSelectedItem().toString();
198 | if (selectedTaper)
199 | taperType = bookingScreen.getHaircutSelect().getSelectedItem().toString();
200 |
201 | int i = bookingScreen.getHaircutSelect().getSelectedItem().toString().indexOf(" ");
202 | if (!selectedSkinFade)
203 | sideType = firstSideValue + " to " + secondSideValue;
204 | if (selectedSkinFade && selectedFade) {
205 | fadeType = bookingScreen.getHaircutSelect().getSelectedItem().toString().substring(0, i) + " Skin Fade";
206 | sideType = null;
207 | } else if (selectedSkinFade && selectedTaper) {
208 | taperType = bookingScreen.getHaircutSelect().getSelectedItem().toString().substring(0, i) + " Skin Fade";
209 | sideType = null;
210 | }
211 | if (selectedDesign) {
212 | design = "Requested Design";
213 | cost = "$" + costMin + " - $" + costMax;
214 | }
215 | if (selectedBeard) {
216 | beard = "Requested Beard Work";
217 | cost = "$" + costMin + " - $" + costMax;
218 | }
219 | if (selectedLineUp)
220 | lineUp = "Requested Line Up";
221 | appointmentDate = month + "/" + date + "/" + year;
222 |
223 | try {
224 | // Write booking information to appointments text file
225 | FileWriter Writer = new FileWriter("accounts/appointments.txt", true);
226 | Writer.write("" + topLength + "," + buzzCut + "," + thinOut + "," + fadeType + ","
227 | + taperType + "," + sideType + "," + design + "," + beard + "," + lineUp + ","
228 | + appointmentDate + "," + time + "," + cost + "," + uniqueID + ",");
229 | Writer.write(System.getProperty("line.separator"));
230 | Writer.close(); // Close writer
231 | ApplicationController.accountImport.importAccounts("accounts/appointments.txt"); // Reload imports
232 | JOptionPane.showMessageDialog(null, "Your appointment has been booked!", "Success",
233 | JOptionPane.INFORMATION_MESSAGE);
234 |
235 | // Reset values
236 | timeMin = 0;
237 | timeMax = 0;
238 | costMin = 20;
239 | costMax = costMin;
240 |
241 | // Switch to home screen
242 | ApplicationController.switchScreen(ApplicationController.screens[ScreenType.HOME_SCREEN.getValue()]);
243 |
244 | } catch (Exception e) {
245 | System.err.println("An error occurred: " + e);
246 | }
247 | }
248 |
249 | // Method to calculate time and cost of a haircut based on the user's inputs
250 | public void calculateTimeAndCost() {
251 | // Fields to get input values
252 | double lengthValue = (double) bookingScreen.getTopLengthSlider().getValue() / 2;
253 | boolean buzzCut = bookingScreen.getBuzzCutCheckBox().isSelected();
254 | boolean thinOut = bookingScreen.getThinOutCheckBox().isSelected();
255 | boolean selectedFade = bookingScreen.getFadeButton().isSelected();
256 | boolean selectedTaper = bookingScreen.getTaperButton().isSelected();
257 | boolean selectedSkinFade = bookingScreen.getSkinFadeCheckBox().isSelected();
258 | boolean selectedDesign = bookingScreen.getDesignCheckBox().isSelected();
259 | boolean selectedBeard = bookingScreen.getBeardCheckBox().isSelected();
260 | boolean selectedLineUp = bookingScreen.getLineUpCheckBox().isSelected();
261 |
262 | // Add a minimum and maximum estimated time for haircut inputs
263 | if (lengthValue > 0) {
264 | timeMin += 5;
265 | timeMax += 20;
266 | } else if (buzzCut) {
267 | timeMin += 5;
268 | timeMax += 10;
269 | }
270 | if (thinOut) {
271 | timeMin += 5;
272 | timeMax += 10;
273 | }
274 | if (selectedSkinFade) {
275 | timeMin += 30;
276 | timeMax += 40;
277 | } else if (selectedFade) {
278 | timeMin += 25;
279 | timeMax += 35;
280 | }
281 | if (selectedTaper) {
282 | timeMin += 20;
283 | timeMax += 30;
284 | }
285 | if (selectedDesign) {
286 | timeMin += 5;
287 | timeMax += 15;
288 | costMax += 10;
289 | }
290 | if (selectedBeard) {
291 | timeMin += 5;
292 | timeMax += 10;
293 | costMax += 5;
294 | }
295 | if (selectedLineUp) {
296 | timeMin += 2;
297 | timeMax += 5;
298 | }
299 | }
300 | }
301 |
--------------------------------------------------------------------------------