33
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 AudioClip AudioClip AudioClip 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 manipo- lazione dei dati e delle informazioni. Una delle caratteristiche più interessanti di Java è sicu- ramente 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 tridimensiona- le 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 potran- no 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) ren- dono possibile la multimedialità. A trarre beneficio da questa rivoluzione multimediale sa- ranno 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

La multimedialità: le immagini, le animazioni e i suoni · Nei prossimi dieci anni, lo sviluppo nella grafica tridimensionale renderà possibili nuove applicazioni: immaginate di

  • Upload
    vohanh

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

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 usandoun oggetto AudioClipAudioClipAudioClipAudioClipAudioClip

8.1 IntroduzioneCon l’evoluzione dell’informatica, i computer hanno smesso di essere degli strumenti utilisoltanto a eseguire velocemente calcoli matematici, e sono diventati strumenti per la manipo-lazione dei dati e delle informazioni. Una delle caratteristiche più interessanti di Java è sicu-ramente la multimedialità, ovvero la capacità di usare suoni, immagini, grafica e video nelleapplicazioni.

La programmazione multimediale offre molte sfide nuove. I nuovi computer vengonoormai 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 tridimensiona-le e ad alta risoluzione. Nei prossimi dieci anni, lo sviluppo nella grafica tridimensionalerenderà possibili nuove applicazioni: immaginate di avere una televisione tridimensionalenella vostra casa, in cui seguire gli eventi sportivi e gli spettacoli come se avvenissero nelvostro salotto! Gli studenti di medicina potranno vedere operazioni che si stanno svolgendoa migliaia di chilometri di distanza come se avvenissero nella stessa stanza. Le persone potran-no imparare a guidare usando simulatori di automobile estremamente realistici prima ancoradi salire in auto. Le possibilità sono eccitanti e potenzialmente senza fine.

La multimedialità richiede ai computer un’enorme quantità di potenza. Fino a pocotempo fa, non erano disponibili dei computer economici con la potenza necessaria. I processoriveloci 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) ren-dono possibile la multimedialità. A trarre beneficio da questa rivoluzione multimediale sa-ranno principalmente l’industria informatica e il mondo delle comunicazioni, in quanto gliutenti 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

19 - Multimedialità.p65 19/12/2003, 9.36437

438 CAPITOLO 8

multimediali. Paradossalmente, poi, il costo di tutto ciò non sarà eccessivamente elevato, inquanto la competizione sarà altissima e, quindi, i prezzi tenderanno a scendere sempre più.

Per creare applicazioni multimediali efficaci, però, sono necessari linguaggi di program-mazione che facilitino la creazione di contenuti multimediali. La maggior parte dei linguaggiattualmente esistenti, infatti, non possiede capacità multimediali di tipo nativo. Al contrariodi questi linguaggi, Java offre funzionalità multimediali complete, che permettono ai pro-grammatori di sviluppare da subito applicazioni multimediali estremamente interessanti epotenti.

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 scatene-ranno la vostra creatività.

8.2 Caricare, visualizzare e scalare immaginiLe capacità multimediali di Java consentono di gestire grafica, immagini, suoni e video. Ini-ziamo 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 nellasua dimensione originale e poi ingrandita, usando due versioni del metodo drawImage dellaclasse 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 posizionedell’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;1112 // carica immagine quando l’applet viene caricata13 public void init()

Figura 8.1 Caricare e visualizzare un’immagine in un applet (continua)

19 - Multimedialità.p65 19/12/2003, 9.36438

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 439

14 {15 logo1 = getImage( getDocumentBase(), “logo.gif” );16 logo2 = new ImageIcon( “logo.gif” );17 }1819 // visualizza immagine20 public void paint( Graphics g )21 {22 g.drawImage( logo1, 0, 0, this ); // disegna immagine originale2324 // disegna immagine che riempie larghezza e altezza meno

120 pixel25 g.drawImage( logo1, 0, 120, getWidth(), getHeight() – 120, this );2627 // disegna icona usando il suo metodo paintIcon28 logo2.paintIcon( this, g, 180, 0 );29 }3031 } // 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 ogget-to della classe Image. È necessario invece che l’applet chiami un metodo che fa in modo cheil contenitore dell’applet carichi e ritorni l’oggetto Image da usare nel programma. La classeApplet (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: laposizione e il nome del file dell’immagine. Nel primo argomento, il metodo getDocumentBasedella classe Applet viene utilizzato per ritornare un URL che rappresenta la posizione dell’im-magine in Internet (o sul computer, se è da qui che proviene l’applet). In questo caso, si parte

19 - Multimedialità.p65 19/12/2003, 9.36439

440 CAPITOLO 8

dal presupposto che l’immagine da caricare si trovi nella stessa directory del file HTML cheha invocato l’applet. Il metodo getDocumentBase ritorna la posizione in Internet del fileHTML come un oggetto della classe URL. Il secondo argomento specifica un nome di file perl’immagine. Java supporta attualmente parecchi formati per le immagini, tra cui GraphicsInterchange 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 cre-ati direttamente. Per ottenere l’indipendenza dalla piattaforma, l’implementazione Javasu ognuna delle piattaforme fornisce la propria sottoclasse di Image per memorizzare leinformazioni relative alle immagini.

La riga 15 inizia a caricare l’immagine dal computer locale (o a scaricare l’immagine daInternet). Quando l’immagine viene richiesta dal programma, viene caricata in un threadseparato di esecuzione. Questo permette al programma di continuare la propria esecuzionementre l’immagine viene caricata. [Nota: Se il file richiesto non è disponibile, il metodogetImage non segnala un errore.]

La classe ImageIcon non è una classe abstract, quindi è possibile creare un oggettoImageIcon. La riga 16 del metodo init dell’applet crea un oggetto ImageIcon, che carica lastessa immagine logo.gif. La classe ImageIcon fornisce vari costruttori che permettono alprogramma di inizializzare un oggetto ImageIcon con un’immagine proveniente dal compu-ter locale, oppure con un’immagine conservata in Internet.

Il metodo paint dell’applet (righe 20-29) visualizza l’immagine. La riga 22 usa il meto-do drawImage di Graphics per visualizzare un oggetto Image. Il metodo drawImage ricevequattro 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 esserevisualizzata all’interno dell’applet (le coordinate corrispondono all’angolo superiore sinistrodell’immagine). L’ultimo argomento è un riferimento a un oggetto ImageObserver. Questoargomento è importante se si visualizzano immagini di grandi dimensioni, che richiedonomolto tempo per essere scaricate da Internet. È possibile dunque che il programma esegua ilcodice che visualizza l’immagine prima che questa sia stata scaricata completamente. L’ogget-to ImageObserver viene avvisato di aggiornare l’immagine visualizzata mano a mano che ilresto dell’immagine viene scaricato. Normalmente, l’ImageObserver è l’oggetto su cui vienevisualizzata l’immagine. Un ImageObserver può essere un qualsiasi oggetto che implemental’interfaccia ImageObserver, per esempio la classe Component (una delle superclassi indiret-te della classe Applet); tutti i Component, quindi (incluso il nostro applet), possono esseredegli ImageObserver. Quando eseguite questo applet, osservate attentamente la visualizzazionedelle 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 unaversione scalata dell’immagine. Il quarto e quinto argomento specificano la larghezza e l’al-tezza dell’immagine ai fini della visualizzazione. L’immagine viene automaticamente scalatain base alla larghezza e all’altezza specificate. In questo esempio, il quarto argomento indicache la larghezza dell’immagine scalata deve essere pari alla larghezza dell’applet, mentre il

