La multimedialità: le immagini, le animazioni e i suoni



Documenti analoghi
LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 1

Grafico della parabola

L applicazione di MVC alla simulazione di ascensore I COMPONENTI DELLE INTERFACCE UTENTE GRAFICHE: PARTE II 1

I Canvas. import java.awt.*; import javax.swing.*; public class Graf{ public Graf () { JFrame f = new JFrame("Finestra"); // crea frame invisibile

lo PERSONALIZZARE LA FINESTRA DI WORD 2000

Java Applet. Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

L interfaccia grafica in Java

Come costruire una presentazione. PowerPoint 1. ! PowerPoint permette la realizzazione di presentazioni video ipertestuali, animate e multimediali

Il calendario di Windows Vista

Progettazione : Design Pattern Creazionali

Sistema operativo. Sommario. Sistema operativo...1 Browser...1. Convenzioni adottate

Cosa è un foglio elettronico

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

Esercitazione n 4. Obiettivi

Uso di JUnit. Fondamenti di informatica Oggetti e Java. JUnit. Luca Cabibbo. ottobre 2012

Manuale Utente Amministrazione Trasparente GA

Prova di Laboratorio di Programmazione

Le basi della grafica in Java. Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni

Capitolo 3. L applicazione Java Diagrammi ER. 3.1 La finestra iniziale, il menu e la barra pulsanti

Il controllo della visualizzazione

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito)

Presentation Draw. Guida dell utilizzatore

COGNOME.NOME. Matricola

Guida all uso di Java Diagrammi ER

Corso sul linguaggio Java

IL MIO PRIMO SITO NEWS USANDO GLI SCHEDARI

Identificare le classi in un sistema

La specifica del problema

Manuale Utente Albo Pretorio GA

Novità di Access 2010

Esercizi di JavaScript

Funzioni in C. Violetta Lonati

Registratori di Cassa

Simulazione traffico urbano

per immagini guida avanzata Uso delle tabelle e dei grafici Pivot Geometra Luigi Amato Guida Avanzata per immagini excel

Modulo 4: Ereditarietà, interfacce e clonazione

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi

Gestione delle informazioni necessarie all attività di validazione degli studi di settore. Trasmissione degli esempi da valutare.

Oggetti Lezione 3. aspetti generali e definizione di classi I

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Java: Interfacce grafiche (GUI)

Informatica 1 Lezione 1

GUIDA ALLA PROGRAMMAZIONE GRAFICA IN C

Microsoft Office XP. dott. ing. Angelo Carpenzano. La suite Microsoft Office XP

SmartGPS Satellite Information System Guida all utilizzo del programma Sviluppato da Fabio e Marco Adriani Versione 1.0.0

Identificare le diverse parti di una finestra: barra del titolo, barra dei menu, barra degli strumenti, barra di stato, barra di scorrimento.

Figura 1 Le Icone dei file di Excel con e senza macro.

Introduzione alla programmazione in C

Soluzione dell esercizio del 2 Febbraio 2004

WoWords. Guida all uso: creare ed utilizzare le frasi. In questa guida è descritto come creare ed utilizzare le frasi nel software WoWords.

PULSANTI E PAGINE Sommario PULSANTI E PAGINE...1

1. Il Client Skype for Business

Banca dati Professioniste in rete per le P.A. Guida all uso per le Professioniste

Plate Locator Riconoscimento Automatico di Targhe

Esercitazioni di Progettazione del Software. Esercitazione (Prova al calcolatore del 17 settembre 2010)

Joomla: Come installarlo e come usarlo. A cura di

ISTRUZIONI XCODE. Autore: Luca Florio (luca.florio<at>polimi.it)

SPSS Statistics per Windows - Istruzioni di installazione per (Licenza per utenti singoli)

Linee Guida all uso dell ESLC Testing Tool per gli studenti (IT)

Gui Gu d i a d ra r p a i p d i a V d o a d f a one Int fone In e t r e net rnet Box Key Mini

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (utente singolo)

Guida. Macchina Scratch

MANUALE PORTALE UTENTE IMPRENDITORE

IRSplit. Istruzioni d uso 07/10-01 PC

MANUALE D USO DELL E-COMMERCE. Versione avanzata

CREARE UN JUKEBOX CON POWERPOINT

Configurare TPTP in Eclipse e testare un applicazione

Università di L Aquila Facoltà di Biotecnologie Agro-alimentari

11/02/2015 MANUALE DI INSTALLAZIONE DELL APPLICAZIONE DESKTOP TELEMATICO VERSIONE 1.0

EXCEL PER WINDOWS95. sfruttare le potenzialità di calcolo dei personal computer. Essi si basano su un area di lavoro, detta foglio di lavoro,

Manuale NetSupport v Liceo G. Cotta Marco Bolzon

LITESTAR 4D v Manuale d Uso. WebCatalog Catalogo Elettronico interattivo su Internet. Luglio 2013

Il web server Apache Lezione n. 3. Introduzione

15 - Packages. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Installazione e caratteristiche generali 1

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Cominciamo dalla barra multifunzione, ossia la struttura a schede che ha sostituito la barra dei menu e la barra delle icone (Figura 1).

Modulo 6 Strumenti di presentazione

Guida Joomla. di: Alessandro Rossi, Flavio Copes

PowerPoint 2007 Le funzioni

START Easy GO! Il gestionale sempre in tasca! Procedura di aggiornamento. Documentazione utente Pagina 1 di 18

IL MIO PRIMO SITO: NEWS

STRUMENTI DI PRESENTAZIONE MODULO 6

SOMMARIO... 3 INTRODUZIONE...

7.4 Estrazione di materiale dal web

MANUALE EDICOLA 04.05

Modello per la compilazione della scheda progetto SK_3.1.xls (da utilizzarsi per la presentazione di progetti di attività formative)

Avvio di Internet ed esplorazione di pagine Web.

Programmazione a Oggetti Modulo B

Istruzioni per l installazione del software per gli esami ICoNExam (Aggiornate al 15/01/2014)

Lettore di badge Nexus

GESTIONE DEI PROCESSI

Client - Server. Client Web: il BROWSER

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

2.0 Gli archivi. 2.1 Inserire gli archivi. 2.2 Archivio Clienti, Fornitori, Materiali, Noleggi ed Altri Costi. Impresa Edile Guida all uso

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni

1. Le macro in Access 2000/2003

Guida alla registrazione on-line di un DataLogger

Transcript:

CAPITOLO 8 La multimedialità: le immagini, le animazioni e i suoni Obiettivi Imparare a visualizzare le immagini Creare animazioni da sequenze di immagini Creare mappe di immagini Imparare a riprodurre, fermare e riprodurre continuamente suoni usando un oggetto AudioClip 8.1 Introduzione Con l evoluzione dell informatica, i computer hanno smesso di essere degli strumenti utili soltanto a eseguire velocemente calcoli matematici, e sono diventati strumenti per la manipolazione dei dati e delle informazioni. Una delle caratteristiche più interessanti di Java è sicuramente la multimedialità, ovvero la capacità di usare suoni, immagini, grafica e video nelle applicazioni. La programmazione multimediale offre molte sfide nuove. I nuovi computer vengono ormai venduti già provvisti di unità CD-ROM o DVD, schede audio e speciali funzionalità video. Sempre più utenti, poi, vogliono avere la possibilità di realizzare grafica tridimensionale e ad alta risoluzione. Nei prossimi dieci anni, lo sviluppo nella grafica tridimensionale renderà possibili nuove applicazioni: immaginate di avere una televisione tridimensionale nella vostra casa, in cui seguire gli eventi sportivi e gli spettacoli come se avvenissero nel vostro salotto! Gli studenti di medicina potranno vedere operazioni che si stanno svolgendo a migliaia di chilometri di distanza come se avvenissero nella stessa stanza. Le persone potranno imparare a guidare usando simulatori di automobile estremamente realistici prima ancora di salire in auto. Le possibilità sono eccitanti e potenzialmente senza fine. La multimedialità richiede ai computer un enorme quantità di potenza. Fino a poco tempo fa, non erano disponibili dei computer economici con la potenza necessaria. I processori veloci ora disponibili, come SPARC Ultra di Sun Microsystems, Pentium e Itanium di Intel, Alpha di Hewlett-Packard, e i processori di MIPS/Silicon Graphics (per citarne alcuni) rendono possibile la multimedialità. A trarre beneficio da questa rivoluzione multimediale saranno principalmente l industria informatica e il mondo delle comunicazioni, in quanto gli utenti saranno disposti ad acquistare processori più veloci, memorie e ampiezze di banda più grandi per le comunicazioni, tutte cose necessarie per poter supportare le applicazioni

438 CAPITOLO 8 multimediali. Paradossalmente, poi, il costo di tutto ciò non sarà eccessivamente elevato, in quanto la competizione sarà altissima e, quindi, i prezzi tenderanno a scendere sempre più. Per creare applicazioni multimediali efficaci, però, sono necessari linguaggi di programmazione che facilitino la creazione di contenuti multimediali. La maggior parte dei linguaggi attualmente esistenti, infatti, non possiede capacità multimediali di tipo nativo. Al contrario di questi linguaggi, Java offre funzionalità multimediali complete, che permettono ai programmatori di sviluppare da subito applicazioni multimediali estremamente interessanti e potenti. In questo capitolo, verranno presentati vari esempi delle funzionalità multimediali più importanti per la realizzazione di applicazioni efficaci, tra cui: come manipolare le immagini come creare animazioni fluide come riprodurre suoni con l interfaccia AudioClip come creare mappe di immagini in grado di sentire quando il puntatore del mouse si trova sopra di loro, anche senza un clic da parte dell utente. Gli esercizi alla fine del capitolo proporranno decine di progetti interessanti, che scateneranno la vostra creatività. 8.2 Caricare, visualizzare e scalare immagini Le capacità multimediali di Java consentono di gestire grafica, immagini, suoni e video. Iniziamo la nostra trattazione con le immagini. L applet della figura 8.1 mostra il caricamento di un oggetto Image (package java.awt) e di un oggetto ImageIcon (package javax.swing). L applet visualizza l oggetto Image nella sua dimensione originale e poi ingrandita, usando due versioni del metodo drawimage della classe Graphics. L applet disegna inoltre l oggetto ImageIcon usando il suo metodo painticon. La classe ImageIcon è più semplice da usare della classe Image, perché il suo costruttore può ricevere argomenti di formati diversi, tra cui un array di byte contente i byte dell immagine, un oggetto Image già caricato in memoria e una stringa o un URL che rappresenta la posizione dell immagine. 1 // Fig. 8.1: LoadImageAndScale.java 2 // Carica un immagine e la visualizza nella sua dimensione originale e 3 // raddoppiata. Carica e visualizza la stessa immagine come un ImageIcon 4 import java.applet.applet; 5 import java.awt.*; 6 import javax.swing.*; 7 8 public class LoadImageAndScale extends JApplet { 9 private Image logo1; 10 private ImageIcon logo2; 11 12 // carica immagine quando l applet viene caricata 13 public void init() Figura 8.1 Caricare e visualizzare un immagine in un applet (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 439 14 { 15 logo1 = getimage( getdocumentbase(), logo.gif ); 16 logo2 = new ImageIcon( logo.gif ); 17 } 18 19 // visualizza immagine 20 public void paint( Graphics g ) 21 { 22 g.drawimage( logo1, 0, 0, this ); // disegna immagine originale 23 24 // disegna immagine che riempie larghezza e altezza meno 120 pixel 25 g.drawimage( logo1, 0, 120, getwidth(), getheight() 120, this ); 26 27 // disegna icona usando il suo metodo painticon 28 logo2.painticon( this, g, 180, 0 ); 29 } 30 31 } // fine classe LoadImageAndScale Figura 8.1 Caricare e visualizzare un immagine in un applet Le righe 9 e 10 dichiarano rispettivamente un riferimento Image e un riferimento ImageIcon. La classe Image è una classe abstract; quindi, non è possibile creare direttamente un oggetto della classe Image. È necessario invece che l applet chiami un metodo che fa in modo che il contenitore dell applet carichi e ritorni l oggetto Image da usare nel programma. La classe Applet (la superclasse di JApplet) fornisce il metodo getimage (riga 15 del metodo init) per caricare un Image nell applet. Questa versione di getimage prende due argomenti: la posizione e il nome del file dell immagine. Nel primo argomento, il metodo getdocumentbase della classe Applet viene utilizzato per ritornare un URL che rappresenta la posizione dell immagine in Internet (o sul computer, se è da qui che proviene l applet). In questo caso, si parte

440 CAPITOLO 8 dal presupposto che l immagine da caricare si trovi nella stessa directory del file HTML che ha invocato l applet. Il metodo getdocumentbase ritorna la posizione in Internet del file HTML come un oggetto della classe URL. Il secondo argomento specifica un nome di file per l immagine. Java supporta attualmente parecchi formati per le immagini, tra cui Graphics Interchange Format (GIF), Joint Photographic Experts Group (JPEG) e Portable Network Graphics (PNG). I nomi di file di ognuno di questi tipi terminano rispettivamente con l estensione.gif,.jpg (o.jpeg) e.png. Obiettivo portabilità 8.1 La classe Image è una classe abstract, quindi gli oggetti Image non possono essere creati direttamente. Per ottenere l indipendenza dalla piattaforma, l implementazione Java su ognuna delle piattaforme fornisce la propria sottoclasse di Image per memorizzare le informazioni relative alle immagini. La riga 15 inizia a caricare l immagine dal computer locale (o a scaricare l immagine da Internet). Quando l immagine viene richiesta dal programma, viene caricata in un thread separato di esecuzione. Questo permette al programma di continuare la propria esecuzione mentre l immagine viene caricata. [Nota: Se il file richiesto non è disponibile, il metodo getimage non segnala un errore.] La classe ImageIcon non è una classe abstract, quindi è possibile creare un oggetto ImageIcon. La riga 16 del metodo init dell applet crea un oggetto ImageIcon, che carica la stessa immagine logo.gif. La classe ImageIcon fornisce vari costruttori che permettono al programma di inizializzare un oggetto ImageIcon con un immagine proveniente dal computer locale, oppure con un immagine conservata in Internet. Il metodo paint dell applet (righe 20-29) visualizza l immagine. La riga 22 usa il metodo drawimage di Graphics per visualizzare un oggetto Image. Il metodo drawimage riceve quattro argomenti. Il primo argomento è un riferimento all oggetto Image da visualizzare (logo1). Il secondo e il terzo argomento sono le coordinate x e y in cui l immagine deve essere visualizzata all interno dell applet (le coordinate corrispondono all angolo superiore sinistro dell immagine). L ultimo argomento è un riferimento a un oggetto ImageObserver. Questo argomento è importante se si visualizzano immagini di grandi dimensioni, che richiedono molto tempo per essere scaricate da Internet. È possibile dunque che il programma esegua il codice che visualizza l immagine prima che questa sia stata scaricata completamente. L oggetto ImageObserver viene avvisato di aggiornare l immagine visualizzata mano a mano che il resto dell immagine viene scaricato. Normalmente, l ImageObserver è l oggetto su cui viene visualizzata l immagine. Un ImageObserver può essere un qualsiasi oggetto che implementa l interfaccia ImageObserver, per esempio la classe Component (una delle superclassi indirette della classe Applet); tutti i Component, quindi (incluso il nostro applet), possono essere degli ImageObserver. Quando eseguite questo applet, osservate attentamente la visualizzazione delle varie parti dell immagine, via via che questa viene caricata. [Nota: Con i computer più veloci, questo effetto potrebbe non essere visibile.] La riga 25 usa un altra versione del metodo drawimage di Graphics per mostrare una versione scalata dell immagine. Il quarto e quinto argomento specificano la larghezza e l altezza dell immagine ai fini della visualizzazione. L immagine viene automaticamente scalata in base alla larghezza e all altezza specificate. In questo esempio, il quarto argomento indica che la larghezza dell immagine scalata deve essere pari alla larghezza dell applet, mentre il

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 441 quinto argomento indica che l altezza deve essere l altezza dell applet meno 120 pixel. La larghezza e l altezza dell applet sono determinate con i metodi getwidth e getheight (ereditati dalla classe Component). La riga 28 usa il metodo painticon di ImageIcon per visualizzare l immagine. Il metodo richiede quattro argomenti: un riferimento al Component sul quale l immagine verrà visualizzata, un riferimento all oggetto Graphics che verrà utilizzato per rappresentare l immagine sullo schermo, la coordinata x dell angolo superiore sinistro dell immagine, e la coordinata y dell angolo superiore sinistro dell immagine. Se confrontate i due modi in cui abbiamo caricato e visualizzato le immagini in questo esempio, vedrete che l impiego di ImageIcon è più semplice. È possibile creare oggetti della classe ImageIcon direttamente, senza alcun bisogno di usare un riferimento ImageObserver durante la visualizzazione dell immagine. È questo il motivo per cui utilizzeremo la classe ImageIcon per tutto il resto del capitolo. [Nota: Il metodo painticon della classe ImageIcon non permette di scalare un immagine. Questa classe, però, fornisce il metodo getimage, che ritorna un riferimento Image da utilizzare con il metodo drawimage di Graphics per visualizzare un immagine scalata.] 8.3 Animare una sequenza di immagini Il prossimo esempio mostra l animazione di una sequenza di immagini che sono conservate all interno di un array di ImageIcon. L animazione presentata nella figura 8.2 è stata progettata come una sottoclasse di JPanel (chiamata LogoAnimator), che può essere attaccata a una finestra di applicazione, oppure a un JApplet. La classe LogoAnimator definisce inoltre un metodo main (righe 85-99) per eseguire l animazione sotto forma di applicazione. Il metodo main definisce un istanza della classe JFrame, aggiungendo un oggetto LogoAnimator al JFrame, per visualizzare l animazione. 1 // Fig. 8.2: LogoAnimator.java 2 // Animazione di una sequenza di immagini 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 public class LogoAnimator extends JPanel implements ActionListener { 8 9 private final static String IMAGE_NAME = deitel ; // nome base immagine 10 protected ImageIcon images[]; // array di immagini 11 12 private int totalimages = 30; // numero di immagini 13 private int currentimage = 0; // indice corrente di immagine 14 private int animationdelay = 50; // ritardo in millisecondi 15 private int width; // larghezza dell immagine 16 private int height; // altezza dell immagine 17 18 private Timer animationtimer; // Timer che controlla l animazione 19 Figura 8.2 L animazione di una sequenza di immagini (continua)

442 CAPITOLO 8 20 // inizializza LogoAnimator caricando le immagini 21 public LogoAnimator() 22 { 23 images = new ImageIcon[ totalimages ]; 24 25 // carica immagini 26 for ( int count = 0; count < images.length; ++count ) 27 images[ count ] = new ImageIcon( getclass().getresource( 28 images/ + IMAGE_NAME + count +.gif ) ); 29 30 // questo esempio assume che le immagini abbiano le stesse dimensioni 31 width = images[ 0 ].geticonwidth(); // ottiene larghezza icona 32 height = images[ 0 ].geticonheight(); // ottiene altezza icona 33 } 34 35 // visualizza immagine corrente 36 public void paintcomponent( Graphics g ) 37 { 38 super.paintcomponent( g ); 39 40 images[ currentimage ].painticon( this, g, 0, 0 ); 41 42 // si sposta alla prossima immagine solo se il timer è partito 43 if ( animationtimer.isrunning() ) 44 currentimage = ( currentimage + 1 ) % totalimages; 45 } 46 47 // risponde a eventi del timer 48 public void actionperformed( ActionEvent actionevent ) 49 { 50 repaint(); // ridisegna animator 51 } 52 53 // fa partire o ripartire l animazione 54 public void startanimation() 55 { 56 if ( animationtimer == null ) { 57 currentimage = 0; 58 animationtimer = new Timer( animationdelay, this ); 59 animationtimer.start(); 60 } 61 else // continua dall ultima immagine visualizzata 62 if (! animationtimer.isrunning() ) 63 animationtimer.restart(); 64 } 65 66 // ferma timer dell animazione 67 public void stopanimation() Figura 8.2 L animazione di una sequenza di immagini (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 443 68 { 69 animationtimer.stop(); 70 } 71 72 // ritorna la dimensione minima di animation 73 public Dimension getminimumsize() 74 { 75 return getpreferredsize(); 76 } 77 78 // ritorna la dimensione preferenziale di animation 79 public Dimension getpreferredsize() 80 { 81 return new Dimension( width, height ); 82 } 83 84 // esegue animation in un JFrame 85 public static void main( String args[] ) 86 { 87 LogoAnimator animation = new LogoAnimator(); // crea LogoAnimator 88 89 JFrame window = new JFrame( Animator test ); // imposta finestra 90 window.setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE ); 91 92 Container container = window.getcontentpane(); 93 container.add( animation ); 94 95 window.pack(); // rende la finestra abbastanza larga per la sua GUI 96 window.setvisible( true ); // visualizza finestra 97 animation.startanimation(); // inizia animazione 98 99 } // fine metodo main 100 101 } // fine classe LogoAnimator Figura 8.2 L animazione di una sequenza di immagini La classe LogoAnimator mantiene un array di ImageIcon che vengono caricate nel costruttore (righe 21-33). Le righe 26-32 creano ogni oggetto ImageIcon e caricano le 30 immagini dell animazione. L argomento del costruttore usa la concatenazione delle stringhe per assemblare il nome del file dai vari pezzi images/, IMAGE_NAME, count e.gif. Ognuna delle immagini dell animazione è un file chiamato deitel#.gif, dove # è un valore 0-29 specificato dalla variabile di controllo del ciclo count. Le righe 31-32 determinano la larghezza e

444 CAPITOLO 8 l altezza dell animazione dalle dimensioni della prima immagine nell array images. Assumeremo che tutte le immagini abbiano la stessa larghezza e altezza. Dopo che il costruttore di LogoAnimator ha caricato le immagini, il metodo main imposta la finestra in cui apparirà l animazione (righe 89-96) e la riga 97 chiama il metodo startanimation della classe LogoAnimator (definito alle righe 54-64) per dare inizio all animazione. L animazione è guidata da un istanza della classe Timer (package javax.swing). Un oggetto della classe Timer genera degli ActionEvent ad un intervallo di tempo fissato in millisecondi (normalmente specificato come argomento del costruttore di Timer) e notifica dell evento tutti i suoi ActionListener registrati. Le righe 56-60 determinano se il riferimento animationtimer di tipo Timer è null. In caso affermativo, currentimage è impostato su 0 (riga 57), per indicare che l animazione dovrebbe iniziare con l immagine che si trova nel primo elemento dell array images. La riga 58 assegna un nuovo oggetto Timer ad animationtimer. Il costruttore di Timer riceve due argomenti: l attesa in millisecondi (in questo esempio, animationdelay è 50, come specificato dalla riga 14) e l ActionListener che risponderà agli ActionEvent di Timer. La classe LogoAnimator implementa ActionListener, quindi la riga 58 specifica this come ascoltatore. La riga 59 avvia l oggetto Timer; una volta avviato, animationtimer genererà un ActionEvent ogni 50 millisecondi. Le righe 62-63 permettono al programma di interrompere e riavviare l animazione. Per ottimizzare un animazione all interno di un applet, per esempio, questa dovrebbe essere interrotta quando l utente passa a un altra pagina Web. Se l utente ritorna alla pagina Web contenente l animazione, il metodo startanimation può essere chiamato per riavviarla. La condizione if alla riga 62 usa il metodo isrunning di Timer per determinare se Timer è attualmente in esecuzione (ovvero, se sta generando degli eventi). Se non è in esecuzione, la riga 63 chiama il metodo restart di Timer per indicare che Timer dovrebbe ricominciare a generare eventi. In risposta a ognuno degli eventi di Timer di questo esempio, il programma chiama il metodo actionperformed (righe 48-51). La riga 50 chiama il metodo repaint di LogoAnimator che programma una chiamata al metodo paintcomponent di LogoAnimator (righe 36-45). Ricordate che qualsiasi sottoclasse di JComponent che esegue dei disegni deve farlo nel suo metodo paintcomponent. Come visto nel capitolo 3, la prima istruzione di qualsiasi metodo paintcomponent dovrebbe essere una chiamata al metodo paintcomponent della superclasse, per assicurarsi che i componenti Swing siano visualizzati correttamente. La riga 40 disegna l ImageIcon dell elemento currentimage all interno dell array. Le righe 43-44 determinano se animationtimer è in esecuzione e, in caso affermativo, si preparano a visualizzare l immagine successiva aumentando di 1 currentimage. Notate il calcolo del resto per impostare il valore di currentimage su 0 quando si supera il valore 29 (l ultimo elemento dell array). L istruzione if ci assicura che, se paintcomponent viene chiamato quando Timer viene fermato, verrà visualizzata la stessa immagine. Questo potrebbe essere utile in una GUI che consente all utente di far partire e fermare l animazione. Per esempio, se l animazione viene fermata e l utente la copre con un altra finestra e poi la scopre nuovamente, verrà chiamato il metodo paintcomponent. In questo caso, non vogliamo che l animazione mostri l immagine successiva. Il metodo stopanimation (righe 67-70) interrompe l animazione chiamando il metodo stop della classe Timer per indicare che il Timer dovrebbe interrompere la generazione di eventi. Questo fatto, a sua volta, impedisce ad actionperformed di chiamare repaint per avviare la visualizzazione dell immagine successiva all interno dell array.

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 445 Ingegneria del software 8.1 Quando si crea un animazione da utilizzare all interno di un applet, è necessario fornire un meccanismo che la disattivi quando l utente passa a una pagina Web diversa dalla pagina in cui si trova l animazione. I metodi getminimumsize (righe 73-76) e getpreferredsize (righe 79-82) sovrascrivono i corrispondenti metodi ereditati dalla classe Component per aiutare il layout manager a determinare la corretta dimensione di un LogoAnimator all interno di un layout. In questo esempio, le immagini sono larghe 160 pixel e alte 80 pixel, quindi il metodo getpreferredsize ritorna un oggetto Dimension contenente i numeri 160 e 80. Il metodo getminimumsize chiama semplicemente getpreferredsize (una normale abitudine di programmazione) per indicare che la dimensione minima e quella preferenziale sono uguali. Alcuni layout manager ignorano le dimensioni specificate da questi metodi. Per esempio, le regioni NORTH e SOUTH di BorderLayout usano solo l altezza preferenziale di un componente. 8.4 Mappe di immagini Una tecnica molto comune per creare pagine Web interattive è il ricorso alle mappe di immagini. Una mappa di immagini è un immagine che possiede delle aree attive su cui l utente può fare clic al fine di eseguire un attività, come il caricamento di una diversa pagina Web all interno del browser. Quando l utente posiziona il puntatore del mouse su una di queste aree, appare normalmente un messaggio descrittivo nella barra di stato del browser o in un tool tip. La figura 8.3 carica un immagine contenente varie icone utilizzate all interno del libro. Il programma permette all utente di posizionare il puntatore del mouse su di un icona, visualizzando un messaggio descrittivo relativo a questa icona. Il gestore di eventi mousemoved (righe 37-41) prende le coordinate del mouse e le passa al metodo translatelocation (righe 59-70). Il metodo translatelocation analizza le coordinate per determinare l icona su cui è stato posizionato il mouse quando è stato chiamato il metodo mousemoved; il metodo ritorna quindi un messaggio che indica ciò che l icona rappresenta; questo messaggio viene visualizzato nella barra di stato del contenitore dell applet. Facendo clic all interno dell applet della figura 8.3, non viene eseguita alcuna azione. Nel capitolo 7, abbiamo parlato delle tecniche necessarie per caricare un altra pagina Web all interno di un browser usando oggetti URL e l interfaccia AppletContext. Usando queste tecniche, è possibile modificare quest applet affinché ogni icona sia associata a un URL diverso che il browser può visualizzare quando l utente fa clic sull icona. 1 // Fig. 8.3: ImageMap.java 2 // Dimostrazione di una mappa di immagini 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 public class ImageMap extends JApplet { 8 private ImageIcon mapimage; 9 Figura 8.3 Una mappa di immagini (continua)

446 CAPITOLO 8 10 private static final String captions[] = { Common Programming Error, 11 Good Programming Practice, Graphical User Interface Tip, 12 Performance Tip, Portability Tip, 13 Software Engineering Observation, Error-Prevention Tip }; 14 15 // imposta ascoltatori del mouse 16 public void init() 17 { 18 addmouselistener( 19 20 new MouseAdapter() { // classe interna anonima 21 22 // indica quando il puntatore del mouse esce dall area dell applet 23 public void mouseexited( MouseEvent event ) 24 { 25 showstatus( Pointer outside applet ); 26 } 27 28 } // fine classe interna anonima 29 30 ); // fine chiamata a addmouselistener 31 32 addmousemotionlistener( 33 34 new MouseMotionAdapter() { // classe interna anonima 35 36 // determina l icona su cui il mouse è posizionato 37 public void mousemoved( MouseEvent event ) 38 { 39 showstatus( translatelocation( 40 event.getx(), event.gety() ) ); 41 } 42 43 } // fine classe interna anonima 44 45 ); // fine chiamata a addmousemotionlistener 46 47 mapimage = new ImageIcon( icons.png ); // ottiene immagine 48 49 } // fine metodo init 50 51 // visualizza mapimage 52 public void paint( Graphics g ) 53 { 54 super.paint( g ); 55 mapimage.painticon( this, g, 0, 0 ); 56 } Figura 8.3 Una mappa di immagini (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 447 57 58 // ritorna testo descrittivo associato con l icona 59 public String translatelocation( int x, int y ) 60 { 61 // se le coordinate sono fuori dall immagine, ritorna immediatamente 62 if ( x >= mapimage.geticonwidth() y >= mapimage.geticonheight() ) 63 return ; 64 65 // determina il numero dell icona (0-6) 66 int iconwidth = mapimage.geticonwidth() / 7; 67 int iconnumber = x / iconwidth; 68 69 return captions[ iconnumber ]; // ritorna testo appropriato 70 } 71 72 } // fine classe ImageMap Figura 8.3 Una mappa di immagini (continua)

448 CAPITOLO 8 Figura 8.3 Una mappa di immagini 8.5 Caricare e riprodurre i clip audio I programmi Java sono in grado di utilizzare e riprodurre i clip audio, che Internet offre in grande abbondanza. Per poter riprodurre questi clip audio, il sistema deve disporre dell apposito hardware (altoparlanti e una scheda audio). Java offre diversi meccanismi per la riproduzione dei suoni all interno di un applet. I due più semplici sono il metodo play di Applet e il metodo play dell interfaccia AudioClip. Funzionalità aggiuntive sono disponibili nelle librerie Java Media Framework e Java Sound. Se volete riprodurre un suono una volta all interno di un programma, il metodo play di Applet permette di caricare questo suono e di riprodurlo una sola volta, dopodiché il suono viene contrassegnato per la garbage collection. Il metodo play di Applet ha due forme: public void play( URL location, String soundfilename ); public void play( URL soundurl ); La prima versione carica il clip audio memorizzato nel file soundfilename, alla posizione location, e ne riproduce il suono. Il primo argomento è normalmente una chiamata al

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 449 metodo getdocumentbase o getcodebase dell applet. Il metodo getdocumentbase ritorna la posizione del file HTML che ha caricato l applet (se l applet è in un package, il metodo ritorna la posizione del package o del file JAR che contiene il package). Il metodo getcodebase indica dove si trova il file.class dell applet. La seconda versione del metodo play, invece, prende un URL che contiene la posizione e il nome del file del clip audio. L istruzione play( getdocumentbase(), hi.au ); carica il clip audio memorizzato nel file hi.au, riproducendolo una volta. Il motore sonoro che riproduce i clip audio supporta vari formati di file, tra cui Sun Audio (estensione.au), Windows Wave (.wav), Macintosh AIFF (.aif o.aiff), Musical Instrument Digital Interface (MIDI) (.mid o.rmi). Le librerie Java Media Framework (JMF) e Java Sound supportano anche altri formati. Il programma della figura 8.4 mostra il caricamento e la riproduzione di un AudioClip (package java.applet). Questa tecnica è più flessibile rispetto al metodo play di Applet, in quanto permette di memorizzare il clip audio all interno del programma, così da poterlo riutilizzare più volte durante l esecuzione. Il metodo getaudioclip Applet ha due forme, che prendono gli stessi argomenti del metodo play visto poco fa. Il metodo getaudioclip ritorna un riferimento a un AudioClip; una volta caricato un AudioClip, è possibile invocare tre metodi: play, loop e stop. Il metodo play riproduce il clip una volta; il metodo loop riproduce il clip in continuazione; il metodo stop interrompe la riproduzione di un clip. Nel programma, ognuno di questi metodi è associato a un pulsante dell applet. 1 // Fig. 8.4: LoadAudioAndPlay.java 2 // Carica un clip audio e lo riproduce 3 4 import java.applet.*; 5 import java.awt.*; 6 import java.awt.event.*; 7 import javax.swing.*; 8 9 public class LoadAudioAndPlay extends JApplet { 10 private AudioClip sound1, sound2, currentsound; 11 private JButton playsound, loopsound, stopsound; 12 private JComboBox choosesound; 13 14 // carica il suono quando l applet inizia l esecuzione 15 public void init() 16 { 17 Container container = getcontentpane(); 18 container.setlayout( new FlowLayout() ); 19 20 String choices[] = { Welcome, Hi }; 21 choosesound = new JComboBox( choices ); 22 23 choosesound.additemlistener( 24 25 new ItemListener() { Figura 8.4 Caricare e riprodurre un AudioClip (continua)

450 CAPITOLO 8 26 27 // ferma il suono e imposta il suono sulla selezione dell utente 28 public void itemstatechanged( ItemEvent e ) 29 { 30 currentsound.stop(); 31 32 currentsound = 33 choosesound.getselectedindex() == 0? sound1 : sound2; 34 } 35 36 } // fine classe interna anonima 37 38 ); // fine chiamata a additemlistener 39 40 container.add( choosesound ); 41 42 // imposta i pulsanti e il loro gestore degli eventi 43 ButtonHandler handler = new ButtonHandler(); 44 45 playsound = new JButton( Play ); 46 playsound.addactionlistener( handler ); 47 container.add( playsound ); 48 49 loopsound = new JButton( Loop ); 50 loopsound.addactionlistener( handler ); 51 container.add( loopsound ); 52 53 stopsound = new JButton( Stop ); 54 stopsound.addactionlistener( handler ); 55 container.add( stopsound ); 56 57 // carica suoni e imposta currentsound 58 sound1 = getaudioclip( getdocumentbase(), welcome.wav ); 59 sound2 = getaudioclip( getdocumentbase(), hi.au ); 60 currentsound = sound1; 61 62 } // fine metodo init 63 64 // ferma il suono quando l utente carica un altra pagina Web 65 public void stop() 66 { 67 currentsound.stop(); 68 } 69 70 // classe interna privata per gestire eventi dei pulsanti 71 private class ButtonHandler implements ActionListener { 72 73 // elabora eventi dei pulsanti play, loop e stop Figura 8.4 Caricare e riprodurre un AudioClip (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 451 74 public void actionperformed( ActionEvent actionevent ) 75 { 76 if ( actionevent.getsource() == playsound ) 77 currentsound.play(); 78 79 else if ( actionevent.getsource() == loopsound ) 80 currentsound.loop(); 81 82 else if ( actionevent.getsource() == stopsound ) 83 currentsound.stop(); 84 } 85 86 } // fine classe ButtonHandler 87 88 } // fine classe LoadAudioAndPlay Figura 8.4 Caricare e riprodurre un AudioClip Le righe 58-59 del metodo init dell applet usano getaudioclip per caricare due file audio: un file Windows Wave (welcome.wav) e un file Sun Audio (hi.au). L utente può selezionare quale clip audio riprodurre dal JComboBox choosesound. Notate come il metodo stop dell applet venga sovrascritto alle righe 65-68. Quando l utente cambia pagina Web, viene chiamato il metodo stop; questo garantisce che la riproduzione del clip audio venga interrotta, altrimenti continuerebbe in sottofondo, anche se l applet non viene visualizzato nel browser. Questo potrebbe non essere un problema, ma potrebbe disturbare l utente. L esperienza dell utente 8.1 Durante la riproduzione dei clip audio in un applet o in un applicazione, fornite sempre all utente un meccanismo per disabilitare l audio. 8.6 Risorse in Internet e World Wide Web www.nasa.gov/gallery/index.html La galleria multimediale della NASA contiene un ampia varietà di immagini, clip audio e video che possono essere scaricati e utilizzati per testare i propri programmi Java di tipo multimediale. sunsite.sut.ac.jp/multimed/ Il sito Web Sunsite Japan Multimedia Collection fornisce un ampia varietà di immagini, clip audio e video che possono essere scaricati e utilizzati a scopi educativi. www.anbg.gov.au/anbg/index.html

452 CAPITOLO 8 Il sito Web Australian National Botanic Gardens offre collegamenti ai suoni di molti animali. Provate il collegamento Common Birds. www.thefreesite.com Offre collegamenti a suoni e immagini gratuiti. www.soundcentral.com Offre audio clip nei formati WAV, AU, AIFF e MIDI. www.animationfactory.com Offre migliaia di animazioni GIF gratuite per uso personale. www.clipart.com Servizio (basato su iscrizione) che fornisce immagini e suoni. www.pngart.com Fornisce oltre 50 mila immagini gratuite in formato PNG. developer.java.sun.com/developer/techdocs/hi/repository Il Java Look-and-Feel Graphics Repository fornisce immagini standard da usare in una GUI Swing Riferimenti alle librerie Java Multimedia java.sun.com/products/java-media/jmf/ Home page di Java Media Framework (JMF) API. Qui potete scaricare l ultima implementazione del JMF e la relativa documentazione. java.sun.com/products/java-media/sound/ Home page di Java Sound API. Fornisce funzionalità per riprodurre e registrare audio. java.sun.com/products/java-media/3d/ Home page di Java 3D API. Fornisce funzionalità per produrre immagini tridimensionali. developer.java.sun.com/developer/onlinetraining/java3d/ Fornisce un corso di Java 3D API. java.sun.com/products/java-media/jai/ Home page di Java Advanced Imaging API. Fornisce funzionalità per elaborare immagini, come aumento del contrasto, ritaglio, scalatura e trasformazioni geometriche. freetts.sourceforge.net/docs/index.php FreeTTS è un implementazione di Java Speech API. java.sun.com/products/java-media/2d/ Home page di Java 2D API. Questa API (introdotta nel capitolo 1) fornisce funzionalità complesse per le immagini bidimensionali. java.sun.com/j2se/1.4.1/docs/guide/imageio/

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 453 Contiene una rassegna di Java Image I/O API, che permette ai programmi di definire il caricamento e il salvataggio di formati di immagini che non sono attualmente supportati dalle librerie Java. 8.7 (Caso di studio facoltativo) Pensare a oggetti: animazioni e suoni nella vista Questo caso di studio si è focalizzato principalmente sul modello MVC della nostra simulazione di ascensore. Ora che abbiamo completato la progettazione del modello, ci occupiamo della vista, che fornisce la presentazione visiva del modello. Nel nostro caso di studio, la vista, incapsulata nella classe ElevatorView, è un oggetto JPanel contenente altri oggetti JPanel figli, ognuno rappresentante un oggetto unico del modello MVC (per esempio, un oggetto Person, un oggetto Button, ecc.). La classe ElevatorView è la classe più grande nel caso di studio. In questa sezione, discutiamo le classi per la grafica e il suono usate da ElevatorView. Presenteremo e spiegheremo il resto del codice sul sito Web www.apogeonline.com/libri/ 02097/allegati/. Nella sezione 3.7 del volume Tecniche di Base, abbiamo costruito il diagramma di classe del nostro modello individuando sostantivi e frasi dalla specifica del problema. Abbiamo ignorato parecchi di questi sostantivi, perché non erano associati con il modello MVC. Ora, elenchiamo i sostantivi e le frasi che sono relativi alla visualizzazione del modello MVC: visualizzazione audio musica dell ascensore. Il sostantivo visualizzazione corrisponde alla vista, o alla presentazione visuale, del modello MVC. Come descritto nella sezione 2.7, la classe ElevatorView aggrega diverse classi. Il sostantivo audio si riferisce agli effetti sonori che la nostra simulazione genera quando accadono varie azioni; creeremo la classe SoundEffects per generare tali effetti sonori. La frase musica dell ascensore si riferisce alla musica che viene riprodotta quando una persona viaggia sull ascensore; useremo la classe SoundEffects anche per riprodurre questa musica. La vista visualizza gli oggetti del modello MVC. Creeremo la classe ImagePanel per rappresentare gli oggetti stazionari del modello, come ElevatorShaft. Creeremo la classe MovingPanel, che estende ImagePanel, per rappresentare gli oggetti in movimento, come Elevator. Infine, creeremo la classe AnimatedPanel, che estende MovingPanel, per rappresentare gli oggetti in movimento la cui immagine corrispondente cambia continuamente, come Person (useremo diverse immagini per mostrare la persona che cammina e preme un pulsante). Usando queste classi, presentiamo il diagramma di classe della vista per la nostra simulazione nella figura 8.5. Le note indicano i ruoli che hanno le classi nel sistema. Secondo il diagramma di classe, la classe ElevatorView rappresenta la vista, le classi ImagePanel, MovingPanel e AnimatedPanel si riferiscono alla grafica e la classe SoundEffects si riferisce ai suoni. La classe ElevatorView contiene diverse istanze delle classi ImagePanel, MovingPanel e AnimatedPanel e un istanza della classe SoundEffects. Nella versione finale del caso di studio, assoceremo ogni oggetto del modello con una classe corrispondente nella vista.

454 CAPITOLO 8 ImagePanel 1..* javax.swing.jpanel 1 MovingPanel 1..* 1 1 ElevatorView 1 Audio AnimatedPanel 1..* 1 SoundEffects Grafica Vista Figura 8.5 Diagramma di classe della vista del simulatore di ascensore In questa sezione, discutiamo le classi ImagePanel, MovingPanel e AnimatedPanel per spiegare la grafica e le animazioni. Poi, discuteremo la classe SoundEffects per spiegare le funzionalità audio. ImagePanel La classe ElevatorView usa oggetti di sottoclassi di JPanel per rappresentare e visualizzare ogni oggetto nel modello (come Elevator, Person, ecc.). La classe ImagePanel (figura 8.6) è una sottoclasse di JPanel in grado di visualizzare un immagine in una data posizione dello schermo. La classe ElevatorView usa oggetti ImagePanel per rappresentare oggetti immobili nel modello, come ElevatorShaft e i due Floor. La classe ImagePanel contiene un attributo intero, ID (riga 16), che dichiara un identificatore unico per tenere traccia dell ImagePanel nella vista. Ciò è utile quando diversi oggetti della stessa classe sono presenti nel modello, come diversi oggetti Person. La classe ImagePanel contiene l oggetto position della classe Point2D.Double (riga 19) per rappresentare la sua posizione sullo schermo. Vedremo più avanti che MovingPanel, che estende ImagePanel, dichiara la velocità con valori double. Convertiremo le coordinate position in valori int per posizionare l oggetto ImagePanel sullo schermo (Java rappresenta le coordinate dello schermo come interi) nel metodo setposition (righe 90-94). La classe ImagePanel contiene anche un oggetto ImageIcon chiamato imageicon (riga 22), il cui metodo paintcomponent (righe 54-60) visualizza l icona sullo schermo. Le righe 41-42 inizializzano ImageIcon usando un parametro stringa che contiene il nome dell immagine. Infine, la classe ImagePanel contiene l oggetto panelchildren della classe Set (riga 25) che memorizza tutti gli oggetti JPanel figli (o oggetti di una sottoclasse di JPanel). Gli oggetti figli vengono visualizzati sopra il loro ImagePanel genitore: per esempio, un oggetto Person dentro un Elevator. Il primo metodo add (righe 63-67) aggiunge un oggetto a panelchildren. Il secondo metodo add (righe 70-74) inserisce un oggetto in panelchildren all indice specificato. Il metodo seticon (righe 84-87) imposta imageicon con una nuova immagine. Gli oggetti della classe AnimatedPanel usano

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 455 ripetutamente il metodo seticon per cambiare l immagine visualizzata, in modo da eseguire l animazione. 1 // ImagePanel.java 2 // sottoclasse di JPanel per posizionare e visualizzare ImageIcon 3 package com.deitel.jhtp5.elevator.view; 4 5 // package Java di base Java 6 import java.awt.*; 7 import java.awt.geom.*; 8 import java.util.*; 9 10 // package Java di estensione 11 import javax.swing.*; 12 13 public class ImagePanel extends JPanel { 14 15 // identificatore 16 private int ID; 17 18 // posizione sullo schermo 19 private Point2D.Double position; 20 21 // imageicon da disegnare sullo schermo 22 private ImageIcon imageicon; 23 24 // memorizza tutti i figli di ImagePanel 25 private Set panelchildren; 26 27 // costruttore che inizializza posizione e immagine 28 public ImagePanel( int identifier, String imagename ) 29 { 30 super( null ); // specifica layout null 31 setopaque( false ); // rende trasparente 32 33 // imposta identificatore unico 34 ID = identifier; 35 36 // imposta posizione 37 position = new Point2D.Double( 0, 0 ); 38 setlocation( 0, 0 ); 39 40 // crea ImageIcon con imagename dato 41 imageicon = new ImageIcon( 42 getclass().getresource( imagename ) ); 43 44 Image image = imageicon.getimage(); Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobile del modello (continua)

456 CAPITOLO 8 45 setsize( 46 image.getwidth( this ), image.getheight( this ) ); 47 48 // crea Set per memorizzare i figli di Panel 49 panelchildren = new HashSet(); 50 51 } // fine costruttore di ImagePanel 52 53 // disegna Panel sullo schermo 54 public void paintcomponent( Graphics g ) 55 { 56 super.paintcomponent( g ); 57 58 // se l immagine e pronta, disegnala sullo schermo 59 imageicon.painticon( this, g, 0, 0 ); 60 } 61 62 // aggiunge figlio di ImagePanel a ImagePanel 63 public void add( ImagePanel panel ) 64 { 65 panelchildren.add( panel ); 66 super.add( panel ); 67 } 68 69 // aggiunge figlio di ImagePanel a ImagePanel all indice dato 70 public void add( ImagePanel panel, int index ) 71 { 72 panelchildren.add( panel ); 73 super.add( panel, index ); 74 } 75 76 // rimuove figlio di ImagePanel da ImagePanel 77 public void remove( ImagePanel panel ) 78 { 79 panelchildren.remove( panel ); 80 super.remove( panel ); 81 } 82 83 // imposta ImageIcon corrente da visualizzare 84 public void seticon( ImageIcon icon ) 85 { 86 imageicon = icon; 87 } 88 89 // imposta posizione sullo schermo 90 public void setposition( double x, double y ) 91 { 92 position.setlocation( x, y ); Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobile del modello (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 457 93 setlocation( ( int ) x, ( int ) y ); 94 } 95 96 // ritorna identificatore di ImagePanel 97 public int getid() 98 { 99 return ID; 100 } 101 102 // ottiene posizione di ImagePanel 103 public Point2D.Double getposition() 104 { 105 return position; 106 } 107 108 // ottiene imageicon 109 public ImageIcon getimageicon() 110 { 111 return imageicon; 112 } 113 114 // ottiene Set di figli di ImagePanel 115 public Set getchildren() 116 { 117 return panelchildren; 118 } 119 } Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobile del modello MovingPanel La classe MovingPanel (figura 8.7) è una sottoclasse di ImagePanel in grado di cambiare la sua posizione sullo schermo in base ai valori xvelocity e yvelocity (righe 20-21). La classe ElevatorView usa oggetti MovingPanel per rappresentare oggetti mobili del modello, come Elevator. 1 // MovingPanel.java 2 // Sottoclasse di JPanel con funzionalità di movimento sullo schermo 3 package com.deitel.jhtp5.elevator.view; 4 5 // package Java di base 6 import java.awt.*; 7 import java.awt.geom.*; 8 import java.util.*; 9 10 // package Java di estensione Figura 8.7 La classe MovingPanel rappresenta e visualizza un oggetto che si muove dal modello (continua)

458 CAPITOLO 8 11 import javax.swing.*; 12 13 public class MovingPanel extends ImagePanel { 14 15 // MovingPanel dovrebbe cambiare posizione? 16 private boolean moving; 17 18 // numero di pixel di cui MovingPanel si muove nelle direzioni x e y 19 // per animationdelay millisecondi 20 private double xvelocity; 21 private double yvelocity; 22 23 // costruttore che inizializza posizione, velocità e immagine 24 public MovingPanel( int identifier, String imagename ) 25 { 26 super( identifier, imagename ); 27 28 // imposta velocità di MovingPanel 29 xvelocity = 0; 30 yvelocity = 0; 31 32 } // fine costruttore di MovingPanel 33 34 // aggiorna posizione e animazione di MovingPanel 35 public void animate() 36 { 37 // aggiorna posizione a seconda della velocità 38 if ( ismoving() ) { 39 double oldxposition = getposition().getx(); 40 double oldyposition = getposition().gety(); 41 42 setposition( oldxposition + xvelocity, 43 oldyposition + yvelocity ); 44 } 45 46 // aggiorna tutti i figli di MovingPanel 47 Iterator iterator = getchildren().iterator(); 48 49 while ( iterator.hasnext() ) { 50 MovingPanel panel = ( MovingPanel ) iterator.next(); 51 panel.animate(); 52 } 53 } // fine metodo animate 54 55 // MovingPanel si sta muovendo sullo schermo? 56 public boolean ismoving() 57 { 58 return moving; 59 } Figura 8.7 La classe MovingPanel rappresenta e visualizza un oggetto che si muove dal modello (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 459 60 61 // imposta MovingPanel per muoversi sullo schermo 62 public void setmoving( boolean move ) 63 { 64 moving = move; 65 } 66 67 // imposta le velocità x e y di MovingPanel 68 public void setvelocity( double x, double y ) 69 { 70 xvelocity = x; 71 yvelocity = y; 72 } 73 74 // ritorna velocità x di MovingPanel 75 public double getxvelocity() 76 { 77 return xvelocity; 78 } 79 80 // ritorna velocità y di MovingPanel 81 public double getyvelocity() 82 { 83 return yvelocity; 84 } 85 } Figura 8.7 La classe MovingPanel rappresenta e visualizza un oggetto che si muove dal modello Il metodo animate (righe 35-53) muove MovingPanel secondo i valori attuali dei campi xvelocity e yvelocity. Se la variabile boolean moving (riga 16) è true, le righe 38-44 usano i campi xvelocity e yvelocity per determinare la prossima posizione di movingpanel. Le righe 47-52 ripetono il procedimento per tutti i figli. Nella nostra simulazione, ElevatorView invoca il metodo animate e il metodo paintcomponent della classe ImagePanel ogni 50 millisecondi. Queste chiamate in rapida successione spostano l oggetto MovingPanel. AnimatedPanel La classe AnimatedPanel (figura 8.8), che estende la classe MovingPanel, rappresenta un oggetto animato del modello (cioè, oggetti in movimento la cui immagine corrispondente cambia continuamente), come Person. La classe ElevatorView anima un AnimatedPanel cambiando l immagine associata con imageicon. 1 // AnimatedPanel.java 2 // Sottoclasse di Panel con funzionalità di animazione 3 package com.deitel.jhtp5.elevator.view; 4 Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animato dal modello (continua)

460 CAPITOLO 8 5 // package Java di base 6 import java.awt.*; 7 import java.util.*; 8 9 // package Java di estensione 10 import javax.swing.*; 11 12 public class AnimatedPanel extends MovingPanel { 13 14 // ImageIcon deve essere animato? 15 private boolean animating; 16 17 // frequenza di cambio immagine 18 private int animationrate; 19 private int animationratecounter; 20 private boolean cycleforward = true; 21 22 // ImageIcon individuali usati per l animazione 23 private ImageIcon imageicons[]; 24 25 // memorizza tutte le sequenze di frame 26 private java.util.list framesequences; 27 private int currentanimation; 28 29 // deve continuare l animazione alla fine del ciclo? 30 private boolean loop; 31 32 // deve visualizzare l ultima immagine alla fine dell animazione? 33 private boolean displaylastframe; 34 35 // determina la prossima immagine da visualizzare 36 private int currentframecounter; 37 38 // costruttore che prende un array di nomi di file 39 public AnimatedPanel( int identifier, String imagename[] ) 40 { 41 super( identifier, imagename[0] ); 42 43 // crea oggetti ImageIcon dall array di stringhe imagename 44 imageicons = new ImageIcon[ imagename.length ]; 45 46 for ( int i = 0; i < imageicons.length; i++ ) { 47 imageicons[i] = new ImageIcon( 48 getclass().getresource( imagename[i] ) ); 49 } 50 51 framesequences = new ArrayList(); 52 53 } // fine costruttore di AnimatedPanel 54 Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animato dal modello (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 461 55 // aggiorna posizione dell icona e immagine dell animazione 56 public void animate() 57 { 58 super.animate(); 59 60 // visualizza la prossima immagine se counter > frequenza di animazione 61 if ( framesequences!= null && isanimating() ) { 62 63 if ( animationratecounter > animationrate ) { 64 animationratecounter = 0; 65 determinenextframe(); 66 } 67 else 68 animationratecounter++; 69 } 70 } // fine metodo animate 71 72 // determina prossima immagine dell animazione 73 private void determinenextframe() 74 { 75 int framesequence[] = 76 ( int[] ) framesequences.get( currentanimation ); 77 78 // se non ci sono più immagini, determina immagine finale 79 // a meno che non si debba ripetere l animazione 80 if ( currentframecounter >= framesequence.length ) { 81 currentframecounter = 0; 82 83 // se loop è false, termina animazione 84 if (!isloop() ) { 85 86 setanimating( false ); 87 88 if ( isdisplaylastframe() ) 89 90 // visualizza ultima immagine della sequenza 91 currentframecounter = framesequence.length - 1; 92 } 93 } 94 95 // imposta immagine corrente dell animazione 96 setcurrentframe( framesequence[ currentframecounter ] ); 97 currentframecounter++; 98 99 } // fine metodo determinenextframe 100 101 // aggiunge animazione all ArrayList framesequences Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animato dal modello (continua)

462 CAPITOLO 8 102 public void addframesequence( int framesequence[] ) 103 { 104 framesequences.add( framesequence ); 105 } 106 107 // chiede se AnimatedPanel sta eseguendo l animazione 108 public boolean isanimating() 109 { 110 return animating; 111 } 112 113 // imposta AnimatedPanel per eseguire l animazione 114 public void setanimating( boolean animate ) 115 { 116 animating = animate; 117 } 118 119 // imposta ImageIcon corrente 120 public void setcurrentframe( int frame ) 121 { 122 seticon( imageicons[ frame ] ); 123 } 124 125 // imposta frequenza di animazione 126 public void setanimationrate( int rate ) 127 { 128 animationrate = rate; 129 } 130 131 // ottiene frequenza di animazione 132 public int getanimationrate() 133 { 134 return animationrate; 135 } 136 137 // imposta se l animazione deve ripetersi 138 public void setloop( boolean loopanimation ) 139 { 140 loop = loopanimation; 141 } 142 143 // ottiene se l animazione deve ripetersi 144 public boolean isloop() 145 { 146 return loop; 147 } 148 Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animato dal modello (continua)

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 463 149 // ottiene se visualizzare l ultima immagine alla fine dell animazione 150 private boolean isdisplaylastframe() 151 { 152 return displaylastframe; 153 } 154 155 // imposta se visualizzare l ultima immagine alla fine dell animazione 156 public void setdisplaylastframe( boolean displayframe ) 157 { 158 displaylastframe = displayframe; 159 } 160 161 // inizia ad eseguire la sequenza di animazione all indice dato 162 public void playanimation( int framesequence ) 163 { 164 currentanimation = framesequence; 165 currentframecounter = 0; 166 setanimating( true ); 167 } 168 } Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animato dal modello La classe AnimatedPanel sceglie un oggetto ImageIcon da disegnare sullo schermo tra diversi oggetti ImageIcon memorizzati nell array imageicons (riga 23). La classe AnimatedPanel determina l oggetto ImageIcon secondo una sequenza di riferimenti, memorizzata nella lista framesequences (riga 26), che è un array di interi che memorizza la sequenza appropriata per visualizzare gli oggetti ImageIcon: in particolare, ogni intero rappresenta l indice di un oggetto ImageIcon nell array imageicons. La figura 8.9 mostra la relazione tra imageicons e framesequences (questo non è un diagramma UML). Per esempio, la sequenza numero 2 = { 2, 1, 0 } si riferisce a { imageicon[2], imageicon[1], imageicon[0] }, che porta alla sequenza di immagini { C, B, A }. Nella vista, ogni immagine è un file.png unico. Il metodo framesequences image sequences imageicons 0= 0 1 2 A B C 1= 0 1 3 1 0 A B D B A A B C D 0 1 2 3 2= 2 1 0 C B A 3= 3 2 2 0 D C C A Figura 8.9 Relazione tra l array imageicons e la lista FrameSequences