ePJ2 is an electric vehicle rental simulation system for the fictional city of JavaCity.
It manages a fleet of cars, bikes, and scooters across a real-time 20×20 city grid, calculates rental fares, tracks malfunctions, and produces financial reports — all through a dark tactical HUD-style GUI built with Java Swing.
The dashboard on startup, before a simulation is launched.
Vehicles moving across the city grid in real time. Green = Scooter, Red = Car, Yellow = Bike.
The SIM LOG panel on the right streams dispatch events live.
Sales, Salary, and Repair monitors filled with results after the simulation completes.
Recommended environment: Eclipse IDE for Java Developers
- Open Eclipse.
- Go to File → Import → Existing Projects into Workspace.
- Select the root folder of the repository and click Finish.
Place the following files directly in the project root (same level as src/):
PJ2 - projektni zadatak 2024 - Prevozna sredstva.csv ← vehicle data
PJ2 - projektni zadatak 2024 - Iznajmljivanja.csv ← rental data
- In the Package Explorer, expand
src → gui. - Right-click
MainWindow.java. - Select Run As → Java Application.
- The dashboard window will open.
Click the ▶ START SIMULATION button in the bottom-right corner of the dashboard.
The simulation will:
- Load all vehicles and rentals from the CSV files.
- Dispatch each vehicle as a separate thread.
- Animate vehicle movement live on the city map.
- Stream log events to the SIM LOG panel.
- Fill the SALES, SALARY, and REPAIRS monitors when done.
- Open a popup showing the most loss-making vehicle type.
The system tracks three types of electric vehicles:
| Type | Battery | Map Colour |
|---|---|---|
| Car | 300 units | 🔴 Red |
| Bike | 200 units | 🟡 Yellow |
| Scooter | 100 units | 🟢 Green |
Each vehicle is a Java thread — it moves step-by-step across the 20×20 grid, drains its battery per step, and generates a Bill for its passenger on arrival.
- Three vehicle subclasses:
Car,Bike,Scooter(extend abstractVehicle extends Thread). VehicleTypeenum replaces all raw type strings ("automobil","bicikl","trotinet").- Each vehicle exposes a
getMapColor()method — the map panel uses polymorphism to colour cells with zeroinstanceofchecks. - Battery charges and discharges per movement step; two bugs in the original
Batteryclass were fixed during refactoring.
- Rentals are loaded from a CSV file, validated, deduplicated, and sorted chronologically.
- Fare calculation accounts for: base unit price per vehicle type, wide/narrow city zone multiplier, every-10th-rental promotional discount, and malfunction waiver.
- Passengers are randomly assigned as
Local(national ID) orStranger(passport). - A
Billis generated and attached to each passenger at trip end.
- Each vehicle runs on its own
Thread. - The city grid is a
20×20array ofObjectcells protected by per-cellReentrantLocks. - The map repaints at ~30 fps via a Swing
Timer. - Vehicle movement is logged live in the SIM LOG panel.
Three monitors update automatically after the simulation ends:
| Monitor | Tracks |
|---|---|
| SALES | Number of rentals per vehicle type |
| SALARY | Total revenue, discount revenue, promotion revenue |
| REPAIRS | Repair costs per vehicle type (7% / 4% / 2% of purchase price) |
The most loss-making vehicle type is serialized to Reports/MostLossMakingVehicles.ser and deserialized into a popup window.
The interface follows a dark tactical HUD aesthetic — think mission control for a smart city.
| Element | Description |
|---|---|
| Title bar | App name in electric cyan + live HH:mm:ss clock |
| SALES / SALARY / REPAIRS panels | Left column, stacked flush, each with a titled header strip |
| CITY MAP | Centre panel — dark grid, glowing vehicle cells, dashed zone boundary |
| SIM LOG | Right panel — live scrolling dispatch log |
| Bottom bar | Vehicle legend, status text, glowing START button |
All design tokens (colours, fonts) live in AppTheme.java. Changing one value propagates everywhere.
ePJ2/
│
├── src/
│ ├── battery/ Battery, BatteryException
│ ├── bill/ Bill
│ ├── data/ VehicleDataLoader, RentalDataLoader
│ ├── gui/ MainWindow, MapPanel, AppTheme, GlowButton,
│ │ LossMakingVehiclesWindow
│ ├── javacitymap/ JavaCityMap, JavaCityMapException
│ ├── malfunction/ Malfunction
│ ├── model/ Vehicle (abstract), Car, Bike, Scooter, VehicleType
│ ├── monitor/ RentalSalesMonitor, RentalSalaryMonitor,
│ │ RentalRepairCostsMonitor
│ ├── passenger/ Passenger (abstract), Local, Stranger
│ ├── rental/ Rental
│ └── utility/ ConfigFileCreator, ConfigFileReader,
│ Serializer, Deserializer, RandomStringGenerator
│
├── Reports/ Serialized binary output (auto-created at runtime)
├── config.properties Auto-generated pricing config
├── PJ2 - projektni zadatak 2024 - Prevozna sredstva.csv
├── PJ2 - projektni zadatak 2024 - Iznajmljivanja.csv
└── README.md
This project was significantly refactored from the original submission. Notable improvements:
VehicleTypeenum — eliminates all raw Bosnian string literals scattered across six files.- Bug fix:
Battery.charge()— original code always added 100 instead of theamountargument. - Bug fix:
Battery.setChargeLevel()— original guard condition0 < status && status >= 100was logically impossible (nothing could satisfy it). - Thread-safe monitors —
AtomicLong/DoubleAdderreplace plainstatic doublefields. getMapColor()polymorphism —MapPanelhas noinstanceofchain; each vehicle subclass declares its own colour.- Billing extracted — fare calculation moved out of
Vehicle.run()into a dedicatedgenerateBill()method. - Deleted dead code —
proba/package (commented-out scratch tests) and duplicateuser/package removed entirely. - All identifiers translated to English — no Bosnian/Serbian variable or method names remain in the codebase.
config.properties is auto-created on first run by ConfigFileCreator. Default values:
CAR_UNIT_PRICE = 0.05
BIKE_UNIT_PRICE = 0.02
SCOOTER_UNIT_PRICE = 0.01
DISTANCE_WIDE = 1.5
DISTANCE_NARROW = 1.0
DISCOUNT = 0.1
DISCOUNT_PROM = 0.05- Full JavaDoc on all public classes and methods.
- Packages for every logical layer.
- Single Responsibility — data loading, simulation, billing, and monitoring are separate concerns.
ReentrantLockper grid cell for fine-grained thread safety.Collections.synchronizedListfor shared vehicle lists in monitors.
Developed as part of the Programski jezici 2 course at
Elektrotehnički fakultet, Banja Luka.
- Andrej Trožić — Student, Elektrotehnički fakultet Banja Luka