19 - Multimedialità.p65 19/12/2003, 9.36440

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. Lalarghezza e l’altezza dell’applet sono determinate con i metodi getWidth e getHeight (eredi-tati dalla classe Component).

La riga 28 usa il metodo paintIcon di ImageIcon per visualizzare l’immagine. Il meto-do richiede quattro argomenti: un riferimento al Component sul quale l’immagine verràvisualizzata, un riferimento all’oggetto Graphics che verrà utilizzato per rappresentare l’im-magine sullo schermo, la coordinata x dell’angolo superiore sinistro dell’immagine, e la coor-dinata y dell’angolo superiore sinistro dell’immagine.

Se confrontate i due modi in cui abbiamo caricato e visualizzato le immagini in questoesempio, vedrete che l’impiego di ImageIcon è più semplice. È possibile creare oggetti dellaclasse ImageIcon direttamente, senza alcun bisogno di usare un riferimento ImageObserverdurante la visualizzazione dell’immagine. È questo il motivo per cui utilizzeremo la classeImageIcon per tutto il resto del capitolo. [Nota: Il metodo paintIcon della classe ImageIconnon permette di scalare un’immagine. Questa classe, però, fornisce il metodo getImage, cheritorna un riferimento Image da utilizzare con il metodo drawImage di Graphics per visualizzareun’immagine scalata.]

8.3 Animare una sequenza di immaginiIl prossimo esempio mostra l’animazione di una sequenza di immagini che sono conservateall’interno di un array di ImageIcon. L’animazione presentata nella figura 8.2 è stata proget-tata come una sottoclasse di JPanel (chiamata LogoAnimator), che può essere attaccata auna finestra di applicazione, oppure a un JApplet. La classe LogoAnimator definisce inoltreun metodo main (righe 85-99) per eseguire l’animazione sotto forma di applicazione. Il me-todo main definisce un’istanza della classe JFrame, aggiungendo un oggetto LogoAnimatoral 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

immagine10 protected ImageIcon images[]; // array di immagini1112 private int totalImages = 30; // numero di immagini13 private int currentImage = 0; // indice corrente di immagine14 private int animationDelay = 50; // ritardo in millisecondi15 private int width; // larghezza dell’immagine16 private int height; // altezza dell’immagine1718 private Timer animationTimer; // Timer che controlla l’animazione19

Figura 8.2 L’animazione di una sequenza di immagini (continua)

19 - Multimedialità.p65 19/12/2003, 9.36441

442 CAPITOLO 8

20 // inizializza LogoAnimator caricando le immagini21 public LogoAnimator()22 {23 images = new ImageIcon[ totalImages ];2425 // carica immagini26 for ( int count = 0; count < images.length; ++count )27 images[ count ] = new ImageIcon( getClass().getResource(28 “images/” + IMAGE_NAME + count + “.gif” ) );2930 // questo esempio assume che le immagini abbiano le stesse

dimensioni31 width = images[ 0 ].getIconWidth(); // ottiene larghezza icona32 height = images[ 0 ].getIconHeight(); // ottiene altezza icona33 }3435 // visualizza immagine corrente36 public void paintComponent( Graphics g )37 {38 super.paintComponent( g );3940 images[ currentImage ].paintIcon( this, g, 0, 0 );4142 // si sposta alla prossima immagine solo se il timer è partito43 if ( animationTimer.isRunning() )44 currentImage = ( currentImage + 1 ) % totalImages;45 }4647 // risponde a eventi del timer48 public void actionPerformed( ActionEvent actionEvent )49 {50 repaint(); // ridisegna animator51 }5253 // fa partire o ripartire l’animazione54 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 visualizzata62 if ( ! animationTimer.isRunning() )63 animationTimer.restart();64 }6566 // ferma timer dell’animazione67 public void stopAnimation()

Figura 8.2 L’animazione di una sequenza di immagini (continua)

19 - Multimedialità.p65 19/12/2003, 9.36442

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 443

68 {69 animationTimer.stop();70 }7172 // ritorna la dimensione minima di animation73 public Dimension getMinimumSize()74 {75 return getPreferredSize();76 }7778 // ritorna la dimensione preferenziale di animation79 public Dimension getPreferredSize()80 {81 return new Dimension( width, height );82 }8384 // esegue animation in un JFrame85 public static void main( String args[] )86 {87 LogoAnimator animation = new LogoAnimator(); // crea LogoAnimator8889 JFrame window = new JFrame( “Animator test” ); // imposta finestra90 window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );9192 Container container = window.getContentPane();93 container.add( animation );9495 window.pack(); // rende la finestra abbastanza larga

per la sua GUI96 window.setVisible( true ); // visualizza finestra97 animation.startAnimation(); // inizia animazione9899 } // fine metodo main100101 } // 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 immaginidell’animazione. L’argomento del costruttore usa la concatenazione delle stringhe per assemblareil nome del file dai vari pezzi “images/”, IMAGE_NAME, count e “.gif”. Ognuna delleimmagini dell’animazione è un file chiamato “deitel#.gif”, dove # è un valore 0-29 speci-ficato dalla variabile di controllo del ciclo count. Le righe 31-32 determinano la larghezza e

19 - Multimedialità.p65 19/12/2003, 9.36443

444 CAPITOLO 8

l’altezza dell’animazione dalle dimensioni della prima immagine nell’array images. Assume-remo che tutte le immagini abbiano la stessa larghezza e altezza.

Dopo che il costruttore di LogoAnimator ha caricato le immagini, il metodo mainimposta la finestra in cui apparirà l’animazione (righe 89-96) e la riga 97 chiama il metodostartAnimation della classe LogoAnimator (definito alle righe 54-64) per dare inizioall’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 fissatoin millisecondi (normalmente specificato come argomento del costruttore di Timer) enotifica dell’evento tutti i suoi ActionListener registrati. Le righe 56-60 determinano seil riferimento animationTimer di tipo Timer è null. In caso affermativo, currentImageè impostato su 0 (riga 57), per indicare che l’animazione dovrebbe iniziare con l’immagineche si trova nel primo elemento dell’array images. La riga 58 assegna un nuovo oggettoTimer 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’ActionListenerche 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; unavolta avviato, animationTimer genererà un ActionEvent ogni 50 millisecondi. Le righe62-63 permettono al programma di interrompere e riavviare l’animazione. Per ottimizzareun’animazione all’interno di un applet, per esempio, questa dovrebbe essere interrotta quandol’utente passa a un’altra pagina Web. Se l’utente ritorna alla pagina Web contenente l’ani-mazione, il metodo startAnimation può essere chiamato per riavviarla. La condizioneif alla riga 62 usa il metodo isRunning di Timer per determinare se Timer è attualmentein esecuzione (ovvero, se sta generando degli eventi). Se non è in esecuzione, la riga 63chiama il metodo restart di Timer per indicare che Timer dovrebbe ricominciare a ge-nerare eventi.

