First prints the menu options for the activity type and then asks for the user input. Then it runs a series
+ of case statements to return a string based ob the user input. This string is used to set the category type of
+ Activity class.
This constructor sets the new employee object, and at the same time calls the
+ loadAppointmentsFromFile method to add appointments to ArrayList, if they exists.
public Activity(java.lang.String description,
+ java.lang.String category)
+
Constructor calls the two setters to set the parameters passed into constructor. It receives the two
+ string values as the description of the type of activity user wants.
+
+
Parameters:
+
description - The description of the activity.
+
category - Predefined string passed by makeAppointmentFromUserInput method from Scheduler class.
public class Appointment
+extends java.lang.Object
+implements java.io.Serializable
+
This class helps to make the Appointment object that stores the user's name, phone number, appointment date
+ and time, and type of activity to be done.
This constructor chains to the another constructor which takes two different strings for the first
+ and last names. It splits the full name into two parts in the constructor call
This is the class where everything happens - making appointments, saving appointments, changing the appointments,
+ saving the appointments to file, retrieving the appointments from file, entering the information about
+ appointments, making objects and instances.
This constructor sets the new employee object, and at the same time calls the
+ loadAppointmentsFromFile method to add appointments to ArrayList, if they exists.
Makes a new Appointment object by making several other objects such as TelephoneNumber and Activity;
+ takes in various information needed to make a Appointment.
This method takes a string value and concatenates it to a static string variable which is then
+ used to output messages to the JScrollPanel in the the Scheduler Viewer Class.
This constructor sets the new employee object, and at the same time calls the
+ loadAppointmentsFromFile method to add appointments to ArrayList, if they exists.
+
+
Parameters:
+
employee - The instantiated employee object, then set to the current employee object.
The launch method maintains a while loop that keep the program running. It also catches the exceptions thrown
+ by the execution of the program. This method calls two other methods displayMenu() and executeMenuItem() to
+ complete its functions. It exits the program if user selects O option.
This method takes a string value and concatenates it to a static string variable which is then
+ used to output messages to the JScrollPanel in the the Scheduler Viewer Class.
+ It is used to show daily string and appointment information.
+
+
Parameters:
+
msg - The string used to append the static string above
public static boolean saveAppointment(Appointment apt)
+
Saves the appointment to the ArrayList, but only after making sure that
+ it does not already exits in the ArrayList. Also sorts the ArrayList after saving the appointment by
+ using sort method.
+
+
Parameters:
+
apt - A complete appointment object returned by the makeAppointmentFromUserInput method. if null
+ is received, it means the appointment does not exists.
+
Returns:
+
boolean whether the appointment save was successful or not.
+ true if yes, false
+ if appointment save is not successful.
Finds the appointment in the ArrayList by using the Collections class' sort method. It passes three arguments to this
+ method, first - the ArrayList, second - a dummy appointment made by just using calendar object to help
+ in the searching, third - a new instance of the the SortAppointmentByCalendar class that extends
+ Comparable.
+
+
Parameters:
+
cal - helps in searching of appointment by date and time. It helps to create a dummy appointment that plays a
+ role to search appointments.
+
Returns:
+
appointment object - if present in the array; otherwise returns null.
public static boolean deleteAppointment(java.util.Calendar cal)
+
Deletes the appointment based on the date and time received as a calendar object. First it finds the appointment
+ by using the findAppointment method and then displays it. Then prompts the user to confirm the delete and then
+ deletes the appointment from the ArrayList.
+
+
Parameters:
+
cal - the calendar object by using which appointments will be searched.
+
Returns:
+
true - if delete was successful
+ false - if delete was not successful.
public static boolean changeAppointment(java.util.Calendar cal)
+
Changes the existing appointment's date and time to a new date and time.
+ First it finds the appointment by using the findAppointment method and if Appointment is found, displays it
+ and asks for confirmation, and then makes a new calendar object for the new sate and time. it then sets the
+ new calendar for the existing appointment.
+
+
Parameters:
+
cal - the calendar object used for searching the appointments.
+
Returns:
+
true - if change rime was successful
+ false - if changing time failed due to some reason.
public static void displayAppointment(java.util.Calendar cal)
+
Displays a single appointment based on the user entered date and time.
+ First, it calls the findAppointment method to search for the appointment and if no appointment is found, displays
+ a message that appointment does not exists. If the appointment is found, prints it by using the Appointment
+ class' toString method.
+
+
Parameters:
+
cal - the calendar object used to find the appointments. This method passed the the calendar parameter
+ to the findAppointment method.
public static void displayDaySchedule(java.util.Calendar cal)
+
Displays the day schedule by using a for loop to loop between 8 AM - 4 PM and calling displayAppointment method
+ in each iteration.
+
+
Parameters:
+
cal - the calendar object used to set the HOUR_OF_DAY to find all appointments on a given date, which is eventually
+ passed down to the findAppointment Class.
public static boolean saveAppointmentsToFile(java.util.ArrayList<Appointment> apts,
+ java.lang.String saveFile)
+
Saves the appointments in memory to a file on the disk. It uses FileOutputStream and ObjectOutputStream to
+ write the objects to file by using a enhanced for loop through the Appointments Array.
+
+
Parameters:
+
apts - The appointments array used to save the appointments declared at top of the class
+
saveFile - the actual name of the file to be saved on the disk.
+
Returns:
+
true - if save appointments to file was successful
+ false - if save appointments to file failed or an exception was thrown.
public static boolean loadAppointmentsFromFile(java.lang.String sourceFile,
+ java.util.ArrayList<Appointment> apts)
+
Does exactly opposite of saveAppointmentsToFile method by loading appointments from file
+ and adding them to array one by one. It first clears the ArrayList to remove all appointments that are
+ in the memory. Then uses FileInputStream and ObjectInputStream to read the objects from file.
+
+
Parameters:
+
sourceFile - the name of the file on the disk.
+
apts - the actual appointments ArrayList used to save appointments.
+
Returns:
+
whether the loading appointments was successful or not - true if yes; false if an error occurred or
+ an exception was thrown.
public static Appointment makeAppointmentFromUserInput()
+
Makes a new Appointment object by making several other objects such as TelephoneNumber and Activity;
+ takes in various information needed to make a Appointment. It also checks if the entered name has any illegal
+ characters or not. Makes a new Appointment by using the information and returns it.
+
+
Returns:
+
a new Appointment Object
+
Throws:
+
BadAppointmentDataException - if the name contains illegal characters or the name is greater
+ than the specified length, or if user only enters the single name.
public static java.util.Calendar makeCalendarFromUserInput(boolean suppressHour)
+
Makes a new Calendar Object by taking the user input. it calls another method to set the date of the
+ calendar instance. Sets the Calendar.setLenient to false so that user is not able to set the bad date for the
+ calendar.
+
+
Parameters:
+
suppressHour - used if user wants to take the date input only. Then it does not prompt the user for the
+ time input.
+
Returns:
+
the new calendar object made by the method after taking dates and times from the user.
This is the sub method used to set the appointment date as well as check for any bad date formats.
+ It uses a pre defined date format and matches all input date formats with the given format. In case
+ of a mismatch, it throws a new BadAppointmentDataException.
+
+
Parameters:
+
date - the string value to be parsed and matched with pre defined date format
+
cal - the calendar object created in previous method; used to set date.
Main method of the program. It instantiates a new Employee object of type Dentist and instantiates a new
+ Scheduler object by passing made dentist as parameter.
public class SortAppointmentByCalendar
+extends java.lang.Object
+implements java.util.Comparator<Appointment>
+
The class overwrites the compare method in the the Comparator interface and it helps to sort the
+ appointments in the ArrayList by returning a number based on comparison result.
public class TelephoneNumber
+extends java.lang.Object
+implements java.io.Serializable
+
The class helps to make the Telephone number object that validates, parses and processes the phone number.
+ It stores the phone number in three different fields.
public TelephoneNumber(java.lang.String phoneNumber)
+
Constructor receives the phone number string from the Scheduler class and processes it into different fields -
+ area code, prefix, and line number.
+ Makes sures that the phone number meets the specified formats and it does not contain any
+ illegal characters.
+ Then, extracts the substrings from the passed string and assign them to the various fields by converting them
+ to integer values.
+ Also makes sure that area code does not start with 0 or 1
+
+
Parameters:
+
phoneNumber - phone number passed by the Scheduler Class.
+
Throws:
+
BadAppointmentDataException - if the phone number does not meet the specified formats - that is -
+ contains illegal characters, has bad format, or the area code starts with 0 or 1.
Makes a new Appointment object by making several other objects such as TelephoneNumber and Activity;
+ takes in various information needed to make a Appointment.
This class helps to make the Appointment object that stores the user's name, phone number, appointment date
+ and time, and type of activity to be done.
This is the class where everything happens - making appointments, saving appointments, changing the appointments,
+ saving the appointments to file, retrieving the appointments from file, entering the information about
+ appointments, making objects and instances.
The class overwrites the compare method in the the Comparator interface and it helps to sort the
+ appointments in the ArrayList by returning a number based on comparison result.
This class helps to make the Appointment object that stores the user's name, phone number, appointment date
+ and time, and type of activity to be done.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Use
+
Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
This class helps to make the Appointment object that stores the user's name, phone number, appointment date
+ and time, and type of activity to be done.
This method takes a string value and concatenates it to a static string variable which is then
+ used to output messages to the JScrollPanel in the the Scheduler Viewer Class.
This is the class where everything happens - making appointments, saving appointments, changing the appointments,
+ saving the appointments to file, retrieving the appointments from file, entering the information about
+ appointments, making objects and instances.
This constructor sets the new employee object, and at the same time calls the
+ loadAppointmentsFromFile method to add appointments to ArrayList, if they exists.
The class overwrites the compare method in the the Comparator interface and it helps to sort the
+ appointments in the ArrayList by returning a number based on comparison result.
Makes a new Appointment object by making several other objects such as TelephoneNumber and Activity;
+ takes in various information needed to make a Appointment.
+
+
+
diff --git a/doc/stylesheet.css b/doc/stylesheet.css
new file mode 100644
index 0000000..98055b2
--- /dev/null
+++ b/doc/stylesheet.css
@@ -0,0 +1,574 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+
+@import url('resources/fonts/dejavu.css');
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.useSummary td.colFirst, .useSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor {
+ background-color:#FFFFFF;
+}
+.rowColor {
+ background-color:#EEEEEF;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+div.contentContainer ul.blockList li.blockList h2{
+ padding-bottom:0px;
+}
diff --git a/out/artifacts/CST8284_19F_Assignment4/CST8284_19F_Assignment4.jar b/out/artifacts/CST8284_19F_Assignment4/CST8284_19F_Assignment4.jar
new file mode 100644
index 0000000..796174c
Binary files /dev/null and b/out/artifacts/CST8284_19F_Assignment4/CST8284_19F_Assignment4.jar differ
diff --git a/out/artifacts/CST8284_19F_Assignment4_jar/CST8284_19F_Assignment4.jar b/out/artifacts/CST8284_19F_Assignment4_jar/CST8284_19F_Assignment4.jar
new file mode 100644
index 0000000..82dab14
Binary files /dev/null and b/out/artifacts/CST8284_19F_Assignment4_jar/CST8284_19F_Assignment4.jar differ
diff --git a/out/production/CST8284_19F_Assignment4/META-INF/MANIFEST.MF b/out/production/CST8284_19F_Assignment4/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..7ac2d42
--- /dev/null
+++ b/out/production/CST8284_19F_Assignment4/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: cst8284.asgmt4.scheduler.SchedulerLauncher
+
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Dentist.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Dentist.class
new file mode 100644
index 0000000..50dac91
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Dentist.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Employee.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Employee.class
new file mode 100644
index 0000000..d8330b7
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/employee/Employee.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Activity.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Activity.class
new file mode 100644
index 0000000..e2c2212
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Activity.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Appointment.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Appointment.class
new file mode 100644
index 0000000..b71a032
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Appointment.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$1.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$1.class
new file mode 100644
index 0000000..ae8976b
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$1.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$2.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$2.class
new file mode 100644
index 0000000..83bdf31
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$2.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$3.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$3.class
new file mode 100644
index 0000000..47ef577
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog$3.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog.class
new file mode 100644
index 0000000..833246c
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/AppointmentDialog.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/BadAppointmentDataException.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/BadAppointmentDataException.class
new file mode 100644
index 0000000..0669355
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/BadAppointmentDataException.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Scheduler.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Scheduler.class
new file mode 100644
index 0000000..b1aaa0e
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/Scheduler.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerLauncher.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerLauncher.class
new file mode 100644
index 0000000..fc904e4
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerLauncher.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerViewer.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerViewer.class
new file mode 100644
index 0000000..f37671d
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SchedulerViewer.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.class
new file mode 100644
index 0000000..58ca80c
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.class differ
diff --git a/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/TelephoneNumber.class b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/TelephoneNumber.class
new file mode 100644
index 0000000..1ea567b
Binary files /dev/null and b/out/production/CST8284_19F_Assignment4/cst8284/asgmt4/scheduler/TelephoneNumber.class differ
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..7ac2d42
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: cst8284.asgmt4.scheduler.SchedulerLauncher
+
diff --git a/src/cst8284/asgmt4/employee/Dentist.java b/src/cst8284/asgmt4/employee/Dentist.java
new file mode 100644
index 0000000..ea87a8e
--- /dev/null
+++ b/src/cst8284/asgmt4/employee/Dentist.java
@@ -0,0 +1,50 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: Dentist
+ * Date: 28 November 2019
+ */
+
+package cst8284.asgmt4.employee;
+
+import java.util.ArrayList;
+
+/**
+ * This class extends from the Employee class and helps to make a Dentist object that stores the full
+ * name of the Employee.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class Dentist extends Employee {
+
+ /**
+ * No-arg constructor.
+ */
+ public Dentist(){}
+
+ /**
+ * The 1-arg constructor for the Dentist class. Takes in the fullname passed and sets it to
+ * the superclass constructor.
+ *
+ * @param fullname the name passed tio the constructor and then it is passed to the {@link Employee} class.
+ */
+ public Dentist(String fullname){
+ super(fullname);
+ }
+
+ /**
+ * First prints the menu options for the activity type and then asks for the user input. Then it runs a series
+ * of case statements to return a string based ob the user input. This string is used to set the category type of
+ * {@link cst8284.asgmt4.scheduler.Activity} class.
+ *
+ * @return a activity type string that determines the type of activity user wants. Its pre defined, but is only
+ * returned when a user submits a valid choice.
+ */
+ @Override
+ public String[] getActivityType(){
+ String[] activity = {"Assessment", "Filling", "Crown", "Cosmetic Repairs"};
+
+ return activity;
+ }
+ }
diff --git a/src/cst8284/asgmt4/employee/Employee.java b/src/cst8284/asgmt4/employee/Employee.java
new file mode 100644
index 0000000..63e990f
--- /dev/null
+++ b/src/cst8284/asgmt4/employee/Employee.java
@@ -0,0 +1,65 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: Employee
+ * Date: 28 November 2019
+ */
+package cst8284.asgmt4.employee;
+
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * The employee abstract class that have the abstract methods and fields to store employee information.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public abstract class Employee {
+ /**
+ * The field used to store the current full name of the Employee.
+ */
+ private String fullName;
+ /**
+ * scanner object used to take user input.
+ */
+ protected static Scanner scan = new Scanner(System.in);
+
+
+ /**
+ * Constructor chains to the next 1-arg constructor and passes a default value.
+ */
+ protected Employee() {this("unknown");}
+
+ /**
+ * Calls the setter of fullname and passes it to be set by it.
+ * @param fullName full name passed for the employee
+ */
+ protected Employee(String fullName) {setName(fullName);}
+
+ /**
+ * Sets the passed name value to the fullName field.
+ * @param fullName value passed by the constructor
+ */
+ public void setName(String fullName) {this.fullName = fullName;}
+
+ /**
+ * Getter for fullName
+ * @return the fullname field
+ */
+ public String getName() {return fullName;}
+
+ /**
+ * Abstract method to be overridden by subclasses.
+ * @return String depicting the type of
+ */
+ public abstract String[] getActivityType();
+
+ /**
+ * Overridden toString method
+ * @return the current Employee name by using a getter
+ */
+ @Override
+ public String toString() {return getName();}
+
+}
\ No newline at end of file
diff --git a/src/cst8284/asgmt4/scheduler/Activity.java b/src/cst8284/asgmt4/scheduler/Activity.java
new file mode 100644
index 0000000..b535986
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/Activity.java
@@ -0,0 +1,89 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: Activity
+ * Date: 28 November 2019
+ */
+
+package cst8284.asgmt4.scheduler;
+
+import java.io.Serializable;
+
+/**
+ * This class helps to make an Activity Object that stores two fields - category of Appointment and
+ * description of Activity to be performed.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class Activity implements Serializable {
+
+ /**
+ * The variable used to store the description passed down by the setters and constructors.
+ */
+ private String descriptionOfWork;
+ /**
+ * The variable used to store the category passed down by the setters and constructors.
+ */
+ private String category;
+ public static final long serialVersionUID = 1L;
+
+
+ /**
+ * Constructor calls the two setters to set the parameters passed into constructor. It receives the two
+ * string values as the description of the type of activity user wants.
+ *
+ * @param description The description of the activity.
+ * @param category Predefined string passed by makeAppointmentFromUserInput method from Scheduler class.
+ */
+ public Activity(String description, String category){
+ setDescription(description);
+ setCategory(category);
+ }
+
+ /**
+ * Returns the description of work stored.
+ *
+ * @return The description of work.
+ */
+ public String getDescription() {
+ return descriptionOfWork;
+ }
+
+ /**
+ * Sets the passed parameter.
+ *
+ * @param s description of the type of work to be performed.
+ */
+ public void setDescription(String s) {
+ this.descriptionOfWork = s;
+ }
+
+ /**
+ * Returns the category.
+ *
+ * @return category string. It is pre-written in the {@link cst8284.asgmt4.employee.Employee } class.
+ */
+ public String getCategory() {
+ return category;
+ }
+
+ /**
+ * Sets the passed category.
+ *
+ * @param s Returns current category
+ */
+ public void setCategory(String s) {
+ this.category = s;
+ }
+
+ /**
+ * Prints the Activities to console
+ * @return Category and description of work in the string format, combined together, to be used by
+ * the {@link Appointment} class' toString method.
+ */
+ public String toString(){
+ return getCategory() + "\n" + getDescription();
+
+ }
+}
diff --git a/src/cst8284/asgmt4/scheduler/Appointment.java b/src/cst8284/asgmt4/scheduler/Appointment.java
new file mode 100644
index 0000000..c84c50f
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/Appointment.java
@@ -0,0 +1,166 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: Appointment
+ * Date: 28 November 2019
+ * references: https://www.geeksforgeeks.org/split-string-java-examples/
+ */
+
+package cst8284.asgmt4.scheduler;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+/**
+ * This class helps to make the Appointment object that stores the user's name, phone number, appointment date
+ * and time, and type of activity to be done.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class Appointment implements Serializable {
+
+ /**
+ * The calendar abject that stores the appointment date and time.
+ */
+ private Calendar aptDate;
+ /**
+ * Stores the first name of the customer
+ */
+ private String firstName;
+ /**
+ * Stores the last name of the customer
+ */
+ private String lastName;
+ /**
+ * Stores the phone number of the customer
+ */
+ private TelephoneNumber phone;
+ /**
+ * The Activity object that stores the info about type of Activity.
+ */
+ private Activity activity;
+ public static final long serialVersionUID = 1L;
+
+ /**
+ * This constructor chains to the another constructor which takes two different strings for the first
+ * and last names. It splits the full name into two parts in the constructor call
+ *
+ * @param cal Calendar object
+ * @param fullName full name of the person
+ * @param phone TelephoneNumber object
+ * @param activity Activity object
+ */
+ public Appointment(Calendar cal, String fullName, TelephoneNumber phone, Activity activity){
+ this(cal, fullName.split(" ")[0], fullName.split(" ")[1], phone, activity);
+ }
+
+ // references: https://www.geeksforgeeks.org/split-string-java-examples/
+ /**
+ * The second constructor for the Appointment class. Calls all the setters and sets the passed
+ * values to the class fields.
+ *
+ * @param cal the Calendar object
+ * @param firstName first name string
+ * @param lastName last name string
+ * @param phone TelephoneNumber object
+ * @param activity Activity object
+ */
+ public Appointment(Calendar cal, String firstName, String lastName, TelephoneNumber phone, Activity activity){
+ setAptDate(cal);
+ setFirstName(firstName);
+ setLastName(lastName);
+ setPhone(phone);
+ setActivity(activity);
+ }
+
+ /**
+ *
+ * @return current {@link Calendar} object
+ */
+ public Calendar getAptDate() {
+ return aptDate;
+ }
+
+ /**
+ * sets the current aptDate field to passed parameter
+ * @param aptDate Calendar object sent by the {@link Scheduler} class
+ */
+ public void setAptDate(Calendar aptDate) {
+ this.aptDate = aptDate;
+ }
+
+ /**
+ *
+ * @return the current firstName field
+ */
+ public String getFirstName() {
+ return firstName;
+ }
+
+ /**
+ * sets the current firstName field to the passed value
+ * @param firstName made by splitting the fullName into two parts
+ */
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ /**
+ *
+ * @return current lastName field
+ */
+ public String getLastName() {
+ return lastName;
+ }
+
+ /**
+ * sets the current lastName field to the passed value
+ * @param lastName made by splitting the fullName into two parts
+ */
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ /**
+ *
+ * @return the current TelephoneNumber Object
+ */
+ public TelephoneNumber getPhone() {
+ return phone;
+ }
+
+ /**
+ * sets the current TelephoneNumber Object to passed value
+ * @param phone Object sent by the {@link Scheduler} class
+ */
+ public void setPhone(TelephoneNumber phone) {
+ this.phone = phone;
+ }
+
+ /**
+ *
+ * @return the current Activity object
+ */
+ public Activity getActivity() {
+ return activity;
+ }
+
+ /**
+ * sets the current Activity object to the passed value
+ * @param activity Activity object sent by the {@link Scheduler} class
+ */
+ public void setActivity(Activity activity) {
+ this.activity = activity;
+ }
+
+ /**
+ * Returns the Complete Appointment information, formatted, and by using toString methods from
+ * {@link Calendar}, {@link TelephoneNumber}, and {@link Activity} classes.
+ *
+ * @return complete formatted output (appointment information)
+ */
+ public String toString(){
+ return getAptDate().getTime() + "\n" + getFirstName() + " " + getLastName() + "\n" + getPhone().toString() + "\n" + getActivity();
+ }
+}
diff --git a/src/cst8284/asgmt4/scheduler/AppointmentDialog.java b/src/cst8284/asgmt4/scheduler/AppointmentDialog.java
new file mode 100644
index 0000000..4f8f07e
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/AppointmentDialog.java
@@ -0,0 +1,185 @@
+package cst8284.asgmt4.scheduler;
+
+
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.*;
+
+import static javax.swing.JOptionPane.showMessageDialog;
+
+/* Adapted, with considerable modification, from
+ * http://www.java2s.com/Code/Java/Swing-JFC/TextAcceleratorExample.htm,
+ *
+ */
+
+public class AppointmentDialog {
+
+ private static final GridBagConstraints textConstants = new GridBagConstraints(
+ 0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, // gridx, gridy, gridwidth, gridheight, weightx, weighty
+ GridBagConstraints.EAST, 0, new Insets(2, 2, 2, 2), 1, 1); // anchor, fill, insets, ipadx, ipady
+
+ private static final GridBagConstraints labelConstants = new GridBagConstraints(
+ 1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0,
+ GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0);
+
+ private static final GridBagConstraints buttonConstant = new GridBagConstraints(
+ 1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0,
+ GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0);
+
+
+ private static Container cp;
+ private static final int labelWidth = 35;
+ private static final Font defaultFont = new Font("SansSerif", Font.PLAIN, 16);
+
+ public static JComboBox des;
+ public static JTextField name, phone, date, time, activity;
+
+
+ public static void showAppointmentDialog(){
+ JFrame f = new JFrame("Save an Appointment");
+ cp = f.getContentPane();
+ cp.setLayout(new GridBagLayout());
+
+ name = setRow("Enter Client Name (as FirstName LastName):", 'n');
+ phone = setRow("Phone Number (e.g. 613-555-1212):", 'p');
+ date = setRow("Appointment Date (entered as DDMMYYYY):", 'd');
+ time = setRow("Appointment Time:", 't');
+ activity = setRow("Activity Description", 'a');
+
+ des = new JComboBox(Scheduler.getEmployee().getActivityType());
+ cp.add(new JLabel("Activity Type: ", SwingConstants.RIGHT), textConstants);
+ cp.add(des, labelConstants);
+
+ setBtns("Save",
+ e -> {
+ try {
+ if (Scheduler.saveAppointment(Scheduler.makeAppointmentFromUserInput())) {
+ showMessageDialog(null, "Appointment Saved!");
+ } else showMessageDialog(null, "Cannot save, an appointment at that time already exist.");
+ }
+ catch (BadAppointmentDataException ex){
+ showMessageDialog(null, ex.getMessage(), ex.getDescription(), JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ );
+ f.pack();
+ f.setLocationRelativeTo(null);
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent evt) {
+ f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ }
+ });
+ f.setVisible(true);
+ }
+
+
+ public static void showCalendarDialog(){
+ JFrame f = new JFrame("Get, set, change or delete an appointment");
+ cp = f.getContentPane();
+ cp.setLayout(new GridBagLayout());
+
+ date = setRow("Appointment Date (entered as DDMMYYYY): ", 'd');
+ time = setRow("Appointment Time: ", 't');
+
+ setBtns("Get Appointment",
+ e -> {
+ try {
+ Scheduler.displayAppointment(Scheduler.makeCalendarFromUserInput(false));
+ f.dispose();
+ }
+ catch (BadAppointmentDataException ex){
+ showMessageDialog(null, ex.getMessage(), ex.getDescription(), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ setBtns("Delete",
+ e -> {
+ try {
+ if (Scheduler.deleteAppointment(Scheduler.makeCalendarFromUserInput(false))) {
+ showMessageDialog(null, "Appointment Deleted");
+ } else showMessageDialog(null, "No appointments found at given time.");
+ f.dispose();
+ }
+ catch (BadAppointmentDataException ex){
+ showMessageDialog(null, ex.getMessage(), ex.getDescription(), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ setBtns("Change Time",
+ e -> {
+ try {
+ if (Scheduler.changeAppointment(Scheduler.makeCalendarFromUserInput(false))) {
+ showMessageDialog(null, "Appointment re-booked");
+ } else showMessageDialog(null, "No appointments found at given time.");
+ f.dispose();
+ }
+ catch (BadAppointmentDataException ex){
+ showMessageDialog(null, ex.getMessage(), ex.getDescription(), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ f.pack();
+ f.setLocationRelativeTo(null);
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent evt) {
+ f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ }
+ });
+ f.setVisible(true);
+ }
+
+ /**
+ * GUI for the daily schedule viewer.
+ */
+ public static void showDaySchedule(){
+ JFrame f = new JFrame("Display Day Schedule");
+ cp = f.getContentPane();
+ cp.setLayout(new GridBagLayout());
+
+ date = setRow("Appointment Date (entered as DDMMYYYY): ", 'd');
+
+ setBtns("Get Day Schedule",
+ e -> {
+ try {
+ Scheduler.displayDaySchedule(Scheduler.makeCalendarFromUserInput(true));
+ f.dispose();
+ }
+ catch (BadAppointmentDataException ex){
+ showMessageDialog(null, ex.getMessage(), ex.getDescription(), JOptionPane.ERROR_MESSAGE);
+ }
+ } );
+ f.pack();
+ f.setLocationRelativeTo(null);
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent evt) {
+ f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ }
+ });
+ f.setVisible(true);
+ }
+
+
+
+
+ private static JTextField setRow(String label, char keyboardShortcut) {
+ JLabel l; JTextField t;
+ cp.add(l = new JLabel(label, SwingConstants.RIGHT), textConstants);
+ l.setFont(defaultFont);
+ l.setDisplayedMnemonic(keyboardShortcut);
+ cp.add(t = new JTextField(labelWidth), labelConstants);
+ t.setFocusAccelerator(keyboardShortcut);
+ return t;
+ }
+
+ private static JButton setBtns(String btnLabel, ActionListener act) {
+ final Font font = new Font("SansSerif", Font.PLAIN, 20);
+ JButton btn = new JButton(btnLabel);
+ btn.setFont(font);
+ btn.addActionListener(act);
+ cp.add(btn, buttonConstant);
+ return btn;
+ }
+
+}
diff --git a/src/cst8284/asgmt4/scheduler/BadAppointmentDataException.java b/src/cst8284/asgmt4/scheduler/BadAppointmentDataException.java
new file mode 100644
index 0000000..3d29cab
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/BadAppointmentDataException.java
@@ -0,0 +1,65 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: BadAppointmentDataException
+ * Date: 28 November 2019
+ */
+
+package cst8284.asgmt4.scheduler;
+
+/**
+ * The Exception is thrown whenever there is an inconsistency in the data entered by the user. It extends
+ * RuntimeException.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class BadAppointmentDataException extends java.lang.RuntimeException {
+ private static final long serialVersionUID = 1L;
+ /**
+ * The variable used to store the more details of the error or exception thrown.
+ */
+ private String description;
+
+
+ /**
+ * It chains to the two-string constructor by passing a preset message.
+ */
+ public BadAppointmentDataException(){
+ this("Please try again", "Bad data entered");
+ }
+
+ /**
+ * Takes the two parameters and passes one of them to the superclass of Exception and stores the other
+ * in the local field.
+ *
+ * @param error the actual error message passed in the {@link BadAppointmentDataException}, then passed to the
+ * superclass constructor.
+ * @param description the detailed description of the exception thrown, passed in
+ * the {@link BadAppointmentDataException} exception.
+ */
+ public BadAppointmentDataException(String error, String description){
+ super(error);
+ setDescription(description);
+ }
+
+ /**
+ * Sets the description to the passed value
+ * @param description the description message passed by constructor
+ */
+ public void setDescription(String description){
+ this.description = description;
+ }
+
+ /**
+ *
+ * @return description stored in the field above.
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+
+
+
+}
diff --git a/src/cst8284/asgmt4/scheduler/Scheduler.java b/src/cst8284/asgmt4/scheduler/Scheduler.java
new file mode 100644
index 0000000..de9f1f5
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/Scheduler.java
@@ -0,0 +1,436 @@
+/*
+ * Course Name: CST8284_303
+ * Class name: Scheduler
+ * Date: 28 November 2019
+
+ * References:
+ https://www.youtube.com/watch?v=_jhCvy8_lGE
+ https://stackoverflow.com/questions/2294551/java-io-writeabortedexception-writing-aborted-java-io-notserializableexception
+ http://tutorials.jenkov.com/java-exception-handling/catching-multiple-exceptions.html
+ Lecture notes.
+ */
+
+
+package cst8284.asgmt4.scheduler;
+
+import java.io.*;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import cst8284.asgmt4.employee.Employee;
+import javax.swing.*;
+import static javax.swing.JOptionPane.showMessageDialog;
+
+/**
+ * This is the class where everything happens - making appointments, saving appointments, changing the appointments,
+ * saving the appointments to file, retrieving the appointments from file, entering the information about
+ * appointments, making objects and instances.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class Scheduler {
+
+ /**
+ * The variable which stores the daily schedule and the appointment data to be used by the GUI
+ */
+ public static String outString="";
+ /**
+ * ArrayList that stores all the Appointments.
+ */
+ private static ArrayList appointments = new ArrayList<>();
+ /**
+ * A declaration of a Employee Object to hold the current employee name.
+ */
+ private static Employee employee;
+ /**
+ * The DateFormat is used to check the correct date format for the input date
+ */
+ private static DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
+
+
+
+ /**
+ * This constructor sets the new employee object, and at the same time calls the
+ * loadAppointmentsFromFile method to add appointments to ArrayList, if they exists.
+ *
+ * @param employee The instantiated employee object, then set to the current employee object.
+ */
+ public Scheduler(Employee employee){
+ setEmployee(employee);
+ loadAppointmentsFromFile("CurrentAppointments.apts", getAppointments());
+ }
+
+
+ /**
+ * The launch method maintains a while loop that keep the program running. It also catches the exceptions thrown
+ * by the execution of the program. This method calls two other methods displayMenu() and executeMenuItem() to
+ * complete its functions. It exits the program if user selects O option.
+ */
+ public void launch() {
+
+ try{
+ SchedulerViewer.launchGUI();
+ }
+ catch (Exception ex){
+ showMessageDialog(SchedulerViewer.frame, ex.getMessage());
+ }
+ }
+
+ /**
+ * This method takes a string value and concatenates it to a static string variable which is then
+ * used to output messages to the JScrollPanel in the the Scheduler Viewer Class.
+ * It is used to show daily string and appointment information.
+ *
+ * @param msg The string used to append the static string above
+ */
+ public static void output(String msg){
+ outString+=msg;
+ SchedulerViewer.scrollText.setText(outString);
+ }
+
+
+ /**
+ * This is the setter for the name of Employee object used in the class.
+ *
+ * @param emp sets the current employee object to the passed employee object.
+ */
+ private void setEmployee(Employee emp){
+ employee = emp;
+ }
+
+ /**
+ * The getter for the current employee object.
+ *
+ * @return current employee object (name of the employee).
+ */
+ public static Employee getEmployee(){
+ return employee;
+ }
+
+ /**
+ * Saves the appointment to the ArrayList, but only after making sure that
+ * it does not already exits in the ArrayList. Also sorts the ArrayList after saving the appointment by
+ * using sort method.
+ *
+ * @param apt A complete appointment object returned by the makeAppointmentFromUserInput method. if null
+ * is received, it means the appointment does not exists.
+ * @return boolean whether the appointment save was successful or not.
+ * true if yes, false
+ * if appointment save is not successful.
+ */
+ public static boolean saveAppointment(Appointment apt){
+ if (findAppointment(apt.getAptDate())==null){
+ getAppointments().add(apt);
+ Collections.sort(getAppointments(), new SortAppointmentByCalendar());
+ return true;
+ }
+ else return false;
+ }
+
+ /**
+ * Finds the appointment in the ArrayList by using the Collections class' sort method. It passes three arguments to this
+ * method, first - the ArrayList, second - a dummy appointment made by just using calendar object to help
+ * in the searching, third - a new instance of the the {@link SortAppointmentByCalendar} class that extends
+ * {@link Comparable}.
+ *
+ * @param cal helps in searching of appointment by date and time. It helps to create a dummy appointment that plays a
+ * role to search appointments.
+ * @return appointment object - if present in the array; otherwise returns null.
+ */
+ private static Appointment findAppointment(Calendar cal) {
+ // references: https://www.concretepage.com/java/example-collections-binarysearch-java
+ int index = Collections.binarySearch(getAppointments(), new Appointment(cal,null,null,null,null) , new SortAppointmentByCalendar() );
+ if (index<0) return null;
+ else return getAppointments().get(index);
+ }
+
+
+ /**
+ * Deletes the appointment based on the date and time received as a calendar object. First it finds the appointment
+ * by using the findAppointment method and then displays it. Then prompts the user to confirm the delete and then
+ * deletes the appointment from the ArrayList.
+ *
+ * @param cal the calendar object by using which appointments will be searched.
+ * @return true - if delete was successful
+ * false - if delete was not successful.
+ */
+ public static boolean deleteAppointment(Calendar cal){
+ if(findAppointment(cal)!=null){
+
+ int j = JOptionPane.showConfirmDialog(null, findAppointment(cal).toString(), "Do you want to delete?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+ if (j==0){
+ getAppointments().remove(findAppointment(cal));
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Changes the existing appointment's date and time to a new date and time.
+ * First it finds the appointment by using the findAppointment method and if Appointment is found, displays it
+ * and asks for confirmation, and then makes a new calendar object for the new sate and time. it then sets the
+ * new calendar for the existing appointment.
+ *
+ * @param cal the calendar object used for searching the appointments.
+ * @return true - if change rime was successful
+ * false - if changing time failed due to some reason.
+ */
+ public static boolean changeAppointment(Calendar cal){
+ if(findAppointment(cal)!=null){
+
+ int j = JOptionPane.showConfirmDialog(null, findAppointment(cal).toString(), "Do you want to change?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+
+ if (j==0){
+
+ AppointmentDialog.date.setText(JOptionPane.showInputDialog(null,"Enter new date"));
+ AppointmentDialog.time.setText(JOptionPane.showInputDialog(null,"Enter new time"));
+
+
+ Calendar newCal = makeCalendarFromUserInput(false);
+ if(findAppointment(newCal)==null){
+ findAppointment(cal).setAptDate(newCal);
+ return true;
+ } else showMessageDialog(null,"Appointment Does not exitst");
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Displays a single appointment based on the user entered date and time.
+ * First, it calls the findAppointment method to search for the appointment and if no appointment is found, displays
+ * a message that appointment does not exists. If the appointment is found, prints it by using the {@link Appointment}
+ * class' toString method.
+ *
+ * @param cal the calendar object used to find the appointments. This method passed the the calendar parameter
+ * to the findAppointment method.
+ */
+ public static void displayAppointment (Calendar cal){
+ if (findAppointment(cal)==null){
+ output("No appointments found between " + cal.get(Calendar.HOUR_OF_DAY) + ":00 and " + (cal.get(Calendar.HOUR_OF_DAY)+1) + ":00\n");
+ }
+ else {
+ output("\n" + findAppointment(cal).toString() + "\n\n");
+ }
+ }
+
+
+ /**
+ * Displays the day schedule by using a for loop to loop between 8 AM - 4 PM and calling displayAppointment method
+ * in each iteration.
+ *
+ * @param cal the calendar object used to set the HOUR_OF_DAY to find all appointments on a given date, which is eventually
+ * passed down to the findAppointment Class.
+ */
+ public static void displayDaySchedule (Calendar cal) {
+ for (int i = 8; i <= 16; i++) {
+ cal.set(Calendar.HOUR_OF_DAY,i);
+ displayAppointment(cal);
+ }
+
+ }
+
+
+ // reference: https://www.youtube.com/watch?v=_jhCvy8_lGE
+ /**
+ * Saves the appointments in memory to a file on the disk. It uses FileOutputStream and ObjectOutputStream to
+ * write the objects to file by using a enhanced for loop through the Appointments Array.
+ *
+ * @param apts The appointments array used to save the appointments declared at top of the class
+ * @param saveFile the actual name of the file to be saved on the disk.
+ * @return true - if save appointments to file was successful
+ * false - if save appointments to file failed or an exception was thrown.
+ */
+ public static boolean saveAppointmentsToFile(ArrayList apts, String saveFile ){
+ File file = new File(saveFile);
+ try {
+ FileOutputStream fout = new FileOutputStream(file);
+ ObjectOutputStream output = new ObjectOutputStream(fout);
+ for (Appointment apt: apts){
+ output.writeObject(apt);
+ }
+ output.close();
+ fout.close();
+ return true;
+ } catch (IOException exp){
+ showMessageDialog(null,exp.getMessage());
+ }
+ return false;
+ }
+
+
+ // reference: https://www.youtube.com/watch?v=_jhCvy8_lGE
+ /**
+ * Does exactly opposite of saveAppointmentsToFile method by loading appointments from file
+ * and adding them to array one by one. It first clears the ArrayList to remove all appointments that are
+ * in the memory. Then uses FileInputStream and ObjectInputStream to read the objects from file.
+ *
+ * @param sourceFile the name of the file on the disk.
+ * @param apts the actual appointments ArrayList used to save appointments.
+ * @return whether the loading appointments was successful or not - true if yes; false if an error occurred or
+ * an exception was thrown.
+ */
+ public static boolean loadAppointmentsFromFile(String sourceFile, ArrayList apts){
+ apts.clear();
+ File file = new File(sourceFile);
+ try(
+ FileInputStream fin = new FileInputStream(file);
+ ObjectInputStream input = new ObjectInputStream(fin);
+ ){
+ while (true){
+ Appointment apt = (Appointment)input.readObject();
+ apts.add(apt);
+ }
+ }
+ catch (EOFException exp1){
+ return true;
+ }catch (FileNotFoundException exp2){
+ return false;
+ }catch (IOException | ClassNotFoundException exp3){
+ showMessageDialog(SchedulerViewer.frame, exp3.getMessage());
+ }
+ return false;
+ }
+
+
+ /**
+ * Makes a new Appointment object by making several other objects such as TelephoneNumber and Activity;
+ * takes in various information needed to make a Appointment. It also checks if the entered name has any illegal
+ * characters or not. Makes a new Appointment by using the information and returns it.
+ *
+ * @return a new Appointment Object
+ * @throws BadAppointmentDataException if the name contains illegal characters or the name is greater
+ * than the specified length, or if user only enters the single name.
+ */
+ public static Appointment makeAppointmentFromUserInput(){
+
+ String name = AppointmentDialog.name.getText();
+
+ // references: https://stackoverflow.com/questions/2385701/regular-expression-for-first-and-last-name
+ if(name.isEmpty())
+ throw new BadAppointmentDataException("Must enter a value","Empty or null value entered");
+ else if (!name.matches("^[-\\ .'a-zA-z]*$"))
+ throw new BadAppointmentDataException("Name cannot include characters other than alphabetic " +
+ "characters, the dash (-), the period (.), and the apostrophe (‘)","Illegal characters in name");
+ else if (name.length()>30)
+ throw new BadAppointmentDataException("Name cannot exceed 30 characters","Name exceeds maximum length");
+ try{
+ String aa = name.split(" ")[1];
+ }
+ catch (ArrayIndexOutOfBoundsException ex){
+ throw new BadAppointmentDataException("Name is not entered correctly","Name must contain two Strings separated by a single space");
+ }
+
+ String phone = AppointmentDialog.phone.getText();
+ TelephoneNumber phoneNo = new TelephoneNumber(phone);
+
+ Calendar cal = makeCalendarFromUserInput(false);
+ String act = AppointmentDialog.activity.getText();
+ if(act.isEmpty())
+ throw new BadAppointmentDataException("Must enter a value","Empty or null value entered");
+ String des = (String)AppointmentDialog.des.getSelectedItem();
+ Activity activity = new Activity(act, des);
+
+ return new Appointment(cal,name,phoneNo,activity);
+
+ }
+
+
+ /**
+ * Makes a new Calendar Object by taking the user input. it calls another method to set the date of the
+ * calendar instance. Sets the Calendar.setLenient to false so that user is not able to set the bad date for the
+ * calendar.
+ *
+ * @param suppressHour used if user wants to take the date input only. Then it does not prompt the user for the
+ * time input.
+ * @return the new calendar object made by the method after taking dates and times from the user.
+ */
+ public static Calendar makeCalendarFromUserInput(boolean suppressHour){
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.setLenient(false);
+
+ String date = AppointmentDialog.date.getText();
+ if (date.isEmpty())
+ throw new BadAppointmentDataException("Must enter a value","Empty or null value entered");
+
+ setAppointmentDate(date, cal);
+
+ if (!suppressHour) {
+ String time = AppointmentDialog.time.getText();
+ if (time.isEmpty())
+ throw new BadAppointmentDataException("Must enter a value","Empty or null value entered");
+ cal.set(Calendar.HOUR_OF_DAY, processTimeString(time));
+ }
+ return cal;
+ }
+
+
+ /**
+ * This is the sub method used to set the appointment date as well as check for any bad date formats.
+ * It uses a pre defined date format and matches all input date formats with the given format. In case
+ * of a mismatch, it throws a new BadAppointmentDataException.
+ *
+ * @param date the string value to be parsed and matched with pre defined date format
+ * @param cal the calendar object created in previous method; used to set date.
+ * @throws BadAppointmentDataException if the date format is not as specified or user enters bad date.
+ */
+ private static void setAppointmentDate(String date, Calendar cal) {
+
+ dateFormat.setLenient(false);
+ try {
+ Date date2 = dateFormat.parse(date);
+ cal.setTime(date2);
+ }
+ catch (RuntimeException exp){
+ throw new BadAppointmentDataException("General runtime exception thrown setting start date","");
+ }catch (ParseException exp){
+ throw new BadAppointmentDataException("Bad calendar date entered; format is DDMMYYYY","Bad calendar format");
+ }
+
+ }
+
+ /**
+ * Takes in the string value entered by the user and process whether it is am or pm and then convert it to
+ * 13-hour format.
+ *
+ * @param t the string sent by the makeCalendarFromUserInput method to convert to 13-hour.
+ * @return 13-hour format time.
+ */
+ private static int processTimeString(String t){
+
+ try {
+ String t2 = t.replace(":", "").replace("00", "").replace(" ", "");
+ if (t2.contains("a.m.") || t2.contains("am") || t2.contains("a m")) {
+ return Integer.parseInt(t2.replace("a.m.", "").replace("am", "").replace("a m", ""));
+ } else if (t2.contains("p.m.") || t2.contains("pm") || t2.contains("p m")) {
+ return (Integer.parseInt(t2.replace("p.m.", "").replace("pm", "").replace("p m", "")) + 12);
+ } else if (Integer.parseInt(t2) >= 1 && Integer.parseInt(t2) <= 4) {
+ return (Integer.parseInt(t2) + 12);
+ } else return Integer.parseInt(t2);
+ }
+ catch (Exception ex){
+ throw new BadAppointmentDataException("Please enter a valid time","Bad time entered");
+ }
+ }
+
+ /**
+ * The getter for the appointments ArrayList.
+ *
+ * @return appointments stored in the ArrayList.
+ */
+ public static ArrayList getAppointments(){
+ return appointments;
+ }
+}
+
+
+// https://www.youtube.com/watch?v=_jhCvy8_lGE
+// https://stackoverflow.com/questions/2294551/java-io-writeabortedexception-writing-aborted-java-io-notserializableexception
+// http://tutorials.jenkov.com/java-exception-handling/catching-multiple-exceptions.html
+//
\ No newline at end of file
diff --git a/src/cst8284/asgmt4/scheduler/SchedulerLauncher.java b/src/cst8284/asgmt4/scheduler/SchedulerLauncher.java
new file mode 100644
index 0000000..2de7ba4
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/SchedulerLauncher.java
@@ -0,0 +1,33 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: SchedulerLauncher
+ * Date: 28 November 2019
+ */
+
+package cst8284.asgmt4.scheduler;
+
+import cst8284.asgmt4.employee.Dentist;
+import cst8284.asgmt4.employee.Employee;
+
+/**
+ * The entry point of the Assignment and contains a main method.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class SchedulerLauncher {
+
+ /**
+ * Main method of the program. It instantiates a new Employee object of type Dentist and instantiates a new
+ * Scheduler object by passing made dentist as parameter.
+ *
+ * @param args default string
+ */
+ public static void main(String[] args){
+ javax.swing.SwingUtilities.invokeLater
+ (() -> new Scheduler(new Dentist("Dr. Andrews")).launch());
+
+ }
+
+}
diff --git a/src/cst8284/asgmt4/scheduler/SchedulerViewer.java b/src/cst8284/asgmt4/scheduler/SchedulerViewer.java
new file mode 100644
index 0000000..d33f219
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/SchedulerViewer.java
@@ -0,0 +1,103 @@
+package cst8284.asgmt4.scheduler;
+
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+
+import static javax.swing.JOptionPane.showMessageDialog;
+
+public class SchedulerViewer {
+
+ private static final Toolkit tk = Toolkit.getDefaultToolkit();
+ private static final Dimension screenSize = tk.getScreenSize();
+ public static final JTextArea scrollText = new JTextArea();
+ public static JFrame frame;
+
+
+
+ public static void launchGUI(){
+ frame = new JFrame();
+ frame.setTitle("Scheduling Appointments for " + Scheduler.getEmployee());
+ frame.setLayout(new BorderLayout());
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ int screenX = (int) screenSize.getWidth() / 2;
+ int screenY = (int) (7 * screenSize.getHeight() / 8);
+
+ frame.add(getWestPanel(), BorderLayout.WEST);
+ frame.add(getCenterPanel(scrollText, screenY), BorderLayout.CENTER);
+ frame.setPreferredSize(new Dimension(screenX, screenY));
+
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ }
+
+ public static JPanel getCenterPanel(JTextArea jta, int height) {
+ JScrollPane centerPane = new JScrollPane(jta);
+ centerPane.setPreferredSize(new Dimension(400, 7 * height / 8));
+ JPanel jp = new JPanel();
+ jp.add(centerPane);
+ return jp;
+ }
+
+ private static JButton setWestPanelBtns(String btnLabel, ActionListener act) {
+ final Font font = new Font("SansSerif", Font.PLAIN, 20);
+ JButton btn = new JButton(btnLabel);
+ btn.setFont(font);
+ btn.addActionListener(act);
+ return btn;
+ }
+
+ public static JPanel getWestPanel() {
+ JPanel controlPanel = new JPanel(new GridLayout(6, 1));
+ JPanel westPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.NORTH;
+ gbc.weighty = 1;
+
+ controlPanel.add(setWestPanelBtns(" Save Appointment ",
+ e -> AppointmentDialog.showAppointmentDialog()));
+
+ controlPanel.add(setWestPanelBtns(" Display Schedule ",
+ e -> {
+ Scheduler.outString = "";
+ AppointmentDialog.showDaySchedule();
+
+ }));
+
+ controlPanel.add(setWestPanelBtns(" Display Appointment ",
+ e -> {
+ Scheduler.outString = "";
+ AppointmentDialog.showCalendarDialog();
+ }));
+
+ controlPanel.add(setWestPanelBtns("Save Appointment to file",
+ e -> {
+ if (Scheduler.saveAppointmentsToFile(Scheduler.getAppointments(), "CurrentAppointments.apts")) {
+ showMessageDialog(controlPanel, "Appointment data Saved to file");
+ }
+
+ }));
+
+ controlPanel.add(setWestPanelBtns("Load Appointments from file",
+ e -> {
+ if (Scheduler.loadAppointmentsFromFile("CurrentAppointments.apts", Scheduler.getAppointments())) {
+ showMessageDialog(controlPanel, "Appointments successfully loaded from file");
+ }
+ }));
+
+ controlPanel.add(setWestPanelBtns("Exit",
+ e -> {
+ Scheduler.loadAppointmentsFromFile("CurrentAppointments.apts", Scheduler.getAppointments());
+ frame.dispose();
+ }
+ ));
+
+ westPanel.add(controlPanel, gbc);
+ return westPanel;
+ }
+
+}
diff --git a/src/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.java b/src/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.java
new file mode 100644
index 0000000..758c985
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/SortAppointmentByCalendar.java
@@ -0,0 +1,44 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: SortAppointmentByCalendar
+ * Date: 28 November 2019
+ */
+
+package cst8284.asgmt4.scheduler;
+
+import java.util.Comparator;
+
+/**
+ * The class overwrites the compare method in the the Comparator interface and it helps to sort the
+ * appointments in the ArrayList by returning a number based on comparison result.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class SortAppointmentByCalendar implements Comparator {
+
+
+ /**
+ * Overrides the compare method from the Comparator Interface and uses the Calendar.before
+ * and Calendar.after and returns a number based on the result.
+ *
+ * @param apt1 First appointment passed to be compared, passed in the method call
+ * @param apt2 Second appointment to be compared, passed in the method call
+ * @return 1 if apt2 is after apt1,
+ * -1 if apt2 is before apt1,
+ * 0 if no case applies.
+ */
+ @Override
+ public int compare(Appointment apt1, Appointment apt2) {
+
+ if ( apt1.getAptDate().before(apt2.getAptDate()) ) return -1;
+ else if (apt1.getAptDate().after(apt2.getAptDate()) ) return 1;
+ else return 0;
+
+ // source: http://www.java2s.com/Code/Java/Development-Class/CalendarComparator.htm
+
+
+ }
+
+}
diff --git a/src/cst8284/asgmt4/scheduler/TelephoneNumber.java b/src/cst8284/asgmt4/scheduler/TelephoneNumber.java
new file mode 100644
index 0000000..dffeb82
--- /dev/null
+++ b/src/cst8284/asgmt4/scheduler/TelephoneNumber.java
@@ -0,0 +1,142 @@
+/*
+ * Course Name: CST8284_303
+ * Student Name: Amanjot Singh
+ * Class name: TelephoneNumber
+ * Date: 28 November 2019
+ * References: https://www.journaldev.com/807/java-string-substring
+ */
+
+
+package cst8284.asgmt4.scheduler;
+
+import java.io.Serializable;
+
+/**
+ * The class helps to make the Telephone number object that validates, parses and processes the phone number.
+ * It stores the phone number in three different fields.
+ *
+ * @author Amanjot Singh
+ * @version 1.0
+ */
+public class TelephoneNumber implements Serializable {
+
+ /**
+ * The field used to store the 3 digit area code.
+ */
+ private int areaCode;
+ /**
+ * The field used to store the 3 digit number prefix.
+ */
+ private int prefix;
+ /**
+ * The field used to store the line number of the phone number.
+ */
+ private int lineNumber;
+ public static final long serialVersionUID = 1L;
+
+
+// references: https://www.journaldev.com/807/java-string-substring
+ /**
+ * Constructor receives the phone number string from the Scheduler class and processes it into different fields -
+ * area code, prefix, and line number.
+ * Makes sures that the phone number meets the specified formats and it does not contain any
+ * illegal characters.
+ * Then, extracts the substrings from the passed string and assign them to the various fields by converting them
+ * to integer values.
+ * Also makes sure that area code does not start with 0 or 1
+ *
+ * @param phoneNumber phone number passed by the {@link Scheduler} Class.
+ * @throws BadAppointmentDataException if the phone number does not meet the specified formats - that is -
+ * contains illegal characters, has bad format, or the area code starts with 0 or 1.
+ */
+ public TelephoneNumber(String phoneNumber){
+
+// regex idea: http://txt2re.com/index-csharp.php3?s=121-255-4545&4&-19&5&-20&2
+// https://regexr.com/
+ if (phoneNumber.isEmpty())
+ throw new BadAppointmentDataException("Must enter a value","Empty or null value entered");
+ else if (!phoneNumber.matches("^(.{3})(-)(.{3})(-)(.{4})$"))
+ throw new BadAppointmentDataException("Missing digit(s); correct format is AAA-PPP-NNNN, where AAA" +
+ " is the area code and PPP-NNNN is the local number","Incorrect format");
+ else if (!phoneNumber.matches("(\\d+).(\\d+).(\\d+)"))
+ throw new BadAppointmentDataException("Telephone numbers can only contain numbers or the\n" +
+ "character ‘-‘","Bad character(s) in input string");
+
+ String area = phoneNumber.substring(0, 3);
+ String prefix = phoneNumber.substring(4, 7);
+ String line = phoneNumber.substring(8, 12);
+
+ if (area.charAt(0)=='0' || area.charAt(0)=='1')
+ throw new BadAppointmentDataException("Area code can’t start with a ‘0’ or a ‘1’","Invalid number");
+
+ setAreaCode(Integer.parseInt(area));
+ setPrefix(Integer.parseInt(prefix));
+ setLineNumber(Integer.parseInt(line));
+
+ }
+
+ /**
+ *
+ * @return the area code integer
+ */
+ public int getAreaCode() {
+ return areaCode;
+ }
+
+ /**
+ * sets the area code to the passed value.
+ *
+ * @param areaCode area code passed by the constructor
+ */
+ public void setAreaCode(int areaCode) {
+ this.areaCode = areaCode;
+ }
+
+ /**
+ *
+ * @return the prefix integer
+ */
+ public int getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * sets the prefix to the passed int value.
+ *
+ * @param prefix prefix integer made by the constructor
+ */
+ public void setPrefix(int prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ *
+ * @return the line number stored in the above field.
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ /**
+ * sets the line number to the passed integer value.
+ *
+ * @param lineNumber int sent by the constructor
+ */
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ /**
+ * Gets the area code, prefix, and line number using getters and forms a telephone number string with a
+ * specific format.
+ *
+ * @return the complete phone number string to be used by {@link Appointment} class.
+ */
+ public String toString(){
+ return "(" + getAreaCode() + ") " + getPrefix() + "-" + getLineNumber();
+ }
+}
+
+
+
+//"^(\\d{3})(-)(\\d{3})(-)(\\d{4})$"
\ No newline at end of file