commit
1bc540427a
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
@ -0,0 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="google.code.gson" type="repository">
|
||||
<properties maven-id="com.google.code.gson:gson:2.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.9.0/gson-2.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="18" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/cmpt213-a3.iml" filepath="$PROJECT_DIR$/cmpt213-a3.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../../../.." vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="google.code.gson" level="project" />
|
||||
</component>
|
||||
</module>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
package cmpt213.assignment3.packagedeliveries;
|
||||
|
||||
import cmpt213.assignment3.packagedeliveries.view.JavaSwingUI;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello world!");
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JavaSwingUI ui = new JavaSwingUI();
|
||||
ui.displayMainPage();
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package cmpt213.assignment3.packagedeliveries.control;
|
||||
|
||||
import cmpt213.assignment3.packagedeliveries.gson.extras.RuntimeTypeAdapterFactory;
|
||||
import cmpt213.assignment3.packagedeliveries.model.BookPackage;
|
||||
import cmpt213.assignment3.packagedeliveries.model.ElectronicPackage;
|
||||
import cmpt213.assignment3.packagedeliveries.model.PackageInfo;
|
||||
import cmpt213.assignment3.packagedeliveries.model.PerishablePackage;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* It's a class that contains a main method that creates a TextMenu object, loads a list of packages
|
||||
* from a file, and then loops through a menu of options until the user chooses to quit
|
||||
*/
|
||||
public class PackageDeliveriesTracker {
|
||||
private static final String fileName = "list.json";
|
||||
private static final RuntimeTypeAdapterFactory<PackageInfo> r = RuntimeTypeAdapterFactory.of(PackageInfo.class, "type")
|
||||
.registerSubtype(BookPackage.class, "book")
|
||||
.registerSubtype(PerishablePackage.class, "perishable")
|
||||
.registerSubtype(ElectronicPackage.class, "electronic");
|
||||
private static final Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class,
|
||||
new TypeAdapter<LocalDateTime>() {
|
||||
@Override
|
||||
public void write(JsonWriter jsonWriter,
|
||||
LocalDateTime localDateTime) throws IOException {
|
||||
jsonWriter.value(localDateTime.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime read(JsonReader jsonReader) throws IOException {
|
||||
return LocalDateTime.parse(jsonReader.nextString());
|
||||
}
|
||||
}).registerTypeAdapterFactory(r).create();
|
||||
private static ArrayList<PackageInfo> packageList = new ArrayList<>();
|
||||
|
||||
private static PackageDeliveriesTracker instance;
|
||||
|
||||
public static PackageDeliveriesTracker getInstance(){
|
||||
if (instance == null){
|
||||
instance=new PackageDeliveriesTracker();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* It saves the packageList to a file.
|
||||
*/
|
||||
public void save() {
|
||||
try {
|
||||
Writer w = new FileWriter(fileName);
|
||||
gson.toJson(packageList, w);
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It reads the json file, converts it to a list of PackageInfo objects, and then sets the type of
|
||||
* each object to the appropriate type
|
||||
*/
|
||||
public void load() {
|
||||
File file = new File(fileName);
|
||||
try {
|
||||
String json = Files.readString(Paths.get(fileName));
|
||||
Type lType = new TypeToken<ArrayList<PackageInfo>>() {
|
||||
}.getType();
|
||||
packageList = gson.fromJson(json, lType);
|
||||
for (PackageInfo p : packageList) {
|
||||
if (p instanceof BookPackage) {
|
||||
p.setType("book");
|
||||
} else if (p instanceof PerishablePackage) {
|
||||
p.setType("perishable");
|
||||
} else if (p instanceof ElectronicPackage) {
|
||||
p.setType("electronic");
|
||||
}
|
||||
}
|
||||
System.out.println("packages loaded");
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("no packages to load");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getAllPackages(){
|
||||
StringBuilder b= new StringBuilder();
|
||||
if (packageList.size() == 0) {
|
||||
return("No packages to show");
|
||||
} else {
|
||||
Collections.sort(packageList);
|
||||
for (int i = 0; i < packageList.size(); i++) {
|
||||
String bString=("Package #" + (i + 1)) + "\n" + packageList.get(i) + "\n";
|
||||
b.append(bString);
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
package cmpt213.assignment3.packagedeliveries.control;
|
||||
|
||||
import cmpt213.assignment3.packagedeliveries.model.BookPackage;
|
||||
import cmpt213.assignment3.packagedeliveries.model.ElectronicPackage;
|
||||
import cmpt213.assignment3.packagedeliveries.model.PackageInfo;
|
||||
import cmpt213.assignment3.packagedeliveries.model.PerishablePackage;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* The PackageFactory class is a factory class that creates a package object based on the type of
|
||||
* package that is passed in
|
||||
*/
|
||||
public class PackageFactory {
|
||||
/**
|
||||
* > This function creates a new package object based on the package type
|
||||
*
|
||||
* @param type The type of package.
|
||||
* @param name The name of the package.
|
||||
* @param notes A string of notes about the package.
|
||||
* @param price The price of the package
|
||||
* @param weight The weight of the package in kilograms
|
||||
* @param delivered Whether or not the package has been delivered
|
||||
* @param expectDate The date the package is expected to be delivered.
|
||||
* @param author The author of the book.
|
||||
* @param expiryDate The date the package expires.
|
||||
* @param handlingFee The handling fee for the package.
|
||||
* @return A new instance of the package type.
|
||||
*/
|
||||
|
||||
public static PackageInfo create(PackageType type, String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectDate, String author, LocalDateTime expiryDate, double handlingFee) {
|
||||
return type.getInstance(name, notes, price, weight, delivered, expectDate, author, expiryDate, handlingFee);
|
||||
}
|
||||
|
||||
// Creating an enum called PackageType.
|
||||
public enum PackageType {
|
||||
Book {
|
||||
public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) {
|
||||
return new BookPackage(name, notes, price, weight, delivered, expectedDate, author);
|
||||
}
|
||||
},
|
||||
|
||||
Perishable {
|
||||
public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) {
|
||||
return new PerishablePackage(name, notes, price, weight, delivered, expectedDate, expiryDate);
|
||||
}
|
||||
},
|
||||
|
||||
Electronic {
|
||||
public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) {
|
||||
return new ElectronicPackage(name, notes, price, weight, delivered, expectedDate, handlingFee);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* It returns a PackageInfo object.
|
||||
*
|
||||
* @param name The name of the package.
|
||||
* @param notes a string that describes the package
|
||||
* @param price The price of the package
|
||||
* @param weight the weight of the package in kg
|
||||
* @param delivered true if the package has been delivered, false otherwise
|
||||
* @param expectedDate The date the package is expected to be delivered.
|
||||
* @param author The name of the author of the book.
|
||||
* @param expiryDate The date when the package expires.
|
||||
* @param handlingFee The handling fee for the package.
|
||||
* @return A package object
|
||||
*/
|
||||
|
||||
public abstract PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
package cmpt213.assignment3.packagedeliveries.control;
|
||||
|
||||
|
||||
import cmpt213.assignment3.packagedeliveries.model.PackageInfo;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* It's a class that displays a menu and allows the user to interact with the program
|
||||
*/
|
||||
public class TextMenu {
|
||||
private final String title = "Package Tracker";
|
||||
private final String[] options = new String[]{
|
||||
"List of all packages",
|
||||
"Add a package",
|
||||
"remove a package",
|
||||
"list overdue packages",
|
||||
"List upcoming packages",
|
||||
"mark package as delivered",
|
||||
"exit"};
|
||||
|
||||
/**
|
||||
* This function displays the title of the menu, the current date, and the options available to the
|
||||
* user
|
||||
*/
|
||||
public void display() {
|
||||
int tag = title.length();
|
||||
for (int i = 0; i <= tag + 3; i++) {
|
||||
System.out.print("#");
|
||||
}
|
||||
System.out.println("\n# " + title + " #");
|
||||
for (int i = 0; i <= tag + 3; i++) {
|
||||
System.out.print("#");
|
||||
}
|
||||
DateFormat today = new SimpleDateFormat("yyy-MM-dd");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
System.out.println("\nToday is: " + today.format(cal.getTime()));
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
System.out.println((i + 1) + ": " + options[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes an ArrayList of PackageInfo objects and prints them out in reverse order
|
||||
*
|
||||
* @param packageList The list of packages to be displayed
|
||||
*/
|
||||
public void list(ArrayList<PackageInfo> packageList) {
|
||||
if (packageList.size() == 0) {
|
||||
System.out.println("No packages to show");
|
||||
} else {
|
||||
Collections.sort(packageList);
|
||||
for (int i = 0; i < packageList.size(); i++) {
|
||||
System.out.println("Package #" + (i + 1));
|
||||
System.out.println(packageList.get(i) + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows the user to add a package to the list of packages
|
||||
*
|
||||
* @param packageList the list of packages
|
||||
*/
|
||||
public void add(ArrayList<PackageInfo> packageList) {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
int itemType;
|
||||
do {
|
||||
System.out.println("please select (1) book, (2) perishable, or (3) electronic package");
|
||||
itemType = Integer.parseInt(scan.nextLine());
|
||||
}
|
||||
while (itemType < 1 || itemType > 3);
|
||||
PackageFactory.PackageType pType = PackageFactory.PackageType.Book;
|
||||
String author = "";
|
||||
LocalDateTime expiryDate = LocalDateTime.now();
|
||||
double handlingFee = 0.0;
|
||||
String pName;
|
||||
do {
|
||||
System.out.println("enter a valid package name:");
|
||||
pName = scan.nextLine();
|
||||
}
|
||||
while (pName.length() == 0);
|
||||
System.out.println("notes:");
|
||||
String pNotes = scan.nextLine();
|
||||
boolean checkDate = false;
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm");
|
||||
LocalDateTime pDate = LocalDateTime.now();
|
||||
while (checkDate == false) {
|
||||
try {
|
||||
System.out.println("enter date as yyyy-mm-dd hh:mm:");
|
||||
pDate = LocalDateTime.parse(scan.nextLine(), format);
|
||||
checkDate = true;
|
||||
} catch (DateTimeParseException e) {
|
||||
System.out.println("invalid date format");
|
||||
}
|
||||
}
|
||||
double pPrice;
|
||||
do {
|
||||
System.out.println("enter price:");
|
||||
pPrice = Double.parseDouble(scan.nextLine());
|
||||
}
|
||||
while (pPrice < 0);
|
||||
double pWeight;
|
||||
do {
|
||||
System.out.println("enter weight:");
|
||||
pWeight = Double.parseDouble(scan.nextLine());
|
||||
}
|
||||
while (pWeight <= 0);
|
||||
switch (itemType) {
|
||||
case 1:
|
||||
do {
|
||||
System.out.println("enter author");
|
||||
author = scan.nextLine();
|
||||
}
|
||||
while (author.length() == 0);
|
||||
break;
|
||||
case 2:
|
||||
boolean checkExpDate = false;
|
||||
while (checkExpDate == false) {
|
||||
try {
|
||||
System.out.println("enter expiry date as yyyy-mm-dd hh:mm");
|
||||
expiryDate = LocalDateTime.parse(scan.nextLine(), format);
|
||||
checkExpDate = true;
|
||||
} catch (DateTimeParseException e) {
|
||||
System.out.println("invalid date format");
|
||||
}
|
||||
}
|
||||
pType = PackageFactory.PackageType.Perishable;
|
||||
break;
|
||||
case 3:
|
||||
do {
|
||||
System.out.println("enter handling fee");
|
||||
handlingFee = Double.parseDouble(scan.nextLine());
|
||||
}
|
||||
while (handlingFee <= 0);
|
||||
pType = PackageFactory.PackageType.Electronic;
|
||||
break;
|
||||
}
|
||||
PackageInfo p = PackageFactory.create(pType, pName, pNotes, pPrice, pWeight, false, pDate, author, expiryDate, handlingFee);
|
||||
packageList.add(p);
|
||||
System.out.println(pName + " has been added to the list!");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in an ArrayList of PackageInfo objects and prints out the list of packages
|
||||
* in the ArrayList. The user is then prompted to enter the number of the package they want to
|
||||
* remove. If the user enters a number that is not in the list, the user is prompted to enter a
|
||||
* number again. If the user enters 0, the function returns without removing anything. If the user
|
||||
* enters a number that is in the list, the package is removed from the list and the user is
|
||||
* notified
|
||||
*
|
||||
* @param packageList the list of packages to be displayed
|
||||
*/
|
||||
public void remove(ArrayList<PackageInfo> packageList) {
|
||||
this.list(packageList);
|
||||
if (packageList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Scanner scan = new Scanner(System.in);
|
||||
int n;
|
||||
do {
|
||||
System.out.println("enter item number you want to remove (0 to cancel):");
|
||||
n = scan.nextInt();
|
||||
}
|
||||
while (n < 0 || n > packageList.size());
|
||||
if (n > 0) {
|
||||
System.out.println(packageList.get(n - 1).getName() + " has been removed from the list.");
|
||||
packageList.remove(n - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in a list of packages, a boolean for whether or not the user wants to see
|
||||
* packages that are due, and a boolean for whether or not the user wants to see all packages. It
|
||||
* then returns a list of packages that are sorted by their expected delivery date
|
||||
*
|
||||
* @param pList the list of packages to be sorted
|
||||
* @param due true if you want to sort the list by due date, false if you want to sort the list by
|
||||
* expected date
|
||||
* @return An ArrayList of PackageInfo objects.
|
||||
*/
|
||||
//due=true returns overdue packages, else upcoming packages
|
||||
public ArrayList<PackageInfo> sortList(ArrayList<PackageInfo> pList, boolean due) {
|
||||
ArrayList<PackageInfo> sortedList = new ArrayList<>();
|
||||
LocalDateTime today = LocalDateTime.now();
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm");
|
||||
today.format(format);
|
||||
for (int i = 0; i < pList.size(); i++) {
|
||||
PackageInfo p = pList.get(i);
|
||||
if (!p.getDelivered()) {
|
||||
if (due && today.isAfter(p.getExpectedDate())) {
|
||||
sortedList.add(p);
|
||||
} else if (!due && today.isBefore(p.getExpectedDate())) {
|
||||
sortedList.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(sortedList);
|
||||
return sortedList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in a list of packages and returns a list of packages that are overdue
|
||||
*
|
||||
* @param packageList the list of packages to be sorted
|
||||
*/
|
||||
public void overDueList(ArrayList<PackageInfo> packageList) {
|
||||
ArrayList<PackageInfo> overdue = sortList(packageList, true);
|
||||
if (overdue.size() == 0) {
|
||||
System.out.println("no overdue packages to show");
|
||||
return;
|
||||
}
|
||||
this.list(overdue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes in a list of packages and prints out the packages that are upcoming
|
||||
*
|
||||
* @param packageList the list of packages to be sorted
|
||||
*/
|
||||
public void upcomingList(ArrayList<PackageInfo> packageList) {
|
||||
ArrayList<PackageInfo> upcoming = sortList(packageList, false);
|
||||
if (upcoming.size() == 0) {
|
||||
System.out.println("no upcoming packages to show");
|
||||
return;
|
||||
}
|
||||
this.list(upcoming);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a list of packages and returns a list of packages that have not been
|
||||
* delivered
|
||||
*
|
||||
* @param packageList The list of packages to be filtered
|
||||
* @return An ArrayList of PackageInfo objects that have not been delivered.
|
||||
*/
|
||||
public ArrayList<PackageInfo> getUndelivered(List<PackageInfo> packageList) {
|
||||
ArrayList<PackageInfo> undelivered = new ArrayList<>();
|
||||
for (int i = 0; i < packageList.size(); i++) {
|
||||
if (packageList.get(i).getDelivered() == false) {
|
||||
undelivered.add(packageList.get(i));
|
||||
}
|
||||
}
|
||||
return undelivered;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a list of packages and prints out the undelivered packages, then asks the
|
||||
* user to select a package to mark as delivered
|
||||
*
|
||||
* @param packageList the list of packages to be marked as delivered
|
||||
*/
|
||||
public void markDelivered(ArrayList<PackageInfo> packageList) {
|
||||
ArrayList<PackageInfo> undelivered = getUndelivered(packageList);
|
||||
if (undelivered.size() == 0) {
|
||||
System.out.println("No undelivered packages to show");
|
||||
return;
|
||||
}
|
||||
this.list(undelivered);
|
||||
Scanner scan = new Scanner(System.in);
|
||||
int n;
|
||||
do {
|
||||
System.out.println("enter item number you want to mark delivered (0 to cancel):");
|
||||
n = scan.nextInt();
|
||||
}
|
||||
while (n < 0 || n > undelivered.size());
|
||||
if (n > 0) {
|
||||
PackageInfo p = undelivered.get(n - 1);
|
||||
packageList.get(packageList.indexOf(p)).setDelivered(true);
|
||||
System.out.println(p.getName() + " has been delivered.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
package cmpt213.assignment3.packagedeliveries.gson.extras;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Adapts values whose runtime type may differ from their declaration type. This
|
||||
* is necessary when a field's type is not the same type that GSON should create
|
||||
* when deserializing that field. For example, consider these types:
|
||||
* <pre> {@code
|
||||
* abstract class Shape {
|
||||
* int x;
|
||||
* int y;
|
||||
* }
|
||||
* class Circle extends Shape {
|
||||
* int radius;
|
||||
* }
|
||||
* class Rectangle extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Diamond extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Drawing {
|
||||
* Shape bottomShape;
|
||||
* Shape topShape;
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>Without additional type information, the serialized JSON is ambiguous. Is
|
||||
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* This class addresses this problem by adding type information to the
|
||||
* serialized JSON and honoring that type information when the JSON is
|
||||
* deserialized: <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "type": "Diamond",
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "type": "Circle",
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* Both the type field name ({@code "type"}) and the type labels ({@code
|
||||
* "Rectangle"}) are configurable.
|
||||
*
|
||||
* <h3>Registering Types</h3>
|
||||
* Create a {@code cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory} by passing the base type and type field
|
||||
* name to the {@link #of} factory method. If you don't supply an explicit type
|
||||
* field name, {@code "type"} will be used. <pre> {@code
|
||||
* cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
|
||||
* = cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory.of(Shape.class, "type");
|
||||
* }</pre>
|
||||
* Next register all of your subtypes. Every subtype must be explicitly
|
||||
* registered. This protects your application from injection attacks. If you
|
||||
* don't supply an explicit type label, the type's simple name will be used.
|
||||
* <pre> {@code
|
||||
* shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
|
||||
* shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
|
||||
* shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
|
||||
* }</pre>
|
||||
* Finally, register the type adapter factory in your application's GSON builder:
|
||||
* <pre> {@code
|
||||
* Gson gson = new GsonBuilder()
|
||||
* .registerTypeAdapterFactory(shapeAdapterFactory)
|
||||
* .create();
|
||||
* }</pre>
|
||||
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
|
||||
* cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory.of(Shape.class)
|
||||
* .registerSubtype(Rectangle.class)
|
||||
* .registerSubtype(Circle.class)
|
||||
* .registerSubtype(Diamond.class);
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Serialization and deserialization</h3>
|
||||
* In order to serialize and deserialize a polymorphic object,
|
||||
* you must specify the base type explicitly.
|
||||
* <pre> {@code
|
||||
* Diamond diamond = new Diamond();
|
||||
* String json = gson.toJson(diamond, Shape.class);
|
||||
* }</pre>
|
||||
* And then:
|
||||
* <pre> {@code
|
||||
* Shape shape = gson.fromJson(json, Shape.class);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
|
||||
private final Class<?> baseType;
|
||||
private final String typeFieldName;
|
||||
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<>();
|
||||
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<>();
|
||||
private final boolean maintainType;
|
||||
|
||||
private RuntimeTypeAdapterFactory(Class<?> baseType, String typeFieldName, boolean maintainType) {
|
||||
if (typeFieldName == null || baseType == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.baseType = baseType;
|
||||
this.typeFieldName = typeFieldName;
|
||||
this.maintainType = maintainType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
* {@code maintainType} flag decide if the type will be stored in pojo or not.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName, boolean maintainType) {
|
||||
return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, maintainType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
|
||||
return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
|
||||
* the type field name.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
|
||||
return new RuntimeTypeAdapterFactory<>(baseType, "type", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by {@code label}. Labels are case
|
||||
* sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or {@code label}
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
|
||||
if (type == null || label == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
|
||||
throw new IllegalArgumentException("types and labels must be unique");
|
||||
}
|
||||
labelToSubtype.put(label, type);
|
||||
subtypeToLabel.put(type, label);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by its {@link Class#getSimpleName simple
|
||||
* name}. Labels are case sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or its simple name
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
|
||||
return registerSubtype(type, type.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
|
||||
if (type.getRawType() != baseType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final TypeAdapter<JsonElement> jsonElementAdapter = gson.getAdapter(JsonElement.class);
|
||||
final Map<String, TypeAdapter<?>> labelToDelegate = new LinkedHashMap<>();
|
||||
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
|
||||
TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
|
||||
labelToDelegate.put(entry.getKey(), delegate);
|
||||
subtypeToDelegate.put(entry.getValue(), delegate);
|
||||
}
|
||||
|
||||
return new TypeAdapter<R>() {
|
||||
@Override
|
||||
public R read(JsonReader in) throws IOException {
|
||||
JsonElement jsonElement = jsonElementAdapter.read(in);
|
||||
JsonElement labelJsonElement;
|
||||
if (maintainType) {
|
||||
labelJsonElement = jsonElement.getAsJsonObject().get(typeFieldName);
|
||||
} else {
|
||||
labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
|
||||
}
|
||||
|
||||
if (labelJsonElement == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType
|
||||
+ " because it does not define a field named " + typeFieldName);
|
||||
}
|
||||
String label = labelJsonElement.getAsString();
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
|
||||
+ label + "; did you forget to register a subtype?");
|
||||
}
|
||||
return delegate.fromJsonTree(jsonElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, R value) throws IOException {
|
||||
Class<?> srcType = value.getClass();
|
||||
String label = subtypeToLabel.get(srcType);
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ "; did you forget to register a subtype?");
|
||||
}
|
||||
JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
|
||||
|
||||
if (maintainType) {
|
||||
jsonElementAdapter.write(out, jsonObject);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject clone = new JsonObject();
|
||||
|
||||
if (jsonObject.has(typeFieldName)) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ " because it already defines a field named " + typeFieldName);
|
||||
}
|
||||
clone.add(typeFieldName, new JsonPrimitive(label));
|
||||
|
||||
for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
|
||||
clone.add(e.getKey(), e.getValue());
|
||||
}
|
||||
jsonElementAdapter.write(out, clone);
|
||||
}
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package cmpt213.assignment3.packagedeliveries.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* It's a subclass of PackageInfo that adds an author field
|
||||
*/
|
||||
public class BookPackage extends PackageInfo {
|
||||
String author;
|
||||
|
||||
public BookPackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author) {
|
||||
|
||||
super(name, note, price, weight, delivered, expectedDate);
|
||||
this.author = author;
|
||||
this.setType("book");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "\nAuthor: " + author;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cmpt213.assignment3.packagedeliveries.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* ElectronicPackage is a subclass of PackageInfo that adds a handlingFee attribute
|
||||
*/
|
||||
public class ElectronicPackage extends PackageInfo {
|
||||
double handlingFee;
|
||||
|
||||
public ElectronicPackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, double handlingFee) {
|
||||
super(name, note, price, weight, delivered, expectedDate);
|
||||
this.handlingFee = handlingFee;
|
||||
this.setType("electronic");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "\nHandling fee: " + handlingFee;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package cmpt213.assignment3.packagedeliveries.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
/**
|
||||
* PackageInfo is a class that contains information about a package
|
||||
*/
|
||||
|
||||
public class PackageInfo implements Comparable<PackageInfo> {
|
||||
private final String name;
|
||||
private final String note;
|
||||
private final double price;
|
||||
private final double weight;
|
||||
private final LocalDateTime expectedDate;
|
||||
private boolean delivered;
|
||||
private String type;
|
||||
|
||||
public PackageInfo(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate) {
|
||||
this.name = name;
|
||||
this.note = note;
|
||||
this.price = price;
|
||||
this.weight = weight;
|
||||
this.delivered = delivered;
|
||||
this.expectedDate = expectedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the name of the person.
|
||||
*
|
||||
* @return The name of the person.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public boolean getDelivered() {
|
||||
return delivered;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the value of the delivered variable to the value of the delivered parameter.
|
||||
*
|
||||
* @param delivered This is a boolean value that indicates whether the message has been delivered
|
||||
* to the recipient.
|
||||
*/
|
||||
public void setDelivered(boolean delivered) {
|
||||
this.delivered = delivered;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpectedDate() {
|
||||
return expectedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the type of the object to the type passed in as a parameter
|
||||
*
|
||||
* @param type The type of the event.
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
// Comparing the expected date of the package to the expected date of the package passed in as a
|
||||
// parameter.
|
||||
@Override
|
||||
public int compareTo(PackageInfo p) {
|
||||
return this.expectedDate.compareTo(p.getExpectedDate());
|
||||
}
|
||||
|
||||
// Overriding the toString method.
|
||||
@Override
|
||||
public String toString() {
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm");
|
||||
LocalDateTime today = LocalDateTime.now();
|
||||
today.format(format);
|
||||
long diff = ChronoUnit.DAYS.between(today, expectedDate);
|
||||
String isDelivered = delivered ? "yes" : "no";
|
||||
return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: " + price + "\n" + "Weight: " + weight + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue");
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cmpt213.assignment3.packagedeliveries.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* It's a subclass of PackageInfo that adds an expiry date
|
||||
*/
|
||||
public class PerishablePackage extends PackageInfo {
|
||||
LocalDateTime expiryDate;
|
||||
|
||||
// It's a constructor that initializes the object with the given parameters.
|
||||
public PerishablePackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, LocalDateTime expiryDate) {
|
||||
super(name, note, price, weight, delivered, expectedDate);
|
||||
this.expiryDate = expiryDate;
|
||||
this.setType("perishable");
|
||||
}
|
||||
|
||||
// It's a method that returns a string representation of the object.
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "\nExpiry date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expiryDate);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package cmpt213.assignment3.packagedeliveries.view;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class Input {
|
||||
JTextField typeLabel;
|
||||
public Input(Frame main){
|
||||
JPanel p = new JPanel();
|
||||
String[] type={"book", "perishable", "electronic"};
|
||||
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
|
||||
JComboBox<String> packageType=new JComboBox<>(type);
|
||||
packageType.setPreferredSize(new Dimension(300, 30));
|
||||
packageType.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String p=(String) packageType.getSelectedItem();
|
||||
switch (p){
|
||||
case "book":
|
||||
typeLabel.setText("author name");
|
||||
break;
|
||||
case "perishable":
|
||||
typeLabel.setText("expiry date");
|
||||
break;
|
||||
case "electronic":
|
||||
typeLabel.setText("handling fee");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JPanel name=new JPanel();
|
||||
JLabel nameLabel=new JLabel();
|
||||
JTextField namefield= new JTextField();
|
||||
name.setLayout(new BoxLayout(name, BoxLayout.X_AXIS));
|
||||
nameLabel.setText("name:");
|
||||
nameLabel.setPreferredSize(new Dimension(50, 25));
|
||||
name.add(nameLabel);
|
||||
name.add(namefield);
|
||||
name.setPreferredSize(new Dimension(200, 50));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package cmpt213.assignment3.packagedeliveries.view;
|
||||
|
||||
import cmpt213.assignment3.packagedeliveries.control.PackageDeliveriesTracker;
|
||||
import com.sun.tools.jconsole.JConsoleContext;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Objects;
|
||||
|
||||
public class JavaSwingUI implements ActionListener {
|
||||
JFrame uiFrame;
|
||||
JTextPane uiPane;
|
||||
private final PackageDeliveriesTracker pTracker=PackageDeliveriesTracker.getInstance();
|
||||
|
||||
public void displayMainPage(){
|
||||
pTracker.load();
|
||||
uiFrame=new JFrame("package deliveries tracker");
|
||||
uiFrame.setSize(500, 500);
|
||||
uiFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
uiFrame.setLayout(new BoxLayout(uiFrame.getContentPane(), BoxLayout.Y_AXIS));
|
||||
uiFrame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
pTracker.save();
|
||||
super.windowClosing(e);
|
||||
uiFrame.dispose();
|
||||
}
|
||||
});
|
||||
uiFrame.setVisible(true);
|
||||
displayPackages();
|
||||
addButton();
|
||||
}
|
||||
|
||||
private void displayPackages(){
|
||||
uiPane=new JTextPane();
|
||||
JScrollPane scrollView=new JScrollPane(uiPane);
|
||||
uiPane.setEditable(false);
|
||||
scrollView.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
uiFrame.add(scrollView);
|
||||
uiPane.setText(pTracker.getAllPackages());
|
||||
uiPane.setCaretPosition(0);
|
||||
}
|
||||
|
||||
private void addButton(){
|
||||
JButton add=new JButton("add a package");
|
||||
JPanel addPanel=new JPanel();
|
||||
addPanel.setLayout(new BoxLayout(addPanel, BoxLayout.X_AXIS));
|
||||
addPanel.add(add);
|
||||
addPanel.setPreferredSize(new Dimension(500, 50));
|
||||
uiFrame.add(addPanel);
|
||||
add.addActionListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String actionString= e.getActionCommand();
|
||||
switch (actionString){
|
||||
case "add a package":
|
||||
addPackage();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addPackage(){
|
||||
new Input(uiFrame);
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package cmpt213.assignment3.packagedeliveries.view;
|
Loading…
Reference in new issue