In risposta a ognuno degli eventi di Timer di questo esempio, il programma chiama ilmetodo actionPerformed (righe 48-51). La riga 50 chiama il metodo repaint di LogoAnimatorche programma una chiamata al metodo paintComponent di LogoAnimator (righe 36-45).Ricordate che qualsiasi sottoclasse di JComponent che esegue dei disegni deve farlo nel suometodo paintComponent. Come visto nel capitolo 3, la prima istruzione di qualsiasi metodopaintComponent 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. Lerighe 43-44 determinano se animationTimer è in esecuzione e, in caso affermativo, si prepa-rano a visualizzare l’immagine successiva aumentando di 1 currentImage. Notate il calcolodel resto per impostare il valore di currentImage su 0 quando si supera il valore 29 (l’ultimoelemento dell’array). L’istruzione if ci assicura che, se paintComponent viene chiamato quandoTimer viene fermato, verrà visualizzata la stessa immagine. Questo potrebbe essere utile inuna GUI che consente all’utente di far partire e fermare l’animazione. Per esempio, se l’ani-mazione viene fermata e l’utente la “copre” con un’altra finestra e poi la “scopre” nuovamen-te, verrà chiamato il metodo paintComponent. In questo caso, non vogliamo che l’animazio-ne mostri l’immagine successiva.

Il metodo stopAnimation (righe 67-70) interrompe l’animazione chiamando il metodostop della classe Timer per indicare che il Timer dovrebbe interrompere la generazione dieventi. Questo fatto, a sua volta, impedisce ad actionPerformed di chiamare repaint peravviare la visualizzazione dell’immagine successiva all’interno dell’array.

19 - Multimedialità.p65 19/12/2003, 9.36444

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 forni-re un meccanismo che la disattivi quando l’utente passa a una pagina Web diversa dallapagina in cui si trova l’animazione.

I metodi getMinimumSize (righe 73-76) e getPreferredSize (righe 79-82) sovrascrivonoi corrispondenti metodi ereditati dalla classe Component per aiutare il layout manager a de-terminare la corretta dimensione di un LogoAnimator all’interno di un layout. In questoesempio, le immagini sono larghe 160 pixel e alte 80 pixel, quindi il metodo getPreferredSizeritorna un oggetto Dimension contenente i numeri 160 e 80. Il metodo getMinimumSizechiama semplicemente getPreferredSize (una normale abitudine di programmazione) perindicare che la dimensione minima e quella preferenziale sono uguali. Alcuni layout managerignorano le dimensioni specificate da questi metodi. Per esempio, le regioni NORTH e SOUTHdi BorderLayout usano solo l’altezza preferenziale di un componente.

8.4 Mappe di immaginiUna tecnica molto comune per creare pagine Web interattive è il ricorso alle mappe di imma-gini. 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’in-terno 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 tooltip.

La figura 8.3 carica un’immagine contenente varie icone utilizzate all’interno del libro. Ilprogramma permette all’utente di posizionare il puntatore del mouse su di un’icona, visualizzandoun 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 è statoposizionato il mouse quando è stato chiamato il metodo mouseMoved; il metodo ritornaquindi un messaggio che indica ciò che l’icona rappresenta; questo messaggio viene visualizzatonella barra di stato del contenitore dell’applet.

Facendo clic all’interno dell’applet della figura 8.3, non viene eseguita alcuna azione. Nelcapitolo 7, abbiamo parlato delle tecniche necessarie per caricare un’altra pagina Web all’in-terno di un browser usando oggetti URL e l’interfaccia AppletContext. Usando queste tecni-che, è possibile modificare quest’applet affinché ogni icona sia associata a un URL diversoche 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)

19 - Multimedialità.p65 19/12/2003, 9.36445

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” };1415 // imposta ascoltatori del mouse16 public void init()17 {18 addMouseListener(1920 new MouseAdapter() { // classe interna anonima2122 // indica quando il puntatore del mouse esce dall’area

dell’applet23 public void mouseExited( MouseEvent event )24 {25 showStatus( “Pointer outside applet” );26 }2728 } // fine classe interna anonima2930 ); // fine chiamata a addMouseListener3132 addMouseMotionListener(3334 new MouseMotionAdapter() { // classe interna anonima3536 // determina l’icona su cui il mouse è posizionato37 public void mouseMoved( MouseEvent event )38 {39 showStatus( translateLocation(40 event.getX(), event.getY() ) );41 }4243 } // fine classe interna anonima4445 ); // fine chiamata a addMouseMotionListener4647 mapImage = new ImageIcon( “icons.png” ); // ottiene immagine4849 } // fine metodo init5051 // visualizza mapImage52 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)

19 - Multimedialità.p65 19/12/2003, 9.36446

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 447

5758 // ritorna testo descrittivo associato con l’icona59 public String translateLocation( int x, int y )60 {61 // se le coordinate sono fuori dall’immagine, ritorna

immediatamente62 if ( x >= mapImage.getIconWidth() || y >=

mapImage.getIconHeight() )63 return “”;6465 // determina il numero dell’icona (0 - 6)66 int iconWidth = mapImage.getIconWidth() / 7;67 int iconNumber = x / iconWidth;6869 return captions[ iconNumber ]; // ritorna testo appropriato70 }7172 } // fine classe ImageMap

Figura 8.3 Una mappa di immagini (continua)

19 - Multimedialità.p65 19/12/2003, 9.36447

448 CAPITOLO 8

Figura 8.3 Una mappa di immagini

8.5 Caricare e riprodurre i clip audioI programmi Java sono in grado di utilizzare e riprodurre i clip audio, che Internet offre ingrande abbondanza. Per poter riprodurre questi clip audio, il sistema deve disporre dell’appo-sito hardware (altoparlanti e una scheda audio).

Java offre diversi meccanismi per la riproduzione dei suoni all’interno di un applet. I duepiù 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 diApplet permette di caricare questo suono e di riprodurlo una sola volta, dopodiché il suonoviene 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 posizionelocation, e ne riproduce il suono. Il primo argomento è normalmente una chiamata al

19 - Multimedialità.p65 19/12/2003, 9.36448

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 449

metodo getDocumentBase o getCodeBase dell’applet. Il metodo getDocumentBase ritor-na la posizione del file HTML che ha caricato l’applet (se l’applet è in un package, il metodoritorna la posizione del package o del file JAR che contiene il package). Il metodo getCodeBaseindica 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 InstrumentDigital Interface (MIDI) (.mid o .rmi). Le librerie Java Media Framework (JMF) e JavaSound 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 poterloriutilizzare più volte durante l’esecuzione. Il metodo getAudioClip di Applet ha due forme,che prendono gli stessi argomenti del metodo play visto poco fa. Il metodo getAudioClipritorna un riferimento a un AudioClip; una volta caricato un AudioClip, è possibile invoca-re tre metodi: play, loop e stop. Il metodo play riproduce il clip una volta; il metodo loopriproduce il clip in continuazione; il metodo stop interrompe la riproduzione di un clip. Nelprogramma, 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;1314 // carica il suono quando l’applet inizia l’esecuzione15 public void init()16 {17 Container container = getContentPane();18 container.setLayout( new FlowLayout() );1920 String choices[] = { “Welcome”, “Hi” };21 chooseSound = new JComboBox( choices );2223 chooseSound.addItemListener(2425 new ItemListener() {

Figura 8.4 Caricare e riprodurre un AudioClip (continua)

19 - Multimedialità.p65 19/12/2003, 9.36449

450 CAPITOLO 8

2627 // ferma il suono e imposta il suono sulla selezione

