Treść zadania:
Firma transportowa posiada flotę pojazdów. Jej zadaniem jest przewiezienie towaru od dostawcy do odbiorcy. Każdy pojazd wchodzący w skład floty pojazdów powinien przewozić towary z miejsc zgłaszających potrzebę przewiezienia towaru do miejsca docelowego. Pomiędzy miejscami powinien zostać przypisany dystans wygenerowany losowo. Pojazd posiada zbiornik (wygenerowany losowa z zadanego zakresu) wskazujący jaki dystans może przejechać. W odpowiednim momencie pojazd powinien podjeżdżać na stację benzynową w celu zatankowania. Tankowanie powinno odbywać się sekwencyjnie. Stacje powinny zostać rozmieszczone w zbiorze miejsc i dojazd do nich również powinien zostać zdefiniowany odpowiednimi dystansami. Liczba odbiorców, dostawców i samochodów jest podawana na starcie programu. Program powinien
działać nieprzerwanie do momentu zamknięcia przez użytkownika. Wszystkie zdarzenia dobywające się w czasie działania programu powinny być wyświetlane na konsoli systemowej w sposób umożliwiający analizę poprawności działania programu.
Moja wersja jest nieco uproszczona. Założyłem, że odbiorca-nadawca to po prostu jeden transport. A samochody tankują do pełna na każdej napotkanej stacji
. Aplikacja działa w pętli (ciągle rozwożone są te same transporty w kółko), ponieważ takie jest założenie w zadaniu. Jeśli pojazd jest -Dead- to po prostu skończyło się paliwo i nie zostanie dostarczony już żaden transport.
Uruchamiamy Window, bo tylko tam jest main. Główne parametry można ustawiać właśnie w tej metodzie (tj main), a resztę w poszczególnych klasach (zmienne na początku klas).
UWAGA - cenzura forum zadziałała i w kodzie nie widać Re*****nt (czyli Reci-pient bez myślnika
).
Kody (cały projekt w załączniku):
FuelLevel
Kod:
package edu;
/**
* @author Dawid Samołyk
*
*/
public class FuelLevel {
private Integer level = 0;
private Integer maxFuelLevel = 0;
public FuelLevel(Integer level, Integer maxFuelLevel) {
this.level = level;
this.maxFuelLevel = maxFuelLevel;
}
public Integer get() {
return level;
}
public void fillToMaxLevel() {
level = maxFuelLevel;
}
public boolean isEmpty() {
return (level == 0);
}
}
GasStation
Kod:
package edu;
/**
* @author Dawid Samołyk
*
*/
public class GasStation {
private Integer distanceToEndPoint;
public GasStation(Integer distanceToEndPoint) {
this.distanceToEndPoint = distanceToEndPoint;
}
public Integer getDistanceToEndPoint() {
return distanceToEndPoint;
}
}
Transport
Kod:
package edu;
import java.util.Random;
/**
* @author Dawid Samołyk
*
*/
public class Transport {
private final int maxGasStationsQuanity = 5;
private GasStation[] gasStations;
private String supplier, re*****nt;
private Integer distance;
public Transport(String supplier, String re*****nt, Integer distance) {
this.supplier = supplier;
this.re*****nt = re*****nt;
this.distance = distance;
initializeGasStations();
}
private void initializeGasStations() {
Random rand = new Random();
Integer quanity = rand.nextInt(maxGasStationsQuanity);
gasStations = new GasStation[quanity];
Integer distanceToEndPoint;
for(int i = 0 ; i < gasStations.length ; i++) {
distanceToEndPoint = rand.nextInt(distance)+1;
gasStations[i] = new GasStation(distanceToEndPoint);
}
}
public boolean isVehicleCanFillFuelOnGasStation(Integer distanceToEndPoint) {
for(int i = 0 ; i < gasStations.length ; i++) {
if(distanceToEndPoint == gasStations[i].getDistanceToEndPoint()) {
return true;
}
}
return false;
}
public Integer getDistanceToEndPoint() {
return distance;
}
public String deliveredNotice() {
return "Transport (distance " + distance+ ") delivered from " + supplier.toString() + " to " + re*****nt.toString() + "!";
}
@Override
public String toString() {
return "TRANSPORT: from " + supplier + " to " + re*****nt + ", distance : " + distance;
}
}
TransportCompany
Kod:
package edu;
import java.util.Random;
/**
* @author Dawid Samołyk
*
*/
public class TransportCompany {
public final int maxFuel = 100, maxDistance = 110;
private String name;
private TransportDispatcher dispatcher;
private Vehicle[] vehicles;
private Transport[] transports;
public TransportCompany(String name, Integer vehiclesQuanity, Integer transportsQuanity) {
this.name = name;
this.vehicles = new Vehicle[vehiclesQuanity];
this.transports = new Transport[transportsQuanity];
initializeVehicles();
initializeTransports();
this.dispatcher = new TransportDispatcher(this.vehicles, this.transports);
}
public Vehicle[] getVehicles() {
return vehicles;
}
private void initializeVehicles() {
Random rand = new Random();
Integer fuelLevel;
FuelLevel fuel;
String vehicleName;
for(int i = 0 ; i < vehicles.length ; i++) {
fuelLevel = rand.nextInt(maxFuel - 40) + 41;
fuel = new FuelLevel(fuelLevel, maxFuel);
vehicleName = "Vehicle " + i;
vehicles[i] = new Vehicle(vehicleName, fuel);
}
}
private void initializeTransports() {
Random rand = new Random();
Integer distance;
String supplierName, re*****ntName;
for(int i = 0 ; i < transports.length ; i++) {
distance = rand.nextInt(maxDistance) + 1;
supplierName = "Supplier " + i;
re*****ntName = "Re*****nt " + i;
transports[i] = new Transport(supplierName, re*****ntName, distance);
}
}
public void startTransportDispatcher() {
this.dispatcher.start();
}
@Override
public String toString() {
return "TRANSPORT COMPANY: " + name;
}
}
TransportDispatcher
Kod:
package edu;
/**
* @author Dawid Samołyk
*
*/
public class TransportDispatcher extends Thread {
private Vehicle[] vehicles;
private Transport[] transports;
public TransportDispatcher(Vehicle[] vehicles, Transport[] transports) {
this.vehicles = vehicles;
this.transports = transports;
}
@Override
public void run() {
dispatch();
for(int i = 0 ; i < vehicles.length ; i++) {
vehicles[i].start();
}
}
private void dispatch() {
Transport transport = null;
Vehicle vehicle = null;
int transportNumber = 0;
int vehicleNumber = 0;
while(transportNumber < transports.length) {
if(vehicleNumber >= vehicles.length) {
vehicleNumber = 0;
}
transport = transports[transportNumber];
vehicle = vehicles[vehicleNumber];
vehicle.addTransport(transport);
transportNumber++;
vehicleNumber++;
}
}
}
Vehicle
Kod:
package edu;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JSlider;
/**
* @author Dawid Samołyk
*
*/
public class Vehicle extends Thread {
private FuelLevel fuelLevel;
private volatile Integer fuel;
private List<Transport> orders = new ArrayList<Transport>();
private JSlider slider;
private JLabel status;
public Vehicle(String name, FuelLevel fuelLevel) {
super(name);
this.fuelLevel = fuelLevel;
}
public void addTransport(Transport transport) {
orders.add(transport);
}
public void setSlider(JSlider slider) {
this.slider = slider;
}
public void setStatus(JLabel status) {
this.status = status;
}
private void deliver(Transport transport) {
Integer distanceToEndPoint = transport.getDistanceToEndPoint();
fuel = fuelLevel.get();
if(slider != null) {
slider.setMaximum(distanceToEndPoint);
slider.setMinimum(0);
}
while(distanceToEndPoint > 0) {
if(fuel == 0) {
orders = null;
return;
}
if(transport.isVehicleCanFillFuelOnGasStation(distanceToEndPoint)) {
fuelLevel.fillToMaxLevel();
fuel = fuelLevel.get();
status.setText("-Filling fuel-");
status.setForeground(Color.BLUE);
fillFuel();
}
slider.setValue(distanceToEndPoint);
status.setText("-Driving-");
status.setForeground(Color.DARK_GRAY);
drive();
distanceToEndPoint--;
fuel--;
}
}
@Override
public void run() {
synchronized(this) {
try {
this.wait();
} catch (InterruptedException e) {
System.err.println(e);
}
}
while(true) {
for(Transport transport : orders) {
if(orders == null) {
status.setText("-Dead-");
status.setForeground(Color.RED);
report();
return;
}
deliver(transport);
}
if(orders != null) {
if(orders.isEmpty() == true) {
slider.setValue(0);
status.setText("-No work-");
status.setForeground(Color.GREEN);
return;
}
slider.setValue(0);
status.setText("-All delivered-");
status.setForeground(Color.GREEN);
report();
} else {
status.setText("-Dead-");
status.setForeground(Color.RED);
report();
return;
}
}
}
@Override
public String toString() {
return "VEHICLE: " + getName() + " (fuel level : " + fuelLevel.get() + ")";
}
private void sleepFor(long milis) {
try {
Thread.sleep(milis);
} catch (InterruptedException e) {
System.out.println(e);
}
}
private void drive() {
sleepFor(100);
}
private void fillFuel() {
sleepFor(800);
}
private void report() {
sleepFor(2000);
}
}
VehicleStatusPanel
Kod:
package edu.GUI;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JSlider;
import edu.Vehicle;
import java.awt.Dimension;
@SuppressWarnings("serial")
public class VehicleStatusPanel extends JPanel {
public VehicleStatusPanel(Vehicle vehicle) {
setDetails(this);
JLabel vehicleName = new JLabel(vehicle.getName());
add(vehicleName);
JLabel status = new JLabel("Unknown status");
add(status);
JSlider route = new JSlider();
route.setEnabled(false);
add(route);
vehicle.setStatus(status);
vehicle.setSlider(route);
}
public static JPanel getDescription() {
JPanel panel = new JPanel();
setDetails(panel);
JLabel vehicle = new JLabel("Vehicle name");
vehicle.setForeground(Color.GRAY);
panel.add(vehicle);
JLabel status = new JLabel("Status");
status.setForeground(Color.GRAY);
panel.add(status);
JLabel route = new JLabel("Route");
route.setForeground(Color.GRAY);
panel.add(route);
return panel;
}
private static void setDetails(JPanel panel) {
panel.setSize(new Dimension(400, 30));
panel.setPreferredSize(new Dimension(400, 30));
panel.setMaximumSize(new Dimension(400, 30));
panel.setMinimumSize(new Dimension(400, 30));
panel.setLayout(new GridLayout(1, 3));
panel.setEnabled(true);
}
}
Window
Kod:
package edu.GUI;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import edu.TransportCompany;
import edu.Vehicle;
import java.awt.GridLayout;
public class Window {
private JFrame frame;
private JPanel panel;
public static void main(String[] args) {
final String companyName = "DPD";
final Integer vehiclesQuanity = 30;
final Integer transportsQuanity = 70;
final TransportCompany company = new TransportCompany(companyName, vehiclesQuanity, transportsQuanity);
company.startTransportDispatcher();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window window = new Window(company, vehiclesQuanity);
window.frame.setVisible(true);
} catch (Exception e) {
System.err.println(e);
}
}
});
}
public Window(TransportCompany company, Integer vehiclesQuanity) {
initialize(vehiclesQuanity, company);
Vehicle[] vehicles = company.getVehicles();
addVehiclesStatusPanels(vehicles);
notifyVehiclesToDoWork(vehicles);
}
private void addVehiclesStatusPanels(Vehicle[] vehicles) {
for(Vehicle vehicle : vehicles) {
panel.add(new VehicleStatusPanel(vehicle));
}
}
private void notifyVehiclesToDoWork(Vehicle[] vehicles) {
for(Vehicle vehicle : vehicles) {
synchronized(vehicle) {
vehicle.notify();
}
}
}
private void initialize(Integer vehiclesQuanity, TransportCompany company) {
frame = new JFrame();
frame.setTitle(company.toString());
frame.setBounds(100, 100, 450, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.add(VehicleStatusPanel.getDescription());
if(vehiclesQuanity != null) {
panel.setLayout(new GridLayout(vehiclesQuanity + 1, 1));
} else {
System.exit(1);
}
JScrollPane scrollPane = new JScrollPane(panel);
frame.add(scrollPane);
}
}