SimulationView
La SimulationView
è l'interfaccia grafica (GUI) della simulazione, implementata in Java Swing. Le sue
responsabilità principali sono il rendering dello stato dell'ambiente, la gestione dell'interazione utente
tramite controlli di esecuzione e la visualizzazione di dati specifici, come lo stato di un robot e il tempo di simulazione.
L'implementazione di riferimento si trova in GUIComponent.scala
.
Architettura e design pattern
Componenti
L'interfaccia è strutturata tramite la composizione di pannelli, ognuno dedicato a una funzione specifica.
- Layout Principale: un
JFrame
contiene unJSplitPane
che separa ilSimulationCanvas
(a sinistra) dai pannelli informativi e di controllo (a destra); - Pannelli Funzionali:
SimulationCanvas
: si occupa del rendering dell'ambiente;RobotPanel
: mostra la lista dei robot, gestisce la selezione e la visualizzazione dei dati del robot selezionato;TimePanel
: mostra il tempo di simulazione;ControlsPanel
: raggruppa i controlli di interazione (start/stop, pausa, velocità).
Stato centralizzato
Per evitare l’accoppiamento diretto tra i pannelli e garantire coerenza dei dati, la vista adotta un stato
centralizzato.
Un singolo oggetto SimulationViewState
, gestito in modo thread-safe tramite un AtomicReference
, contiene i dati
necessari alla UI.
// Lo stato centralizzato contiene tutti i dati necessari per il rendering
final case class SimulationViewState
(
environment: Option[Environment] = None,
selectedRobotId: Option[String] = None,
robots: List[Robot] = Nil,
staticLayer: Option[BufferedImage] = None,
// ... altri campi per la gestione della cache
)
Nota: il flusso è unidirezionale: il controller aggiorna lo stato via
render
, i componenti leggono e si aggiornano.
Ciclo di vita e rendering
init(queue)
: costruisce la UI, registra gli handler e mostra la finestra.render(state)
: a ogni tick aggiornaSimulationViewState
e programma il ridisegno sull’EDT.timeElapsed(state)
: disabilita i controlli al termine della simulazione.close()
: rilascia le risorse della finestra Swing.
Ottimizzazione del rendering
Per garantire fluidità, SimulationCanvas
usa una cache (BufferedImage
). Gli elementi statici (griglia, ostacoli,
luci) sono disegnati una sola volta; ad ogni tick si ridisegnano solo quelli dinamici (robot e sensori). La cache si
rigenera solo quando cambiano dimensioni del canvas o dell’ambiente.
Interazione e flusso degli eventi
Controlli di esecuzione
- Start/Stop: invia
Event.Resume
/Event.Stop
. Per prevenire interruzioni accidentali, Stop prima mette in pausa (Event.Pause
) e chiede conferma tramite un modale. - Pausa/Riprendi: invia
Event.Pause
oEvent.Resume
. - Velocità: i radio button inviano
Event.TickSpeed
con la velocità selezionata.
Selezione del robot e visualizzazione dati
Un robot può essere selezionato sia dalla lista nel RobotPanel
sia cliccando direttamente sulla sua rappresentazione
nel SimulationCanvas
. Una volta selezionato, il RobotPanel
mostra le sue informazioni dettagliate, comprese le
letture dei sensori in tempo reale, ottenute tramite la funzione robot.senseAll(environment)
.
Dettagli grafici
- Entità: gradienti e ombre per migliorare leggibilità.
- Selezione: il robot selezionato è evidenziato con bordo e colore distintivi.
- Sensori: i raggi di prossimità sono linee con lunghezza proporzionale alla distanza misurata.
Per un'overview delle funzionalità offerte dall'interfaccia grafica, si rimanda alla sezione Simulation GUI della User Guide.