dell’utente28 public void itemStateChanged( ItemEvent e )29 {30 currentSound.stop();3132 currentSound =33 chooseSound.getSelectedIndex() == 0 ? sound1 : sound2;34 }3536 } // fine classe interna anonima3738 ); // fine chiamata a addItemListener3940 container.add( chooseSound );4142 // imposta i pulsanti e il loro gestore degli eventi43 ButtonHandler handler = new ButtonHandler();4445 playSound = new JButton( “Play” );46 playSound.addActionListener( handler );47 container.add( playSound );4849 loopSound = new JButton( “Loop” );50 loopSound.addActionListener( handler );51 container.add( loopSound );5253 stopSound = new JButton( “Stop” );54 stopSound.addActionListener( handler );55 container.add( stopSound );5657 // carica suoni e imposta currentSound58 sound1 = getAudioClip( getDocumentBase(), “welcome.wav” );59 sound2 = getAudioClip( getDocumentBase(), “hi.au” );60 currentSound = sound1;6162 } // fine metodo init6364 // ferma il suono quando l’utente carica un’altra pagina Web65 public void stop()66 {67 currentSound.stop();68 }6970 // classe interna privata per gestire eventi dei pulsanti71 private class ButtonHandler implements ActionListener {7273 // elabora eventi dei pulsanti play, loop e stop

Figura 8.4 Caricare e riprodurre un AudioClip (continua)

19 - Multimedialità.p65 19/12/2003, 9.36450

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();7879 else if ( actionEvent.getSource() == loopSound )80 currentSound.loop();8182 else if ( actionEvent.getSource() == stopSound )83 currentSound.stop();84 }8586 } // fine classe ButtonHandler8788 } // 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ò selezionarequale clip audio riprodurre dal JComboBox chooseSound. Notate come il metodo stopdell’applet venga sovrascritto alle righe 65-68. Quando l’utente cambia pagina Web, vienechiamato il metodo stop; questo garantisce che la riproduzione del clip audio venga interrot-ta, 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 sempreall’utente un meccanismo per disabilitare l’audio.

8.6 Risorse in Internet e World Wide Webwww.nasa.gov/gallery/index.html

La galleria multimediale della NASA contiene un’ampia varietà di immagini, clip audio evideo che possono essere scaricati e utilizzati per testare i propri programmi Java di tipomultimediale.

sunsite.sut.ac.jp/multimed/

Il sito Web Sunsite Japan Multimedia Collection fornisce un’ampia varietà di immagini, clipaudio e video che possono essere scaricati e utilizzati a scopi educativi.

www.anbg.gov.au/anbg/index.html

19 - Multimedialità.p65 19/12/2003, 9.36451

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 GUISwing

Riferimenti alle librerie Java Multimediajava.sun.com/products/java-media/jmf/

Home page di Java Media Framework (JMF) API. Qui potete scaricare l’ultima implementazionedel 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/

19 - Multimedialità.p65 19/12/2003, 9.36452

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 ilcaricamento e il salvataggio di formati di immagini che non sono attualmente supportatidalle 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 simula-zione di ascensore. Ora che abbiamo completato la progettazione del modello, ci occupiamodella 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 oggettoPerson, un oggetto Button, ecc.). La classe ElevatorView è la classe più grande nel caso distudio. 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 classedel nostro modello individuando sostantivi e frasi dalla specifica del problema. Abbiamoignorato 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 modelloMVC. Come descritto nella sezione 2.7, la classe ElevatorView aggrega diverse classi. Ilsostantivo “audio” si riferisce agli effetti sonori che la nostra simulazione genera quandoaccadono varie azioni; creeremo la classe SoundEffects per generare tali effetti sonori. Lafrase “musica dell’ascensore” si riferisce alla musica che viene riprodotta quando una personaviaggia sull’ascensore; useremo la classe SoundEffects anche per riprodurre questa musica.

La vista visualizza gli oggetti del modello MVC. Creeremo la classe ImagePanel perrappresentare gli oggetti stazionari del modello, come ElevatorShaft. Creeremo la classeMovingPanel, che estende ImagePanel, per rappresentare gli oggetti in movimento, comeElevator. Infine, creeremo la classe AnimatedPanel, che estende MovingPanel, per rappre-sentare gli oggetti in movimento la cui immagine corrispondente cambia continuamente,come Person (useremo diverse immagini per mostrare la persona che cammina e preme unpulsante). Usando queste classi, presentiamo il diagramma di classe della vista per la nostrasimulazione 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 AnimatedPanelsi riferiscono alla grafica e la classe SoundEffects si riferisce ai suoni. La classe ElevatorViewcontiene diverse istanze delle classi ImagePanel, MovingPanel e AnimatedPanel e un’istan-za della classe SoundEffects. Nella versione finale del caso di studio, assoceremo ogni ogget-to del modello con una classe corrispondente nella vista.

19 - Multimedialità.p65 19/12/2003, 9.36453

454 CAPITOLO 8

In questa sezione, discutiamo le classi ImagePanel, MovingPanel e AnimatedPanel perspiegare la grafica e le animazioni. Poi, discuteremo la classe SoundEffects per spiegare lefunzionalità audio.

ImagePanelLa classe ElevatorView usa oggetti di sottoclassi di JPanel per rappresentare e visualizzareogni 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 delloschermo. La classe ElevatorView usa oggetti ImagePanel per rappresentare oggetti immo-bili nel modello, come ElevatorShaft e i due Floor. La classe ImagePanel contiene unattributo intero, ID (riga 16), che dichiara un identificatore unico per tenere tracciadell’ImagePanel nella vista. Ciò è utile quando diversi oggetti della stessa classe sono presen-ti nel modello, come diversi oggetti Person. La classe ImagePanel contiene l’oggetto positiondella classe Point2D.Double (riga 19) per rappresentare la sua posizione sullo schermo. Ve-dremo più avanti che MovingPanel, che estende ImagePanel, dichiara la velocità con valoridouble. Convertiremo le coordinate position in valori int per posizionare l’oggetto ImagePanelsullo schermo (Java rappresenta le coordinate dello schermo come interi) nel metodosetPosition (righe 90-94). La classe ImagePanel contiene anche un oggetto ImageIconchiamato imageIcon (riga 22), il cui metodo paintComponent (righe 54-60) visualizza l’iconasullo schermo. Le righe 41-42 inizializzano ImageIcon usando un parametro stringa checontiene il nome dell’immagine. Infine, la classe ImagePanel contiene l’oggetto panelChildrendella classe Set (riga 25) che memorizza tutti gli oggetti JPanel figli (o oggetti di una sottoclassedi JPanel). Gli oggetti figli vengono visualizzati sopra il loro ImagePanel genitore: peresempio, un oggetto Person dentro un Elevator. Il primo metodo add (righe 63-67) ag-giunge un oggetto a panelChildren. Il secondo metodo add (righe 70-74) inserisce unoggetto in panelChildren all’indice specificato. Il metodo setIcon (righe 84-87) impostaimageIcon con una nuova immagine. Gli oggetti della classe AnimatedPanel usano

ElevatorView

1

MovingPanel

AnimatedPanel

1

SoundEffects

11..*

1..* 1

Grafica

Audio

Vista

ImagePanel

1

1..*javax.swing.JPanel

Figura 8.5 Diagramma di classe della vista del simulatore di ascensore

19 - Multimedialità.p65 19/12/2003, 9.36454

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 455

