1 Project 4 Introduction – the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of Sea Ports. Here are the classes and their instance variables we wish to define: SeaPortProgram extends JFrame o variables used by the GUI interface o world: World Thing implement Comparable o index: int o name: String o parent: int World extends Thing o ports: ArrayList o time: PortTime SeaPort extends Thing o docks: ArrayList o que: ArrayList // the list of ships waiting to dock o ships: ArrayList // a list of all the ships at this port o persons: ArrayList // people with skills at this port Dock extends Thing o ship: Ship Ship extends Thing o arrivalTime, dockTime: PortTime o draft, length, weight, width: double o jobs: ArrayList PassengerShip extends Ship o numberOfOccupiedRooms: int o numberOfPassengers: int o numberOfRooms: int CargoShip extends Ship o cargoValue: double o cargoVolume: double o cargoWeight: double Person extends Thing o skill: String Job extends Thing – optional till Projects 3 and 4 o duration: double o requirements: ArrayList // should be some of the skills of the persons PortTime o time: int Eventually, in Projects 3 and 4, you will be asked to show the progress of the jobs using JProgressBar’s. 2 Here’s a very quick overview of all projects: 1. Read a data file, create the internal data structure, create a GUI to display the structure, and let the user search the structure. 2. Sort the structure, use hash maps to create the structure more efficiently. 3. Create a thread for each job, cannot run until a ship has a dock, create a GUI to show the progress of each job. 4. Simulate competing for resources (persons with particular skills) for each job. Project 4 General Objectives Project 4 – Concurrency Resource pools o Threads competing for multiple resources Blocking threads Extending the GUI interface to visualize the resource pools and progress of the various threads. Documentation Requirements: You should start working on a documentation file before you do anything else with these projects, and fill in items as you go along. Leaving the documentation until the project is finished is not a good idea for any number of reasons. The documentation should include the following (graded) elements: Cover page (including name, date, project, your class information) Design o including a UML class diagram o classes, variables and methods: what they mean and why they are there o tied to the requirements of the project User’s Guide o how would a user start and run your project o any special features o effective screen shots are welcome, but don’t overdo this Test Plan o do this BEFORE you code anything o what do you EXPECT the project to do o justification for various data files, for example Lessons Learned o express yourself here o a way to keep good memories of successes after hard work 3 Project 4 Specific Goals: Extend project 3 to include making jobs wait until people with the resources required by the job are available at the port. Elaboration: 1. Reading Job specifications from a data file and adding the required resources to each Job instance. 2. Resource pools – SeaPort.ArrayList list of persons with particular skills at each port, treated as resource pools, along with supporting assignment to ships and jobs. 3. Job threads – using the resource pools and supporting the concept of blocking until required resources are available before proceeding. 4. The Job threads should be efficient: 1. If the ship is at a dock and all the people with required skills are available, the job should start. 2. Otherwise, the Job should not hold any resources if it cannot progress. 3. Use synchronization to avoid race conditions. 4. Each Job thread should hold any required synchronization locks for a very short period. 5. When a job is over, all the resources used by the job (the people) should be released back to the port. 6. When all the jobs of a ship are done, the ship should depart the dock and if there are any ships in the port que, one of then should should be assigned to the free dock, and that ships jobs can now try to progress. 7. NOTE: If a job can never progress because the port doesn’t have enough skills among all the persons at the port, the program should report this and cancel the job. 5. GUI showing: o Resources in pools – how many people with skill are currently available o Thread progress, resources acquired, and resources requests still outstanding Deliverables: 1. Java source code files 2. Data files used to test your program 3. Configuration files used 4. A well-written document including the following sections: a. Design: including a UML class diagram showing the type of the class relationships b. User’s Guide: description of how to set up and run your application c. Test Plan: sample input and expected results, and including test data and results, with screen snapshots of some of your test cases d. Optionally, Comments: design strengths and limitations, and suggestions for future improvement and alternative approaches e. Lessons Learned f. Use one of the following formats: MS Word docx or PDF. 4 Your project is due by midnight, EST, on the day of the date posted in the class schedule. We do not recommend staying up all night working on your project – it is so very easy to really mess up a project at the last minute by working when one was overly tired. Your instructor’s policy on late projects applies to this project. Submitted projects that show evidence of plagiarism will be handled in accordance with UMUC Policy 150.25 — Academic Dishonesty and Plagiarism. Format: The documentation describing and reflecting on your design and approach should be written using Microsoft Word or PDF, and should be of reasonable length. The font size should be 12 point. The page margins should be one inch. The paragraphs should be double spaced. All figures, tables, equations, and references should be properly labeled and formatted using APA style. Coding Hints: Code format: (See Google Java Style guide for specifics (https://google.github.io/styleguide/javaguide.html)) o header comment block, including the following information in each source code file: o file name o date o author o purpose o appropriate comments within the code o appropriate variable and function names o correct indentation Errors: o code submitted should have no compilation or run-time errors Warnings: o Your program should have no warnings o Use the following compiler flag to show all warnings: javac -Xlint *.java o More about setting up IDE’s to show warnings o Generics – your code should use generic declarations appropriately, and to eliminate all warnings Elegance: o just the right amount of code o effective use of existing classes in the JDK o effective use of the class hierarchy, including features related to polymorphism. GUI notes: o GUI should resize nicely o DO NOT use the GUI editor/generators in an IDE (integrated development environment, such as Netbeans and Eclipse) o Do use JPanel, JFrame, JTextArea, JTextField, JButton, JLabel, JScrollPane panels on panels gives even more control of the display during resizing JTable and/or JTree for Projects 2, 3 and 4 5 Font using the following gives a nicer display for this program, setting for the JTextArea jta: jta.setFont (new java.awt.Font (“Monospaced”, 0, 12)); o GridLayout and BorderLayout – FlowLayout rarely resizes nicely GridBagLayout for extreme control over the displays you may wish to explore other layout managers o ActionListener, ActionEvent – responding to JButton events Starting with JDK 8, lambda expression make defining listeners MUCH simpler. See the example below, with jbr (read), jbd (display) and jbs (search) three different JButtons. jcb is a JComboBox and jtf is a JTextField. jbr.addActionListener (e -> readFile()); jbd.addActionListener (e -> displayCave ()); jbs.addActionListener (e -> search ((String)(jcb.getSelectedItem()), jtf.getText())); o JFileChooser – select data file at run time o JSplitPane – optional, but gives user even more control over display panels Grading Rubric: Attribute Meets Does not meet Design 20 points Contains just the right amount of code. Uses existing classes in the JDK effectively. Effectively uses of the class hierarchy, including features related to polymorphism. GUI elements should be distinct from the other classes in the program. 0 points Does not contain just the right amount of code. Does not use existing classes in the JDK effectively. Does not effectively use of the class hierarchy, including features related to polymorphism. GUI elements are not distinct from the other classes in the program. Functionality 40 points Contains no coding errors. Contains no compile warnings. Builds from previous projects. Includes reading Job specifications from a data file and adding the 0 points Contains coding errors. Contains compile warnings. Does not build from previous projects. Does not include reading Job specifications from a data file and 6 required resources to each Job instance. Includes resource pools – SeaPort.ArrayList list of persons with particular skills at each port, treated as resource pools, along with supporting assignment to ships and jobs. Includes job threads – using the resource pools and supporting the concept of blocking until required resources are available before proceeding. The Job threads should be efficient. GUI shows resources in pools – how many people with skill are currently available and thread progress, resources acquired, and resources requests still outstanding. adding the required resources to each Job instance. Does not include resource pools – SeaPort.ArrayList list of persons with particular skills at each port, treated as resource pools, along with supporting assignment to ships and jobs. Does not include job threads – using the resource pools and supporting the concept of blocking until required resources are available before proceeding. The Job threads are not efficient. GUI does not show resources in pools – how many people with skill are currently available and thread progress, resources acquired, and resources requests still outstanding. Test Data 20 points Tests the application using multiple and varied test cases. 0 points Does not test the application using multiple and varied test cases. Documentation and submission 15 points Source code files include header comment block, including file name, date, author, purpose, appropriate comments within the code, appropriate variable and function names, correct indentation. Submission includes Java source code files, Data files used to test your program, Configuration files used. Documentation includes a UML class diagram showing the type of the class relationships. 0 points Source code files do not include header comment block, or include file name, date, author, purpose, appropriate comments within the code, appropriate variable and function names, correct indentation. Submission does not include Java source code files, Data files used to test your program, Configuration files used. Documentation does not include a UML class diagram showing the type of the class relationships. Documentation does not include a user’s Guide describing of how to set up and run your application. 7 Documentation includes a user’s Guide describing of how to set up and run your application. Documentation includes a test plan with sample input and expected results, test data and results and screen snapshots of some of your test cases. Documentation includes Lessons learned. Documentation is in an acceptable format. Documentation does not include a test plan with sample input and expected results, test data and results and screen snapshots of some of your test cases. Documentation does not include Lessons learned. Documentation is not in an acceptable format. Documentation form, grammar and spelling 5 points Document is well-organized. The font size should be 12 point. The page margins should be one inch. The paragraphs should be double spaced. All figures, tables, equations, and references should be properly labeled and formatted using APA style. The document should contain minimal spelling and grammatical errors. 0 points Document is not well-organized. The font size is not 12 point. The page margins are not one inch. The paragraphs are not double spaced. All figures, tables, equations, and references are not properly labeled or formatted using APA style. The document should contains many spelling and grammatical errors.
Expert Answer
The following is the required program as per your requirements. Code to copy is given at the end. Get back to me if you have any doubts.
Program Screenshot:
Thing.java
Dock.java
Job.java
World.java
Person.java
SeaPort.java
Ship.java
CargoShip.java
PassengerShip.java
PortTime.java
SeaPortProgram.java
Input text file: aSPaa.txt
Screenshot of the output:
Uml class diagram:
Code to copy:
Thing.java
import java.util.HashMap;
import java.util.Scanner;
//define the class Thing implements Comparable
public class Thing implements Comparable<Thing> {
//declare the variables
private String name;
private int index;
private int parent;
Thing thinkObject;
//constructor
public Thing(){}
//constructor
public Thing(Scanner sc) {
this.name = sc.next();
this.index = sc.nextInt();
this.parent = sc.nextInt();
}
//getter methods
public int getIndex() {
return index;
}
public String getName() {
return name;
}
public int getParent() {
return parent;
}
//setter method
public void setThingObject(HashMap parentHashMap){
if(parentHashMap.get(parent) != null)
thinkObject = (Thing) parentHashMap.get(parent);
}
//definition of the compareTo() method
@Override
public int compareTo(Thing obj) {
return name.compareTo(obj.getName());
}
//definition of the toString() method
synchronized public String toString() {
return name + ” ” + index;
}
}
Dock.java
import java.util.ArrayList;
import java.util.Scanner;
//define the class Dock extends Thing
public class Dock extends Thing
{
// declare the variables
private Ship ship;
// constructor
public Dock(Scanner sc)
{
super(sc);
}
// definition of the method setShip
public void setShip(Ship ship)
{
synchronized (this)
{
this.ship = ship;
if (ship != null)
{
this.ship.thinkObject = this;
}
}
}
// definition of the method getShip
public Ship getShip()
{
return ship;
}
// definition of the method leaveShipFromDock()
public void leaveShipFromDock()
{
setShip(null);
checkDocksAtDock();
}
// definition of the method requestForNewShip()
private void requestForNewShip()
{
Ship ship = ((SeaPort) thinkObject).getShipFromQue();
if (ship != null)
setShip(ship);
}
// definition of the method checkDocksAtDock()
public void checkDocksAtDock()
{
if (ship == null || ship.ships.size() == 0)
requestForNewShip();
}
// definition of the method requestPersonnel()
boolean requestPersonnel(ArrayList<String> requirements)
{
return ((SeaPort) thinkObject).requestPersonnel(requirements);
}
// definition of the method requestWorkers()
public ArrayList<Person> requestWorkers(ArrayList<String> requirements,
Job job)
{
return ((SeaPort) thinkObject).requestWorkers(requirements, job);
}
// definition of the method releaseWorkers()
public void releaseWorkers(ArrayList<Person> workers)
{
((SeaPort) thinkObject).releaseWorkers(workers);
}
// definition of the method toString()
public String toString()
{
if (ship != null)
return “n Dock: ” + super.toString() + “n ” + ship.toString();
else
return “n Dock: ” + super.toString();
}
}
Job.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
//define the class Job extends Thing implements Runnable
public class Job extends Thing implements Runnable {
//declare the variables
private ArrayList<String> requirements = new ArrayList<String>();
JPanel panel;
long duration;
JProgressBar bar = new JProgressBar();
boolean flag = true, noKillFlag = true;
JButton stop = new JButton(“Stop”);
JButton cancel = new JButton(“Cancel”);
Status status = Status.WAITING;
Job removedJob;
Ship parentShip;
enum Status {RUNNING, SUSPENDED, WAITING, DONE}
//constructor
public Job(Scanner sc) {
super(sc);
duration = (long) sc.nextDouble();
while (sc.hasNext()) {
String requirement = sc.next();
if (requirement != null && requirement.length() > 0)
requirements.add(requirement);
}
}
//definition of the method setThingObject()
public void setThingObject(HashMap thinkObject) {
if (thinkObject.get(getParent()) != null) {
this.thinkObject = (Thing) thinkObject.get(getParent());
parentShip = (Ship) this.thinkObject;
setElements();
removedJob = this;
new Thread(this).start();
}
}
//definition of the method setElements()
private void setElements() {
panel = new JPanel();
bar = new JProgressBar();
bar.setStringPainted(true);
stop.setMinimumSize(new Dimension(120, 25));
stop.setMaximumSize(new Dimension(120, 25));
GroupLayout groupLayout = new GroupLayout(panel);
panel.setLayout(groupLayout);
setLayout(groupLayout);
setActionListeners();
}
//definition of the method setLayout()
private void setLayout(GroupLayout groupLayout) {
groupLayout.setAutoCreateGaps(true);
groupLayout.setAutoCreateContainerGaps(true);
JLabel jLabel = new JLabel(parentShip.getName(),
SwingConstants.CENTER);
jLabel.setMinimumSize(new Dimension(150, 25));
jLabel.setMaximumSize(new Dimension(150, 25));
groupLayout.setHorizontalGroup(groupLayout.createSequentialGroup()
.addComponent(bar)
.addComponent(jLabel)
.addComponent(stop)
.addComponent(cancel));
groupLayout.setVerticalGroup(groupLayout.createParallelGroup
(GroupLayout.Alignment.LEADING)
.addComponent(bar)
.addComponent(jLabel)
.addComponent(stop)
.addComponent(cancel));
}
//definition of the method getPanel()
public JPanel getPanel() {
return panel;
}
//definition of the method setActionListeners()
private void setActionListeners() {
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setFlag();
}
});
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setKillFlag();
}
});
}
//definition of the method setFlag()
public void setFlag() {
flag = !flag;
}
//definition of the method setKillFlag()
public void setKillFlag() {
noKillFlag = false;
cancel.setBackground(Color.red);
}
//definition of the method showStatus()
void showStatus(Status st) {
status = st;
switch (status) {
case RUNNING:
stop.setBackground(Color.green);
stop.setText(“Running”);
break;
case SUSPENDED:
stop.setBackground(Color.yellow);
stop.setText(“Suspended”);
break;
case WAITING:
stop.setBackground(Color.orange);
stop.setText(“Waiting turn”);
break;
case DONE:
stop.setBackground(Color.red);
stop.setText(“Done”);
break;
}
}
//definition of the method run()
public void run() {
// wait for the world to be initialized, otherwise
//simulation does not work properly
while (!World.getValue())
waitTime(300);
while (!parentShip.isShipDocked()) {
waitTime(100);
}
while (!parentShip.processShip()) {
waitTime(100);
}
ArrayList<Person> workers = null;
if (requirements.size() == 0 || parentShip.
requestPersonnel(requirements)) {
if (requirements.size() != 0) {
do {
waitTime(100);
workers = parentShip.requestWorkers(requirements,
removedJob);
} while (workers == null || workers.size() !=
requirements.size());
}
long time = System.currentTimeMillis();
long startTime = time;
long stopTime = time + 1000 * duration;
double duration = stopTime – time;
while (time < stopTime && noKillFlag) {
waitTime(100);
if (flag) {
showStatus(Status.RUNNING);
time += 100;
bar.setValue((int) (((time – startTime) /
duration) * 100));
} else {
showStatus(Status.SUSPENDED);
}
}
bar.setValue(100);
showStatus(Status.DONE);
} else {
showStatus(Status.SUSPENDED);
}
if (workers != null && workers.size() > 0)
parentShip.releaseWorkers(workers);
parentShip.removeShip(removedJob);
}
//definition of the method waitTime()
private void waitTime(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
}
}
//definition of the method toString()
public String toString() {
return String.format(“j:%7d:%15s:%5d”, getIndex(),
getName(), duration);
}
}
World.java
import java.util.*;
//define the class World that extends the class Thing
public class World extends Thing {
//declare the variables
HashMap<Integer, SeaPort> ports;
PortTime time;
static boolean value = false;
//define the conresultuctor
public World() {
ports = new HashMap<Integer, SeaPort>();
}
//getter and setter methods
public static void setValue(){
value = true;
}
public static boolean getValue(){
return value;
}
//definition of the method readFile()
// takes Scanner object and reads the data from the file
public void readFile(Scanner scan) {
// Create an object for Hashmap for Dock class
HashMap<Integer, Dock> dockHashMap = new HashMap<Integer, Dock>();
// Create an object for Hashmap for Ship class
HashMap<Integer, Ship> shipHashMap = new HashMap<Integer, Ship>();
// read the data using while loop
while (scan.hasNextLine()) {
//read the line
String line = scan.nextLine();
//replace with space comma
line = line.replaceAll(“^\s+”, “”);
if (line.length() > 0 && line.charAt(0) != ‘/’)
{
Scanner sc = new Scanner(line);
if (!sc.hasNext())
return;
String word = sc.next().toLowerCase();
//if the word is port then call the method addPort()
if (word.matches(“port”))
addPort(sc);
//if the word is dock then call the method addDock()
else if (word.matches(“dock”))
addDock(sc, dockHashMap);
//if the word is pship then call the method addPassengerShip()
else if (word.matches(“pship”))
addPassengerShip(sc, dockHashMap, shipHashMap);
//if the word is cship then call the method addCargoShip()
else if (word.matches(“cship”))
addCargoShip(sc, dockHashMap, shipHashMap);
//if the word is person then call the method addPerson()
else if (word.matches(“person”))
addPerson(sc);
//if the word is job then call the method addJob()
else if (word.matches(“job”))
addJob(sc, shipHashMap);
}
}
}
//definition of the method addJob()
private void addJob(Scanner sc, HashMap<Integer, Ship> shipHashMap) {
Job job = new Job(sc);
if (shipHashMap.get(job.getParent()) != null)
{
job.setThingObject(shipHashMap);
shipHashMap.get(job.getParent()).ships.add(job);
}
}
//definition of the method addPerson()
private void addPerson(Scanner sc) {
Person person = new Person(sc);
ports.get(person.getParent()).addPerson(person);
}
//definition of the method addCargoShip()
private void addCargoShip(Scanner sc, HashMap<Integer, Dock> dockHashMap,
HashMap<Integer, Ship> shipHashMap) {
CargoShip cargoShip = new CargoShip(sc);
shipHashMap.put(cargoShip.getIndex(), cargoShip);
assignShip(cargoShip, dockHashMap);
}
//definition of the method addPassengerShip()
private void addPassengerShip(Scanner sc, HashMap<Integer, Dock>
dockHashMap, HashMap<Integer, Ship> shipHashMap) {
PassengerShip passengerShip = new PassengerShip(sc);
shipHashMap.put(passengerShip.getIndex(), passengerShip);
assignShip(passengerShip, dockHashMap);
}
//definition of the method addDock()
private void addDock(Scanner sc, HashMap<Integer, Dock> dockHashMap)
{
Dock dock = new Dock(sc);
dock.setThingObject(ports);
dockHashMap.put(dock.getIndex(), dock);
// Add dock to port
ports.get(dock.getParent()).addDock(dock);
}
//definition of the method addPort()
private void addPort(Scanner scan) {
SeaPort seaPort = new SeaPort(scan);
ports.put(seaPort.getIndex(), seaPort);
}
//definition of the method assignShip()
private void assignShip(Ship ship, HashMap<Integer, Dock> dockHashMap) {
Dock dock = dockHashMap.get(ship.getParent());
if (dock == null) {
ship.setThingObject(ports);
ports.get(ship.getParent()).addShip(ship);
ports.get(ship.getParent()).addShipToQue(ship);
return;
}
if (dock.getShip() != null)
ports.get(ship.getParent()).addShipToQue(ship);
else
dock.setShip(ship);
ports.get(dock.getParent()).addShip(ship);
}
//definition of the method sortByShipName()
public String sortByShipName() {
List<SeaPort> list = new ArrayList<SeaPort>();
String result = “”;
for (SeaPort seaPort : ports.values()) {
seaPort.sortAllListsByName();
list.add(seaPort);
}
Collections.sort(list);
for (SeaPort seaPort : list) {
result += “Port: “;
result += seaPort.getName() + “n Ships:n “;
for (Ship ship : seaPort.ships) {
result += ship.getName() + “n “;
result += ” Jobs:n “;
for (Job job : ship.ships) {
result += job.getName() + “n “;
}
result += “n “;
}
result += “n Docks:n “;
for (Dock dock : seaPort.docks) {
result += dock.getName() + “n “;
}
result += “n People:n “;
for (Person person : seaPort.persons) {
result += person.getName() + “n “;
}
}
return result;
}
//definition of the method sortByShipWeight()
public String sortByShipWeight() {
String result = “”;
for (SeaPort seaPort : ports.values()) {
seaPort.sortByWeight();
result += “Port: “;
result += seaPort.getName() + “n Ships:n “;
for (Ship ship : seaPort.waitingShipsInQue) {
result += ship.getName() + “: ” + ship.weight + “n “;
}
result += “n”;
}
return result;
}
//definition of the method readFile()
public String sortByShipLength() {
String result = “”;
for (SeaPort seaPort : ports.values()) {
seaPort.sortByLength();
result += “Port: “;
result += seaPort.getName() + “n Ships:n “;
for (Ship ship : seaPort.waitingShipsInQue) {
result += ship.getName() + “: ” + ship.length + “n “;
}
result += “n”;
}
return result;
}
//definition of the method readFile()
public String sortByWidth() {
String result = “”;
for (SeaPort seaPort : ports.values()) {
seaPort.sortByWidth();
result += “Port: “;
result += seaPort.getName() + “n Ships:n “;
for (Ship ship : seaPort.waitingShipsInQue) {
result += ship.getName() + “: ” + ship.width + “n “;
}
result += “n”;
}
return result;
}
//definition of the method sortByShipDraft()
public String sortByShipDraft() {
String result = “”;
for (SeaPort seaPort : ports.values()) {
seaPort.sortByDraft();
result += “Port: “;
result += seaPort.getName() + “n Ships:n “;
for (Ship ship : seaPort.waitingShipsInQue) {
result += ship.getName() + “: ” + ship.draft + “n “;
}
result += “n”;
}
return result;
}
//definition of the method getDockByIndex()
private Dock getDockByIndex(int index) {
for (SeaPort port : ports.values())
for (Dock dock : port.docks)
if (dock.getIndex() == index)
return dock;
return null;
}
//definition of the method getShipByIndex()
private Ship getShipByIndex(int index) {
for (SeaPort port : ports.values())
for (Ship ms : port.ships)
if (ms.getIndex() == index)
return ms;
return null;
}
//definition of the method getPersonByIndex()
private Person getPersonByIndex(int index) {
for (SeaPort port : ports.values()) {
for (Person person : port.persons) {
if (person.getIndex() == index)
return person;
}
}
return null;
}
//definition of the method searchIndex()
public String searchIndex(String search) {
int index;
try {
index = Integer.parseInt(search);
} catch (NumberFormatException e) {
return “That is not a number!”;
}
String result = “”;
result += (getDockByIndex(index) != null) ?
getDockByIndex(index).toString() : “”;
result += (getShipByIndex(index) != null) ?
getShipByIndex(index).toString() : “”;
result += (getPersonByIndex(index) != null) ?
getPersonByIndex(index).toString() : “”;
result += (ports.get(index) != null) ?
ports.get(index).toString() : “”;
return result;
}
//definition of the method searchName()
public String searchName(String search) {
String result = “”;
for (SeaPort port : ports.values()) {
for (Dock dock : port.docks) {
if (dock.getName().toLowerCase().matches(search.
toLowerCase()))
result += dock.toString();
}
for (Ship ship : port.ships) {
if (ship.getName().toLowerCase().matches
(search.toLowerCase()))
result += ship.toString();
}
for (Person person : port.persons) {
if (person.getName().toLowerCase().matches
(search.toLowerCase()))
result += person.toString();
}
if (port.getName().toLowerCase().matches
(search.toLowerCase()))
result += port.toString();
}
return result;
}
//definition of the method readFile()
public String searchSkill(String search) {
String result = “”;
for (SeaPort port : ports.values()) {
for (Person person : port.persons) {
if (person.getSkill().toLowerCase().matches
(search.toLowerCase()))
result += person.toString();
}
}
return result;
}
//definition of the method toString()
public String toString() {
String result = “The world: “;
for (SeaPort sp : ports.values())
result += sp.toString();
return result;
}
}
Person.java
import java.util.Scanner;
//define the class Person extends Thing
public class Person extends Thing {
//declare the variables
private String skill;
boolean available = true;
//constructor
public Person(Scanner sc) {
super(sc);
if (sc.hasNext())
skill = sc.next();
}
//getter method
public String getSkill() {
return skill;
}
//definition of the method hirePerson()
// returns Person object
synchronized public Person hirePerson() {
if (available) {
available = false;
return this;
}
return null;
}
//definition of the method release()
synchronized public void release() {
if (!available)
available = true;
}
//definition of the method hasRequiredSkill()
public boolean hasRequiredSkill(String requirement) {
return requirement.toLowerCase().matches(skill.toLowerCase());
}
//definition of the method toString()
public String toString() {
return ” Person: ” + super.toString() + ” ” + skill;
}
}
SeaPort.java
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
//define the class SeaPort extends Thing
public class SeaPort extends Thing {
//declare the variables
ArrayList<Dock> docks = new ArrayList<Dock>();
// the list of ships waiting to dock
ArrayList<Ship> waitingShipsInQue = new ArrayList<Ship>();
// a list of all the ships at this port
ArrayList<Ship> ships = new ArrayList<Ship>();
// persons with skills at this port
ArrayList<Person> persons = new ArrayList<Person>();
ArrayList<Job> rewaitingShipsInQuestList = new ArrayList<Job>();
JPanel panel = new JPanel();
JLabel resourceLabel = new JLabel(“”, SwingConstants.LEFT);
JLabel rewaitingShipsInQuestLabel = new JLabel(“”, SwingConstants.LEFT);
JProgressBar resourceProgress;
//constructor
public SeaPort(Scanner sc) {
super(sc);
}
//definition of the method addDock()
public void addDock(Dock dock) {
docks.add(dock);
}
//definition of the method addShip()
public void addShip(Ship ship) {
ships.add(ship);
}
//definition of the method addShipToQue()
public void addShipToQue(Ship ship) {
waitingShipsInQue.add(ship);
}
//definition of the method addPerson()
public void addPerson(Person person) {
persons.add(person);
}
//definition of the method sortByWeight()
public void sortByWeight() {
Collections.sort(waitingShipsInQue, new Comparator<Ship>() {
@Override
public int compare(Ship s1, Ship s2) {
return (s1.weight < s2.weight ? -1 : (s1.weight == s2.
weight ? 0 : 1));
}
});
}
//definition of the method sortByLength()
public void sortByLength() {
Collections.sort(waitingShipsInQue, new Comparator<Ship>() {
@Override
public int compare(Ship s1, Ship s2) {
return (s1.length < s2.length ? -1 : (s1.length == s2.
length ? 0 : 1));
}
});
}
//definition of the method sortByWidth()
public void sortByWidth() {
Collections.sort(waitingShipsInQue, new Comparator<Ship>() {
@Override
public int compare(Ship s1, Ship s2) {
return (s1.width < s2.width ? -1 : (s1.width == s2.
width ? 0 : 1));
}
});
}
//definition of the method sortByDraft()
public void sortByDraft() {
Collections.sort(waitingShipsInQue, new Comparator<Ship>(){
@Override
public int compare(Ship s1, Ship s2) {
return (s1.draft < s2.draft ? -1 : (s1.draft == s2.
draft ? 0 : 1));
}
});
}
//definition of the method sortAllListsByName()
public void sortAllListsByName() {
Collections.sort(ships);
Collections.sort(docks);
Collections.sort(persons);
Collections.sort(waitingShipsInQue);
for (Ship ship : ships) {
Collections.sort(ship.ships);
}
for (Ship ship : waitingShipsInQue) {
Collections.sort(ship.ships);
}
}
//definition of the method getShipFromQue()
public Ship getShipFromQue() {
synchronized (this) {
if (waitingShipsInQue.size() > 0) {
Ship ship = waitingShipsInQue.get(waitingShipsInQue.
size() – 1);
waitingShipsInQue.remove(ship);
return ship;
}
}
return null;
}
//definition of the method toString()
public String toString() {
String result = “nnSeaPort: ” + super.toString();
for (Dock md : docks)
result += “n” + md.toString();
result += “nn — List of all ships in waitingShipsInQue:”;
for (Ship ms : waitingShipsInQue)
result += “n > ” + ms.toString();
result += “nn — List of all ships:”;
for (Ship ms : ships)
result += “n > ” + ms.toString();
result += “nn — List of all persons:”;
for (Person mp : persons)
result += “n > ” + mp.toString();
return result;
}
//definition of the method checkDocksAtSeaPort()
public synchronized void checkDocksAtSeaPort() {
for (Dock dock : docks) {
dock.checkDocksAtDock();
}
}
//definition of the method requestPersonnel()
public boolean requestPersonnel(ArrayList<String> requirements) {
ArrayList<Person> check = new ArrayList<Person>();
for (String requirement : requirements) {
for (Person person : persons) {
if (person.hasRequiredSkill(requirement) &&
!check.contains(person))
check.add(person);
if (check.size() == requirements.size()) return true;
}
}
return false;
}
//definition of the method requestWorkers()
public ArrayList<Person> requestWorkers(ArrayList<String>
requirements, Job job) {
ArrayList<Person> requiredWorkers = new ArrayList<Person>();
for (String requirement : requirements) {
for (Person person : persons) {
if (person.hasRequiredSkill(requirement))
synchronized (this) {
requiredWorkers.add(person.hirePerson());
}
if (requiredWorkers.size() == requirements.size()) {
broadcastUpdate();
if (rewaitingShipsInQuestList.contains(job))
rewaitingShipsInQuestList.remove(job);
return requiredWorkers;
}
}
}
if (!rewaitingShipsInQuestList.contains(job)) {
rewaitingShipsInQuestList.add(job);
}
if (requiredWorkers.size() > 0)
releaseWorkers(requiredWorkers);
return null;
}
//definition of the method requestWorkers()
public void releaseWorkers(ArrayList<Person> workers) {
for (Person worker : workers) {
if (worker != null)
synchronized (this) {
worker.release();
}
}
broadcastUpdate();
}
//definition of the method broadcastUpdate()
private void broadcastUpdate() {
int availableResources = getAvailableResources();
resourceLabel.setText(“Resources: ” + availableResources);
rewaitingShipsInQuestLabel.setText(“RewaitingShipsInQuests: ”
+ rewaitingShipsInQuestList.size());
if (resourceProgress != null) {
resourceProgress.setValue(availableResources);
if (availableResources < Math.round(persons.size() * 0.2)) {
resourceProgress.setForeground(Color.red);
} else if (availableResources < Math.round(persons.size() * 0.6)) {
resourceProgress.setForeground(Color.yellow);
} else {
resourceProgress.setForeground(Color.blue);
}
}
}
//definition of the method getAvailableResources()
private int getAvailableResources() {
int numOfAvailablePerson = 0;
for (Person person : persons) {
if (person.available)
numOfAvailablePerson++;
}
return numOfAvailablePerson;
}
//definition of the method setElements()
private void setElements() {
panel = new JPanel();
rewaitingShipsInQuestLabel.setMaximumSize(new Dimension(100, 20));
rewaitingShipsInQuestLabel.setMaximumSize(new Dimension(100, 20));
resourceLabel.setMinimumSize(new Dimension(100, 20));
resourceLabel.setMinimumSize(new Dimension(100, 20));
GroupLayout groupLayout = new GroupLayout(panel);
panel.setLayout(groupLayout);
setLayout(groupLayout);
}
//definition of the method setLayout()
private void setLayout(GroupLayout groupLayout) {
groupLayout.setAutoCreateGaps(true);
groupLayout.setAutoCreateContainerGaps(true);
JLabel portLabel = new JLabel(“Port: ” + getName(),
SwingConstants.LEFT);
portLabel.setMaximumSize(new Dimension(120, 20));
portLabel.setMinimumSize(new Dimension(120, 20));
resourceProgress = new JProgressBar(0, persons.size());
broadcastUpdate();
groupLayout.setHorizontalGroup(groupLayout.createSequentialGroup()
.addComponent(portLabel)
.addComponent(resourceProgress)
.addComponent(resourceLabel)
.addComponent(rewaitingShipsInQuestLabel)
);
groupLayout.setVerticalGroup(groupLayout.createParallelGroup
(GroupLayout.Alignment.LEADING)
.addComponent(portLabel)
.addComponent(resourceProgress)
.addComponent(resourceLabel)
.addComponent(rewaitingShipsInQuestLabel)
);
}
//definition of the method setLayout()
public Component getContainerPanel() {
setElements();
return panel;
}
}
Ship.java
import java.util.ArrayList;
import java.util.Scanner;
//define the class Ship that extends the class Thing
public class Ship extends Thing
{
// declare the variables.
private PortTime arrivalTime, dockTime;
double weight, length, width, draft;
ArrayList<Job> ships = new ArrayList<Job>();
private final Object lock = new Object();
private boolean shipInProcess;
// definition of the constructor
// that Scanner object and reads the values of
// weight, length, width and draft of the ship.
public Ship(Scanner key)
{
super(key);
if (key.hasNextDouble())
weight = key.nextDouble();
if (key.hasNextDouble())
length = key.nextDouble();
if (key.hasNextDouble())
width = key.nextDouble();
if (key.hasNextDouble())
draft = key.nextDouble();
dockTime = new PortTime();
}
// definition of the method isShipDocked()
// checks the Seaport and checks the Dock
// returns boolean value if the ship is docked or not.
public boolean isShipDocked()
{
if (thinkObject instanceof SeaPort)
((SeaPort) thinkObject).checkDocksAtSeaPort();
else
((Dock) thinkObject).checkDocksAtDock();
return thinkObject instanceof Dock
&& ((Dock) thinkObject).getShip() == this;
}
// definition of the method processShip()
// checks whether the ship is in process or not
// returns the boolean value.
public boolean processShip()
{
boolean process = false;
synchronized (lock)
{
if (!shipInProcess)
{
shipInProcess = true;
process = true;
}
}
return process;
}
// definition of the method removeShip()
// this method remove the ship from the dock by
// calling the method leaveShipFromDock()
public void removeShip(Job ship)
{
synchronized (lock)
{
shipInProcess = false;
}
if (ships.size() > 0 && ships.contains(ship))
ships.remove(ship);
if (ships.size() == 0)
{
((Dock) thinkObject).leaveShipFromDock();
}
}
// definition of the method requestPersonnel()
boolean requestPersonnel(ArrayList<String> requirements)
{
return ((Dock) thinkObject).requestPersonnel
(requirements);
}
// definition of the method requestPersonnel()
///returns the ArrayList of the Persons
public ArrayList<Person> requestWorkers(ArrayList<String>
requirements,
Job ship)
{
return ((Dock) thinkObject).requestWorkers(requirements,
ship);
}
// definition of the method releaseWorkers()
// takes arrayList of persons and calls the method
//releaseWorkers() from the Dock class
public void releaseWorkers(ArrayList<Person> workers)
{
((Dock) thinkObject).releaseWorkers(workers);
}
// definition of the method toString()
// returns a string of ship details.
public String toString()
{
String returns = (this instanceof PassengerShip ? “Passenger ”
: “Cargo “);
returns += “Ship: ” + super.toString();
if (ships.size() == 0)
return returns;
for (Job job : ships)
returns += “n – ” + job.toString();
return returns;
}
}
CargoShip.java
import java.util.Scanner;
//define the class CargoShip that extends Ship
public class CargoShip extends Ship {
//declare the variables
private double cargoValue;
private double cargoVolume;
private double cargoWeight;
//define the constructor
public CargoShip(Scanner sc) {
super(sc);
if (sc.hasNextDouble())
cargoValue = sc.nextDouble();
if (sc.hasNextDouble())
cargoVolume = sc.nextDouble();
if (sc.hasNextDouble())
cargoWeight = sc.nextDouble();
}
}
PassengerShip.java
import java.util.Scanner;
//define the class PassengerShip that extends Ship
public class PassengerShip extends Ship {
//declare the variables
private int numberOfOccupiedRooms;
private int numberOfPassengers;
private int numberOfRooms;
//define the constructor
public PassengerShip(Scanner sc) {
super(sc);
if (sc.hasNextInt())
numberOfPassengers = sc.nextInt();
if (sc.hasNextInt())
numberOfRooms = sc.nextInt();
if (sc.hasNextInt())
numberOfOccupiedRooms = sc.nextInt();
}
}
PortTime.java
//define the class PortTime
public class PortTime {
//declare the variables
int time;
//define the constructor
public PortTime() {
this.time = 0;
}
//setter method
public void setTime(int time){
this.time = time;
}
}
SeaPortProgram.java
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
//define the class SeaPortProgram
public class SeaPortProgram {
//declare the variables
static World world;
//definition of the main() method
public static void main(String[] args) {
Scanner scan;
world = new World();
try {
scan = new Scanner(new File(simulateFile()));
world.readFile(scan);
scan = null;
System.gc();
JDisplay jDisplay = new JDisplay(world.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//definition of the simulateFile() method
private static String simulateFile() {
String file = null;
JFileChooser jFileChooser = new JFileChooser(“.”);
jFileChooser.setDialogTitle(“Please select a data file”);
jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (jFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
file = jFileChooser.getSelectedFile().toString();
} else {
System.exit(0);
}
return file;
}
@SuppressWarnings(“serial”)
//definition of the class JDisplay extends JFrame
private static class JDisplay extends JFrame {
//declare the variables
String str;
JTextArea text;
JComboBox sortBox;
JComboBox combo;
JTextField textField;
JButton data;
JButton sortByNameButton;
JScrollPane scroll;
JTree jTree;
JScrollPane scrollPane;
public JDisplay(String str) {
this.str = str;
createAndShowGUI();
}
//definition of the addComponents() method
public void addComponents(Container contentPane) {
initComponentsAndSetFeatures();
addActionListeners();
setLayoutForDisplay(contentPane);
}
//definition of the addActionListeners() method
private void addActionListeners() {
sortBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int index = sortBox.getSelectedIndex();
String sorted = sortShipsInQue(index);
if (index != 0 && !sorted.matches(str)) {
text.setText(sorted);
data.setEnabled(true);
}
}
});
combo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textField.setEditable(combo.getSelectedIndex() != 0);
}
});
textField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Remove all redundant spaces
String searchStr = textField.getText().replaceAll(“[\s\t]+$”, “”).
replaceAll(“^[\s\t]+”, “”);
searchStr = searchStr.replaceAll(“(\s+){2,}”, “”);
String result = search(searchStr);
if (result != null && result.length() > 0) {
text.setText(result);
} else {
text.setText(“No result found!”);
}
data.setEnabled(result == null || !str.matches(result));
}
});
data.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
text.setText(str);
data.setEnabled(false);
}
});
sortByNameButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
text.setText(world.sortByShipName());
data.setEnabled(true);
}
});
}
//definition of the search() method
private String search(String stringSearch) {
switch (combo.getSelectedIndex()) {
case 1:
return world.searchIndex(stringSearch);
case 2:
return world.searchName(stringSearch);
case 3:
return world.searchSkill(stringSearch);
default:
return “”;
}
}
//definition of the sortShipsInQue() method
private String sortShipsInQue(int index) {
switch (index) {
case 1:
return world.sortByShipWeight();
case 2:
return world.sortByShipLength();
case 3:
return world.sortByWidth();
case 4:
return world.sortByShipDraft();
default:
return “”;
}
}
//definition of the setLayoutForDisplay() method
private void setLayoutForDisplay(Container contentPane) {
JSplitPane jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
scroll, scrollPane);
JPanel containerForJobs = new JPanel();
JPanel containerForResources = new JPanel();
containerForJobs.setLayout(new BoxLayout(containerForJobs,
BoxLayout.Y_AXIS));
containerForResources.setLayout(new BoxLayout(containerForResources,
BoxLayout.Y_AXIS));
boolean hasJob = false;
boolean hasResource = false;
for (SeaPort seaPort : world.ports.values()) {
containerForResources.add(seaPort.getContainerPanel());
if (!hasResource)
hasResource = seaPort.persons.size() > 0;
for (Ship ship : seaPort.ships) {
for (Job job : ship.ships) {
containerForJobs.add(job.getPanel());
hasJob = true;
}
}
}
JScrollPane sPaneForJobsContainer = new JScrollPane(new JLabel
(“No jobs!”.toUpperCase(), SwingConstants.CENTER));
if (hasJob)
sPaneForJobsContainer = new JScrollPane(containerForJobs);
JScrollPane sPaneForResourcesContainer = new JScrollPane(new JLabel
(“No resources!”.toUpperCase(), SwingConstants.CENTER));
if (hasResource)
sPaneForResourcesContainer = new JScrollPane(containerForResources);
sPaneForJobsContainer.setMaximumSize(new Dimension(5660, 800));
sPaneForResourcesContainer.setMaximumSize(new Dimension(5660, 200));
GroupLayout layout = new GroupLayout(contentPane);
contentPane.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(combo)
.addComponent(textField))
.addComponent(sortBox)
.addComponent(jSplitPane)
.addGroup(layout.createSequentialGroup()
.addComponent(data)
.addComponent(sortByNameButton))
.addComponent(sPaneForResourcesContainer))
.addComponent(sPaneForJobsContainer));
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(combo)
.addComponent(textField))
.addComponent(sortBox)
.addComponent(jSplitPane)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(data)
.addComponent(sortByNameButton))
.addComponent(sPaneForResourcesContainer))
.addComponent(sPaneForJobsContainer));
}
//definition of the initComponentsAndSetFeatures() method
private void initComponentsAndSetFeatures() {
String[] sortOptions = {“Select a feature to sort ships in que”, “weight”,
“length”, “width”, “draft”};
String[] searchOptions = {“Select a feature to search”, “index”,
“name”, “skill”};
text = new JTextArea(str, 20, 60);
sortBox = new JComboBox(sortOptions);
combo = new JComboBox(searchOptions);
textField = new JTextField();
data = new JButton(“Reload Data”);
sortByNameButton = new JButton(“Sort All Things”);
textField.setPreferredSize(new Dimension(120, 25));
textField.setEditable(false);
sortBox.setSelectedIndex(0);
sortBox.setMaximumSize(new Dimension(5660, 25));
combo.setSelectedIndex(0);
text.setFont(new java.awt.Font(“Monospaced”, 0, 12));
text.setEditable(false);
text.setLineWrap(true);
scroll = new JScrollPane(text, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
data.setEnabled(false);
initTree();
}
//definition of the initTree() method
private void initTree() {
DefaultMutableTreeNode top = new DefaultMutableTreeNode(“World”);
createNodes(top);
jTree = new JTree(top);
scrollPane = new JScrollPane(jTree);
}
//definition of the createNodes() method
private void createNodes(DefaultMutableTreeNode top) {
DefaultMutableTreeNode portNode;
for (SeaPort seaPort : world.ports.values()) {
portNode = createThingNode(seaPort);
DefaultMutableTreeNode node = new DefaultMutableTreeNode(“Docks”);
for (Dock dock : seaPort.docks) {
DefaultMutableTreeNode dockNode = createThingNode(dock);
if (dock.getShip() != null) {
DefaultMutableTreeNode shipNode = createThingNode(dock.getShip());
for (Job job : dock.getShip().ships) {
shipNode.add(createThingNode(job));
}
dockNode.add(shipNode);
}
node.add(dockNode);
portNode.add(node);
}
node = new DefaultMutableTreeNode(“Ships in Que”);
for (Ship ship : seaPort.waitingShipsInQue) {
DefaultMutableTreeNode shipNode = createThingNode(ship);
for (Job job : ship.ships) {
shipNode.add(createThingNode(job));
}
node.add(shipNode);
}
portNode.add(node);
node = new DefaultMutableTreeNode(“All Ships”);
for (Ship ship : seaPort.ships) {
DefaultMutableTreeNode shipNode = createThingNode(ship);
for (Job job : ship.ships) {
shipNode.add(createThingNode(job));
}
node.add(shipNode);
}
portNode.add(node);
node = new DefaultMutableTreeNode(“People”);
for (Person person : seaPort.persons) {
DefaultMutableTreeNode personNode = createThingNode(person);
node.add(personNode);
}
portNode.add(node);
top.add(portNode);
}
}
//definition of the createThingNode() method
private DefaultMutableTreeNode createThingNode(Thing thing) {
return new DefaultMutableTreeNode(thing.getIndex() + ” ” + thing.getName());
}
//definition of the createAndShowGUI() method
private void createAndShowGUI() {
JFrame frame = new JFrame(“Sea Port Simulation”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane and add swing components to it
addComponents(frame.getContentPane());
frame.setPreferredSize(new Dimension(1300, 800));
frame.pack();
frame.setVisible(true);
World.setValue(); // world is set!
}
}
}