ripetutamente il metodo setIcon per cambiare l’immagine visualizzata, in modo da eseguirel’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.*; 910 // package Java di estensione11 import javax.swing.*;1213 public class ImagePanel extends JPanel {1415 // identificatore16 private int ID;1718 // posizione sullo schermo19 private Point2D.Double position;2021 // imageIcon da disegnare sullo schermo22 private ImageIcon imageIcon;2324 // memorizza tutti i figli di ImagePanel25 private Set panelChildren;2627 // costruttore che inizializza posizione e immagine28 public ImagePanel( int identifier, String imageName )29 {30 super( null ); // specifica layout null31 setOpaque( false ); // rende trasparente3233 // imposta identificatore unico34 ID = identifier;3536 // imposta posizione37 position = new Point2D.Double( 0, 0 );38 setLocation( 0, 0 );3940 // crea ImageIcon con imageName dato41 imageIcon = new ImageIcon(42 getClass().getResource( imageName ) );4344 Image image = imageIcon.getImage();

Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobiledel modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36455

456 CAPITOLO 8

45 setSize(46 image.getWidth( this ), image.getHeight( this ) );4748 // crea Set per memorizzare i figli di Panel49 panelChildren = new HashSet();5051 } // fine costruttore di ImagePanel5253 // disegna Panel sullo schermo54 public void paintComponent( Graphics g )55 {56 super.paintComponent( g );5758 // se l’immagine e’ pronta, disegnala sullo schermo59 imageIcon.paintIcon( this, g, 0, 0 );60 }6162 // aggiunge figlio di ImagePanel a ImagePanel63 public void add( ImagePanel panel )64 {65 panelChildren.add( panel );66 super.add( panel );67 }6869 // aggiunge figlio di ImagePanel a ImagePanel all’indice dato70 public void add( ImagePanel panel, int index )71 {72 panelChildren.add( panel );73 super.add( panel, index );74 }7576 // rimuove figlio di ImagePanel da ImagePanel77 public void remove( ImagePanel panel )78 {79 panelChildren.remove( panel );80 super.remove( panel );81 }8283 // imposta ImageIcon corrente da visualizzare84 public void setIcon( ImageIcon icon )85 {86 imageIcon = icon;87 }8889 // imposta posizione sullo schermo90 public void setPosition( double x, double y )91 {92 position.setLocation( x, y );

Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobiledel modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36456

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 457

93 setLocation( ( int ) x, ( int ) y );94 }9596 // ritorna identificatore di ImagePanel97 public int getID()98 {99 return ID;100 }101102 // ottiene posizione di ImagePanel103 public Point2D.Double getPosition()104 {105 return position;106 }107108 // ottiene imageIcon109 public ImageIcon getImageIcon()110 {111 return imageIcon;112 }113114 // ottiene Set di figli di ImagePanel115 public Set getChildren()116 {117 return panelChildren;118 }119 }

Figura 8.6 La classe ImagePanel rappresenta e visualizza un oggetto immobiledel modello

MovingPanelLa classe MovingPanel (figura 8.7) è una sottoclasse di ImagePanel in grado di cambiare lasua posizione sullo schermo in base ai valori xVelocity e yVelocity (righe 20-21). La classeElevatorView usa oggetti MovingPanel per rappresentare oggetti mobili del modello, comeElevator.

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.*; 910 // package Java di estensione

Figura 8.7 La classe MovingPanel rappresenta e visualizza un oggetto che si muovedal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36457

458 CAPITOLO 8

11 import javax.swing.*;1213 public class MovingPanel extends ImagePanel {1415 // MovingPanel dovrebbe cambiare posizione?16 private boolean moving;1718 // numero di pixel di cui MovingPanel si muove nelle direzioni

x e y19 // per animationDelay millisecondi20 private double xVelocity;21 private double yVelocity;2223 // costruttore che inizializza posizione, velocità e immagine24 public MovingPanel( int identifier, String imageName )25 {26 super( identifier, imageName );2728 // imposta velocità di MovingPanel29 xVelocity = 0;30 yVelocity = 0;3132 } // fine costruttore di MovingPanel3334 // aggiorna posizione e animazione di MovingPanel35 public void animate()36 {37 // aggiorna posizione a seconda della velocità38 if ( isMoving() ) {39 double oldXPosition = getPosition().getX();40 double oldYPosition = getPosition().getY();4142 setPosition( oldXPosition + xVelocity,43 oldYPosition + yVelocity );44 }4546 // aggiorna tutti i figli di MovingPanel47 Iterator iterator = getChildren().iterator();4849 while ( iterator.hasNext() ) {50 MovingPanel panel = ( MovingPanel ) iterator.next();51 panel.animate();52 }53 } // fine metodo animate5455 // 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 muovedal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36458

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 459

6061 // imposta MovingPanel per muoversi sullo schermo62 public void setMoving( boolean move )63 {64 moving = move;65 }6667 // imposta le velocità x e y di MovingPanel68 public void setVelocity( double x, double y )69 {70 xVelocity = x;71 yVelocity = y;72 }7374 // ritorna velocità x di MovingPanel75 public double getXVelocity()76 {77 return xVelocity;78 }7980 // ritorna velocità y di MovingPanel81 public double getYVelocity()82 {83 return yVelocity;84 }85 }

Figura 8.7 La classe MovingPanel rappresenta e visualizza un oggetto che si muovedal modello

Il metodo animate (righe 35-53) muove MovingPanel secondo i valori attuali dei campixVelocity e yVelocity. Se la variabile boolean moving (riga 16) è true, le righe 38-44usano 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, ElevatorViewinvoca il metodo animate e il metodo paintComponent della classe ImagePanel ogni 50millisecondi. Queste chiamate in rapida successione spostano l’oggetto MovingPanel.

AnimatedPanelLa classe AnimatedPanel (figura 8.8), che estende la classe MovingPanel, rappresenta unoggetto animato del modello (cioè, oggetti in movimento la cui immagine corrispondentecambia continuamente), come Person. La classe ElevatorView anima un AnimatedPanelcambiando 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 animatodal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36459

460 CAPITOLO 8

5 // package Java di base 6 import java.awt.*; 7 import java.util.*; 8 9 // package Java di estensione10 import javax.swing.*;1112 public class AnimatedPanel extends MovingPanel {1314 // ImageIcon deve essere animato?15 private boolean animating;1617 // frequenza di cambio immagine18 private int animationRate;19 private int animationRateCounter;20 private boolean cycleForward = true;2122 // ImageIcon individuali usati per l’animazione23 private ImageIcon imageIcons[];2425 // memorizza tutte le sequenze di frame26 private java.util.List frameSequences;27 private int currentAnimation;2829 // deve continuare l’animazione alla fine del ciclo?30 private boolean loop;3132 // deve visualizzare l’ultima immagine alla fine dell’animazione?33 private boolean displayLastFrame;3435 // determina la prossima immagine da visualizzare36 private int currentFrameCounter;3738 // costruttore che prende un array di nomi di file39 public AnimatedPanel( int identifier, String imageName[] )40 {41 super( identifier, imageName[0] );4243 // crea oggetti ImageIcon dall’array di stringhe imageName44 imageIcons = new ImageIcon[ imageName.length ];4546 for ( int i = 0; i < imageIcons.length; i++ ) {47 imageIcons[i] = new ImageIcon(48 getClass().getResource( imageName[i] ) );49 }5051 frameSequences = new ArrayList();5253 } // fine costruttore di AnimatedPanel54

Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animatodal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36460

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 461

55 // aggiorna posizione dell’icona e immagine dell’animazione56 public void animate()57 {58 super.animate();5960 // visualizza la prossima immagine se counter > frequenza

di animazione61 if ( frameSequences != null && isAnimating() ) {6263 if ( animationRateCounter > animationRate ) {64 animationRateCounter = 0;65 determineNextFrame();66 }67 else68 animationRateCounter++;69 }70 } // fine metodo animate7172 // determina prossima immagine dell’animazione73 private void determineNextFrame()74 {75 int frameSequence[] =76 ( int[] ) frameSequences.get( currentAnimation );7778 // se non ci sono più immagini, determina immagine finale79 // a meno che non si debba ripetere l’animazione80 if ( currentFrameCounter >= frameSequence.length ) {81 currentFrameCounter = 0;8283 // se loop è false, termina animazione84 if ( !isLoop() ) {8586 setAnimating( false );8788 if ( isDisplayLastFrame() )8990 // visualizza ultima immagine della sequenza91 currentFrameCounter = frameSequence.length - 1;92 }93 }9495 // imposta immagine corrente dell’animazione96 setCurrentFrame( frameSequence[ currentFrameCounter ] );97 currentFrameCounter++;9899 } // fine metodo determineNextFrame100101 // aggiunge animazione all’ ArrayList frameSequences

Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animatodal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36461

462 CAPITOLO 8

102 public void addFrameSequence( int frameSequence[] )103 {104 frameSequences.add( frameSequence );105 }106107 // chiede se AnimatedPanel sta eseguendo l’animazione108 public boolean isAnimating()109 {110 return animating;111 }112113 // imposta AnimatedPanel per eseguire l’animazione114 public void setAnimating( boolean animate )115 {116 animating = animate;117 }118119 // imposta ImageIcon corrente120 public void setCurrentFrame( int frame )121 {122 setIcon( imageIcons[ frame ] );123 }124125 // imposta frequenza di animazione126 public void setAnimationRate( int rate )127 {128 animationRate = rate;129 }130131 // ottiene frequenza di animazione132 public int getAnimationRate()133 {134 return animationRate;135 }136137 // imposta se l’animazione deve ripetersi138 public void setLoop( boolean loopAnimation )139 {140 loop = loopAnimation;141 }142143 // ottiene se l’animazione deve ripetersi144 public boolean isLoop()145 {146 return loop;147 }148

Figura 8.8 La classe AnimatedPanel rappresenta e visualizza un oggetto animatodal modello (continua)

19 - Multimedialità.p65 19/12/2003, 9.36462

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 }154155 // imposta se visualizzare l’ultima immagine alla fine

dell’animazione156 public void setDisplayLastFrame( boolean displayFrame )157 {158 displayLastFrame = displayFrame;159 }160161 // inizia ad eseguire la sequenza di animazione all’indice dato162 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 animatodal modello

La classe AnimatedPanel sceglie un oggetto ImageIcon da disegnare sullo schermo tradiversi oggetti ImageIcon memorizzati nell’array imageIcons (riga 23). La classe AnimatedPaneldetermina l’oggetto ImageIcon secondo una sequenza di riferimenti, memorizzata nella listaframeSequences (riga 26), che è un array di interi che memorizza la sequenza appropriataper visualizzare gli oggetti ImageIcon: in particolare, ogni intero rappresenta l’indice di unoggetto ImageIcon nell’array imageIcons. La figura 8.9 mostra la relazione tra imageIconse 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 sequenzadi immagini { C, B, A }. Nella vista, ogni immagine è un file .png unico. Il metodo

0 1 2

0 1 3 1 0

2 1 0

3 2 2 0

0=

1=

2=

3=

frameSequences

A D

B

C

0 1 2 3

imageIcons A

B

C

A B B A D

C B A

D C C A

image sequences

Figura 8.9 Relazione tra l’array imageIcons e la lista FrameSequences

19 - Multimedialità.p65 19/12/2003, 9.36463

464 CAPITOLO 8

addFrameSequences (righe 102-105) aggiunge una sequenza di animazione alla listaframeSequences. Il metodo playAnimation (righe 162-167) fa partire l’animazione asso-ciata con il parametro frameSequences. Per esempio, supponiamo di avere un oggettoAnimatedPanel chiamato personAnimatedPanel nella classe ElevatorView. Il frammen-to di codice

animatedPanel.playAnimation( 1 );

genererebbe la sequenza di immagini { A, B, D, B, A } se usiamo la figura 8.9 comeriferimento.

Il metodo animate (righe 56-70) sovrascrive il metodo animate della superclasseMovingPanel. Le righe 61-69 determinano la successiva immagine per l’animazione a secon-da del campo animationRate, che è inversamente proporzionale alla velocità dell’animazio-ne: un valore più alto per animationRate comporta un’animazione più lenta. Per esempio,se animationRate vale 5, animate si sposta alla successiva immagine dell’animazione ognicinque volte viene invocato. Usando questa logica, la frequenza di animazione viene massimizzataquando animationRate ha un valore 1, perché la successiva immagine viene determinataogni volta che viene chiamato animate.

Il metodo animate chiama determineNextFrame (righe 73-99) per determinare la suc-cessiva immagine da visualizzare: in particolare, viene chiamato il metodo setCurrentFrame(righe 120-123) che imposta imageIcon (l’immagine correntemente visualizzata) all’imma-gine ritornata dalla corrente sequenza di animazione. Le righe 84-92 di determineNextFramevengono usate per ripetere l’animazione. Se loop vale false, l’animazione termina dopo unaiterazione. L’ultima immagine della sequenza viene visualizzata se displayLastFrame valetrue, e, se vale false, viene visualizzata la prima immagine della sequenza. Se loop valetrue, l’animazione si ripete finché non viene fermata esplicitamente.

Effetti sonoriVediamo ora come generare dei suoni nella nostra simulazione. La classe SoundEffects(figura 8.10) trasforma file audio (.au), wave (.wav) e MIDI (.mid) contenenti suoni comeil campanello, i passi della persona e la musica dell’ascensore, in oggetti java.applet.AudioClip.L’oggetto ElevatorView riprodurrà gli oggetti AudioClip per generare i suoni. Tutti i filedei suoni sono nella struttura di directory

com/deitel/jhtp5/elevator/view/sounds

Nella nostra simulazione, useremo suoni e file MIDI disponibili gratuitamente al sito Web diMicrosoft:

msdn.microsoft.com/downloads/default.asp

Per scaricare questi suoni, fate clic su “Graphics and Multimedia”, “Multimedia (General)”, epoi “Sounds”.

La classe SoundEffects contiene i metodi getAudioClip (righe 16-27), che usa il me-todo statico newAudioClip (della classe java.applet.Applet) per ritornare un oggettoAudioClip usando il parametro soundFile. Il metodo setPathPrefix (righe 30-33) per-mette di cambiare directory del file audio (utile se vogliamo dividere i nostri file sonori tradirectory diverse).

19 - Multimedialità.p65 19/12/2003, 9.36464

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 465

1 // SoundEffects.java2 // Ritorna oggetti AudioClip3 package com.deitel.jhtp5.elevator.view;45 // package Java di base6 import java.applet.*;78 public class SoundEffects {910 // posizione dei file audio11 private String prefix = “”;1213 public SoundEffects() {}1415 // ottiene AudioClip associato con soundFile16 public AudioClip getAudioClip( String soundFile )17 {18 try {19 return Applet.newAudioClip( getClass().getResource(20 prefix + soundFile ) );21 }2223 // ritorna null se il file audio non esiste24 catch ( NullPointerException nullPointerException ) {25 return null;26 }27 }2829 // imposta prefisso per la posizione di soundFile30 public void setPathPrefix( String string )31 {32 prefix = string;33 }34 }

Figura 8.10 La classe SoundEffects ritorna oggetti AudioClip

ConclusioneAvete appena completato un procedimento di progettazione orientata agli oggetti che avevalo scopo di prepararvi per le sfide dei progetti di livello industriale. Speriamo che abbiatetrovato le sezioni “Pensare a oggetti” informative e utili come complemento al materialepresentato nei vari capitoli. Inoltre, speriamo vi siate divertiti a progettare il sistema usandoUML. Il linguaggio UML è stato adottato come standard dall’industria del software mondia-le per la modellazione di software orientato agli oggetti.

Anche se avete completato la fase di progettazione, avete solo sfiorato il processo diimplementazione. Consultate il sito Web www.apogeonline.com/libri/02097/allega-ti/ per la completa implementazione del progetto, e le traduzioni dei diagrammi UML inun programma Java completo per la simulazione dell’ascensore. Studiare l’implementazione

19 - Multimedialità.p65 19/12/2003, 9.36465

466 CAPITOLO 8

rafforzerà le abilità nella programmazione che avete sviluppato leggendo il libro e miglio-rerà la vostra comprensione del processo di progettazione.

Esercizi di autovalutazione

8.1 Completate le seguenti frasi:a) Il metodo ____________ di Applet carica un’immagine all’interno di un applet.b) Il metodo ____________ di Applet ritorna, come un oggetto della classe URL, la posizio-

ne in Internet del file HTML che ha invocato l’applet.c) Il metodo ____________ di Graphics visualizza un’immagine all’interno di un applet.d) Java fornisce due meccanismi per riprodurre suoni all’interno di un applet: il metodo play

di Applet e il metodo play dell’interfaccia ____________.e) Una ____________ è un’immagine che presenta delle aree attive, sulle quali l’utente può

fare clic per portare a termine un’attività, come per esempio il caricamento di una diversapagina Web.

f ) Il metodo ____________ della classe ImageIcon visualizza l’immagine di ImageIcon.g) Java supporta diversi formati di immagini, tra cui ____________, ____________ e

____________

8.2 Determinate se le seguenti affermazioni sono vere o false. Se sono false, spiegate il perché.a) Un suono viene eliminato quando ha finito di essere riprodotto.b) La classe ImageIcon fornisce dei costruttori che permettono ad un oggetto ImageIcon di

essere inizializzato solo con un’immagine dal computer locale.

Risposte agli esercizi di autovalutazione

8.1 a) getImage. b) getDocumentBase. c) drawImage. d) AudioClip. e) mappa di immagini. f )paintIcon. g) Graphics Interchange Format (GIF), Joint Photographic Experts Group (JPEG),Portable Network Graphics (PNG).

8.2 a) Falso. Il suono verrà contrassegnato per essere eliminato (se non è referenziato da un AudioClip)e verrà eliminato quando il garbage collector è in grado di essere eseguito.

b) Falso. ImageIcon può caricare anche immagini da Internet.

Esercizi

8.3 Spiegate come sia possibile rendere un’animazione “browser friendly”.

8.4 Descrivete i metodi Java per riprodurre e utilizzare i clip audio.

8.5 Spiegate l’utilizzo delle mappe di immagini. Elencate diverse applicazioni di mappe di imma-gini.

8.6 (Cancellazione casuale di un’immagine) Supponete che un’immagine venga visualizzata in un’arearettangolare dello schermo. Un modo per cancellare l’immagine è quello di impostare immediatamen-te ogni pixel sullo stesso colore, ma questo produce un effetto visivo noioso. Scrivete un programmaJava che visualizzi un’immagine e poi la cancelli, utilizzando la generazione casuale dei numeri perselezionare i singoli pixel da cancellare. Dopo che gran parte dell’immagine è stata cancellata, cancella-te tutti i pixel rimanenti in una sola volta. È possibile fare riferimento ai singoli pixel attraverso una rigache inizia e finisce allo stesso punto. Potete provare diverse varianti di questo problema. Per esempio,potreste visualizzare le righe in modo casuale, oppure potreste visualizzare le figure in modo casuale percancellare intere regioni dello schermo.

19 - Multimedialità.p65 19/12/2003, 9.36466

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 467

8.7 (Text Flasher) Create un programma Java che lampeggi ripetutamente del testo sullo schermo.Completate il testo con un’immagine di sfondo di un unico colore. Permettete all’utente di controllarela velocità di lampeggiamento e di scegliere il colore o il motivo di sfondo.

8.8 (Image Flasher) Create un programma Java che lampeggi ripetutamente un’immagine sulloschermo. Completate l’immagine con un’immagine di sfondo di un unico colore.

8.9 (Orologio digitale) Implementate un programma che visualizzi un orologio digitale sullo scher-mo. Potete aggiungere delle opzioni per mostrare il giorno, il mese e l’anno, inserire una funzione diallarme, riprodurre determinati suoni in momenti predefiniti, e così via.

8.10 (Richiamare l’attenzione su di un’immagine) Se volete enfatizzare un’immagine, potete posizio-nare intorno a questa immagine una fila di luci, che lampeggino all’unisono, oppure che si accendanouna dopo l’altra in sequenza.

8.11 (Zooming) Create un programma che permetta di eseguire lo zoom di un’immagine.

Sezione speciale: progetti multimediali avanzati

Gli esercizi precedenti servono a verificare la comprensione da parte del lettore dei concetti fondamen-tali del capitolo. Questa sezione contiene una collezione di progetti multimediali avanzati che il lettoredovrebbe trovare stimolanti e divertenti. La difficoltà dei problemi è considerevolmente varia. Alcunirichiedono un’ora o due di progettazione e implementazione. Altri sono utili come progetti di labora-torio che possono richiedere due o tre settimane di studio e implementazione.

8.12 (Animazione) Create un programma generico di animazione Java. Il programma dovrebbe per-mettere all’utente di specificare la sequenza di frame da visualizzare, la velocità con cui le immaginidevono essere visualizzate, i suoni da riprodurre mentre l’animazione è in esecuzione, e così via.

8.13 (Transizione casuale di un’immagine) Questo è un effetto visivo molto interessante. Se statevisualizzando un’immagine in una data area dello schermo, e volete passare a un’altra immagine nellastessa area dello schermo, memorizzate la nuova immagine in un buffer separato, e copiate in modocasuale i pixel della nuova immagine in modo da visualizzare l’area che copre i pixel che si trovavanoprecedentemente in quelle posizioni. Quando la maggior parte dei pixel sono stati copiati, copiatel’intera nuova immagine nell’area di visualizzazione, così da assicurarvi che state visualizzando la nuovaimmagine completa. Per implementare questo programma potrebbe essere necessario usare le classiPixelGrabber e MemoryImageSource (consultate la documentazione Java API per la descrizione diqueste classi). Potete provare diverse varianti di questo problema. Per esempio, potreste selezionaretutti i pixel in una riga selezionata a caso, oppure creare la nuova immagine e sovrapporre questi pixelalle posizioni corrispondenti nella vecchia immagine.

8.14 (Audio in sottofondo) Aggiungete dell’audio di sottofondo a una delle vostre applicazioni prefe-rite, utilizzando il metodo loop della classe AudioClip per riprodurre il suono di sottofondo mentreinteragite con l’applicazione in modo normale.

8.15 (Marquee scorrevole) Create un programma Java che faccia scorrere dei caratteri puntati dadestra verso sinistra (o da sinistra verso destra) all’interno di una fascia di tipo Marquee. Se volete,visualizzate il testo a ciclo continuo, così che quando il testo esce da una parte dello schermo riappaiadalla parte opposta.

8.16 (Immagine scorrevole) Create un programma Java che faccia scorrere un’immagine lungo unoschermo di tipo Marquee.

8.17 (Orologio analogico) Create un programma Java che visualizzi un orologio analogico con lelancette dell’ora, dei minuti e dei secondi. Le lancette si devono spostare in modo corretto in base alloscorrere del tempo.

19 - Multimedialità.p65 19/12/2003, 9.36467

468 CAPITOLO 8

8.18 (Caleidoscopio dinamico) Sviluppate un programma caleidoscopio che visualizzi delle immaginiche simulano il popolare giocattolo per bambini. Incorporate degli effetti sonori che corrispondanoalle immagini che variano in modo dinamico.

8.19 (Generatore di puzzle) Create un generatore di puzzle Java. L’utente specifica un’immagine, cheil programma carica e visualizza. Il programma poi suddivide l’immagine in tante forme selezionate inmodo casuale, e le mischia. L’utente usa il mouse per spostare i vari pezzi del puzzle, al fine di ricomporrel’immagine. Aggiungete i suoni appropriati via via che i pezzi vengono spostati e rimessi al loro posto.Potete tenere delle etichette su ogni pezzo con l’esatta posizione, e poi usare effetti sonori per aiutarel’utente a rimettere i pezzi nella corretta posizione.

8.20 (Generatore di labirinti) Sviluppate un generatore di labirinti multimediale e un programma diattraversamento del labirinto. Permettete all’utente di personalizzare il labirinto, specificando il nume-ro di righe e di colonne, e indicando il livello di difficoltà. Create un topolino animato che percorra illabirinto. Utilizzate l’audio per enfatizzare i movimenti del topolino.

8.21 (Slot machine) Sviluppate una simulazione multimediale di una slot machine. Create tre ruoteche girano, ognuna con disegni di frutti e di altri simboli. Utilizzate la generazione casuale dei numeriper simulare il giro di ogni ruota e la sua interruzione su uno dei simboli.

8.22 (Corsa dei cavalli) Create una simulazione Java di una corsa dei cavalli, con più partecipanti.Usate l’audio per simulare un annunciatore che descrive la gara e annuncia i risultati finali. Riproduce-te i suoni corretti, per indicare la posizione di ognuno dei concorrenti durante la gara. Provate asimulare il tipo di gare che si vedono spesso nelle feste di paese. I giocatori possono, a turno, fareavanzare il proprio cavallo con il mouse.

8.23 (Shuffleboard) Sviluppate una simulazione multimediale del gioco shuffleboard. [Nota: Questogioco, in origine americano, è spesso giocato a bordo delle navi di crociera, e consiste nello spingere,con apposite stecche, dei dischi di legno entro figure geometriche numerate.] Usate i corretti effettiaudio e video.

8.24 (Biliardo) Create una simulazione multimediale del gioco del biliardo. Ogni giocatore usa aturno il mouse, per posizionare la stecca e colpire la palla con la giusta angolazione, affinché finisca inuna delle buche. Il programma deve tenere aggiornati i punteggi.

8.25 (Artista) Progettate un programma Java che offra a un artista una grande quantità di funziona-lità per disegnare, utilizzare immagini, usare animazioni e così via, al fine di creare opere multimedialidinamiche.

8.26 (Fuochi d’artificio) Create un programma Java che possa essere utilizzato per creare uno spetta-colo di fuochi d’artificio. Create varie dimostrazioni e cercate di ottenere gli effetti più spettacolari.

8.27 (Arredatore) Sviluppate un programma Java che aiuti a disporre l’arredamento di una casa.Aggiungete delle caratteristiche che permettano di ottenere la migliore disposizione possibile.

8.28 (Parole crociate) Sviluppate un programma di parole crociate, che permetta al giocatore diinserire e cancellare le parole in modo semplice. Collegate il programma a un grande dizionario sucomputer. Il programma dovrebbe essere in grado di suggerire le parole in base alle lettere che sono giàstate inserite.

8.29 (Gioco del 15) Scrivete un programma Java multimediale che permetta all’utente di giocare ilgioco del 15. Il gioco si compone di una scacchiera 4 × 4, per un totale di 16 caselle. Una di questecaselle è vuota, mentre le altre sono occupate da 15 numeri (dall’1 al 15). Ogni casella vicina a quellavuota può essere spostata al posto di quella vuota facendovi clic. Il programma deve creare la scacchieracon le caselle in ordine sparso. L’obiettivo è quello di sistemare tutte le caselle in ordine sequenziale,riga per riga.

19 - Multimedialità.p65 19/12/2003, 9.36468

LA MULTIMEDIALITÀ: LE IMMAGINI, LE ANIMAZIONI E I SUONI 469

8.30 (Tempi di reazione) Create un programma Java che sposti una figura creata in modo casualeall’interno dello schermo. L’utente sposta il mouse per cercare di fermare la figura. La velocità e ladimensione della figura possono essere modificate. Producete delle statistiche circa il tempo tipica-mente impiegato dall’utente per catturare una figura di una data dimensione. L’utente avrà probabil-mente più difficoltà a catturare le figure veloci di piccole dimensioni.

8.31 (Calendario/Scadenziario) Create un calendario generico con uno scadenziario. Utilizzare suonie immagini. Per esempio, il programma dovrebbe suonare “Tanti Auguri” quando l’utente lo apre ilgiorno del suo compleanno. Il programma deve riprodurre immagini e suoni associati a eventi impor-tanti, e dovrebbe ricordare in anticipo questi eventi all’utente.

8.32 (Immagini rotanti) Create un programma Java che permetta di ruotare un’immagine per undeterminato numero di gradi (al massimo 360). Il programma deve permettere di specificare che l’im-magine dovrebbe ruotare in continuazione. Il programma deve permettere di regolare la velocità dirotazione in modo dinamico.

8.33 (Colorare immagini in bianco e nero) Create un programma Java che permetta di colorare delleimmagini in bianco e nero. Fornite una paletta di colori per la selezione dei colori. Il programma devepermettere di applicare colori diversi alle varie regioni di un’immagine.

8.34 (Simulatore Simpletron multimediale) Modificate il simulatore Simpletron sviluppato nel volu-me Tecniche di base, al fine di includervi delle funzionalità multimediali. Aggiungete suoni simili aquelli di un computer, per indicare che il Simpletron sta eseguendo le istruzioni. Aggiungete il suonodi un vetro che si rompe quando avviene un errore grave. Utilizzate delle luci lampeggianti per indicarequali celle della memoria e/o quali registri sono attualmente in uso. Usate anche altre tecniche multimedialiper rendere il simulatore più utile ai fini educativi.

19 - Multimedialità.p65 19/12/2003, 9.36469