Applet Un applet o un’applet? Introduzione Gli applet sono una tipologia di programmi Java che, a differenza delle applicazioni Java, sono realizzati non per essere eseguiti autonomamente, ma piuttosto per essere immersi in altre applicazioni. in particolare, gli applet possono essere immersi in pagine web ed eseguiti da browser web 2 Introduzione Un applet è un (piccolo) programma realizzato per essere immerso (ovvero, eseguito) nell’ambito di un’altra applicazione gli applet sono solitamente immersi nelle pagine web (nei documenti HTML) i principali browser web sono dotati di una macchina virtuale Java e sono in grado di eseguire applet se una pagina web contiene un applet, un’area della pagina è dedicata alla visualizzazione dell’applet Per realizzare applet è utile comprenderne le caratteristiche principali, ed in particolare l’interazione tra applet e i browser web che li eseguono 3 Un esempio import java.applet.Applet; import java.awt.Graphics; /** Applet che visualizza una frase. */ public class AppletScrittore extends Applet { public void paint(Graphics g) { g.drawString("Il mio primo applet", 25, 50); } } Questa è la definizione di un semplice applet che visualizza una frase (nell’area della pagina web dedicata alla sua visualizzazione) per realizzare un applet è necessario definire una classe che estende la classe Applet (del package java.applet) la classe che implementa un applet non contiene il metodo di classe void main(String[] args) (che va definito per le classi applicazioni) ma alcuni metodi d’istanza 4 La classe Applet In generale, un applet è un oggetto istanza di tipo Applet la classe Applet del package java.applet è un applet elementare, che apparentemente non fa nulla per realizzare un nuovo applet è necessario estendere la classe Applet per aggiungere comportamento all’applet elementare 5 La classe Applet In pratica, nella classe Applet sono definiti i metodi con cui i browser web (o meglio, le macchine virtuali Java di cui i browser web sono dotati) possono interagire con un applet, e che vanno eventualmente ridefiniti per descrivere che cosa deve fare l’applet ad esempio, quando un browser web deve eseguire un applet, per prima cosa istanzia l’applet e, prima o poi, gli chiede di eseguire il metodo paint(...) il metodo paint(...) viene invocato ed eseguito ogni volta che è necessario visualizzare o aggiornare l’area dedicata alla visualizzazione dell’applet questo avviene, ad esempio, nel momento in cui il browser web deve visualizzare l’applet per default, il metodo paint(...) (di Applet) non fa nulla tuttavia, è possibile ridefinire il comportamento del metodo paint(...) per far visualizzare qualcosa all’applet 6 La classe Applet 7 La classe Applet 8 La classe Applet 9 Applet e pagine web Come si interagisce con un applet? una pagina web può contenere un applet, se nella pagina è specificato, mediante un elemento APPLET, il nome della classe che definisce l’applet in questo caso, il browser web scarica il bytecode della classe che è stata specificata istanzia un nuovo oggetto da questa classe richiede a questo oggetto di eseguire alcuni metodi, in un modo che dipende da come l’utente del browser interagisce con il browser 10 Applet e pagine web Per indicare la presenza di un applet in una pagina web va usato l’elemento APPLET, come nel seguente esempio <HTML> <HEAD><TITLE>L'applet scrittore</TITLE></HEAD> <BODY> <APPLET CODE=“AppletScrittore.class” WIDTH=300 HEIGHT=100></APPLET> </BODY> </HTML> un ruolo fondamentale della pagina web che contiene un applet è quello di assegnare all’applet un’area rettangolare dedicata alla visualizzazione dell’applet in particolare, un elemento APPLET deve contenere almeno un attributo CODE che specifica il nome dell’applet gli attributi WIDTH e HEIGHT che specificano, rispettivamente, la larghezza e l’altezza dell’area dedicata all’applet 11 Il metodo Paint Gli oggetti istanza della classe Graphics (del package java.awt) modellano oggetti grafici, ovvero oggetti che sono in grado di eseguire operazioni di disegno normalmente, un oggetto Graphics è associato a un oggetto con capacità grafiche (come ad esempio a un applet) ed è chiamato un contesto grafico dell’oggetto a cui è associato Quando il browser richiede a un applet di eseguire il metodo void paint(Graphics g) gli passa come parametro il riferimento al contesto grafico g associato all’applet il metodo paint contiene normalmente istruzioni che richiedono a g di disegnare o di visualizzare stringhe, al fine di visualizzare lo stato corrente dell’applet 12 Il metodo Paint Al contesto grafico è associata un’area rettangolare: Y X 13 Metodi della classe Graphics Ecco alcuni metodi della classe Graphics void drawLine (int x1, int y1, int x2, int y2) void drawRect (int x, int y, int w, int h) disegna un rettangolo (pieno) con estremo in alto a sinistra nel punto (x, y), larghezza w e altezza h l’estremo in basso a destra del rettangolo avrà coordinate (x+w–1, y+h–1) void drawString (String s, int x, int y) disegna il contorno di un rettangolo con estremo in alto a sinistra nel punto (x, y), larghezza w+1 e altezza h+1 l’estremo in basso a destra del rettangolo avrà coordinate (x+w, y+h) void fillRect (int x, int y, int w, int h) disegna una linea tra i punti (x1, y1) e (x2, y2) visualizza la stringa s — la base (in basso a sinistra) della stringa è posta nel punto di coordinate (x, y) void drawOval (int x, int y, int w, int h) disegna il contorno di un ovale contenuto nel rettangolo con estremo in alto a sinistra nel punto (x, y), larghezza w+1 e altezza h+1 14 Metodi della classe Graphics void fillOval (int x, int y, int w, int h) void drawPolyline (int[] xP, int[] yP, int nP) disegna una linea spezzata (aperta) composta da nP punti di coordinate rispettivamente (xP[0], yP[0]), (xP[1], yP[1]),..., (xP[nP–1], yP[nP–1]) void drawPolyline (int[] xP, int[] yP, int nP) disegna un ovale (pieno) contenuto nel rettangolo con estremo in alto a sinistra nel punto (x, y), larghezza w e altezza h disegna una linea spezzata (chiusa) composta da nP punti di coordinate (xP[0], yP[0]), ...,(xP[nP–1], yP[nP–1]) void setColor (Color c) modifica il colore delle successive attività di disegno 15 Un esempio import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; /* Applet che disegna una casetta (in un'area 300x300 punti) */ public class AppletDisegnatore extends Applet { public void paint(Graphics g) { setBackground(Color.yellow); g.setColor(Color.blue); /* il colore delle linee è blu */ g.drawRect(50, 125, 200, 125); /* disegna il corpo */ g.drawLine(50, 125, 150, 50); /* disegna il tetto */ g.drawLine(250, 125, 150, 50); /* disegna un abbaino */ g.drawOval(135, 80, 30, 30); /* disegna la porta */ g.drawRect(125, 175, 50, 75); g.setColor(Color.red); g.fillRect(126, 176, 49, 74); } } 16 La classe JApplet Il linguaggio Java permette la definizione di applet oltre che AWT anche come classe JApplet (del package javax.swing) è una versione estesa della classe Applet, in grado di supportare componenti Swing la classe JApplet estende la classe Applet Il seguente esempio illustra la definizione di un JApplet import javax.swing.JApplet; import java.awt.Graphics; /** Applet (Swing) che visualizza una frase. */ public class AppletScrittoreSwing extends JApplet { /* Visualizza una frase. */ public void paint(Graphics g) { g.drawString("Il mio primo applet Swing", 25, 50); } } non tutti i browser web supportano gli applet Swing 17 Ciclo di vita di un Applet Un applet è un oggetto, che vive in (cioè viene eseguito da) una macchina virtuale Java di un browser web passando attraverso varie fasi: inizializzazione quando il browser deve visualizzare un applet, ne scarica il bytecode della classe (che deve estendere la classe Applet), crea un oggetto da questa classe e gli chiede di inizializzare il proprio stato; l’inizializzazione avviene una sola volta nella vita di un applet avvio public void init() public void start() subito dopo la creazione e l’inizializzazione, viene avviata l’esecuzione dell’applet se la pagina contenente l’applet viene lasciata e poi viene nuovamente visitata (perché viene visitata un’altra pagina, oppure perché la pagina viene iconizzata e poi deiconizzata), l’esecuzione dell’applet viene nuovamente riavviata (ma l’applet non viene ri-inizializzato) 18 Ciclo di vita di un Applet arresto l’esecuzione di un applet viene arrestata quando la pagina viene lasciata (perché viene visitata un’altra pagina, oppure il browser viene iconizzato oppure chiuso) distruzione public void stop() public void destroy() un applet viene distrutto quando il browser viene chiuso (la distruzione di un applet segue l’arresto della sua esecuzione) 19 Ciclo di vita di un Applet In corrispondenza ai vari passaggi di stato dell’applet vengono eseguiti i metodi init(), start(), stop() e destroy(). In particolare il metodo init() viene usato per inizializzare l’applet; normalmente si occupa dell’inizializzazione dello stato (delle variabili d’istanza) dell’oggetto applet, anche mediante la creazione di altri oggetti eventualmente utilizzati dall’applet (ad esempio, di altri componenti grafici) Poiché per gli applet non sono previsti costruttori l’inizializzazione avviene di solito nell’ambito del metodo init() Il metodo start() descrive le azioni che devono essere svolte dall’applet e si cura della gestione degli oggetti creati dal metodo init() Spesso, il metodo start() deve semplicemente avviare dei nuovi thread di esecuzione Della visualizzazione degli oggetti si occupa il metodo paint(...) 20 Un esempio Questo è HTML Questa è l’applet import import import import public java.applet.*; java.awt.*; java.awt.event.*; java.text.*; class Convertitore extends Applet implements ActionListener { private final double fattoreDiConversione=1936.27; private TextField t; private Checkbox lire, euro; private Button b; public void init() { //Gestore della disposizione setLayout(new BorderLayout()); setBackground(Color.white); //Campo di testo: valore da convertire t=new TextField(""); 21 Un esempio //Bottone: richiede la conversione b=new Button("Converti"); //registrazione del bottone come “ascoltatore” b.addActionListener(this); //Costruzione del selettore di valuta //cbg serve a garantire la mutua esclusione CheckboxGroup cbg= new CheckboxGroup(); //due checkbox, appartenenti al gruppo cbg //la prima inizialmente selezionata lire= new Checkbox("£",true,cbg); //la seconda no euro= new Checkbox("Euro",false,cbg); //Raggruppa alcuni componenti Panel p = new Panel(); p.add(lire); p.add(euro); p.add(b); //aggiungi il campo di testo in alto add(t,"North"); //aggiungi il pannello in basso add(p,"South"); } 22 Un esempio //Viene chiamato ogni volta in cui si preme il bottone public void actionPerformed(ActionEvent e) { String valore=t.getText(); //leggi il campo di testo double d; try { //trasforma la scritta in numero d=NumberFormat.getInstance().parse(valore).doubleValue(); } catch (ParseException nfe) { //in caso di errore d=0.0; } if (lire.getState()) { //Valuta corrente in lire d=d/fattoreDiConversione; euro.setState(true); //Cambia il tipo di valuta } else { //Valuta corrente in euro d=d*fattoreDiConversione; lire.setState(true); //Cambia il tipo di valuta } //Converti d in una stringa e la visualizza t.setText(NumberFormat.getInstance().format(d)); } } 23 Un esempio In generale un applet che ha bottoni e gestisce eventi ha la seguente struttura: import java.applet.*; import java.awt.*; import java.awt.event.*; … public class NomeClasse extends Applet implements ActionListener { … private Button b; … public void init() { // definizione del layout, aggiunta di bottoni, pannelli, ecc. } public void actionPerformed(ActionEvent e) { … } } 24 Un esempio La pagina HTML che conterrà l’applet è la seguente: <html> <body> <center> <h1>Conversione Lire/Euro</h1> <applet code="Convertitore" width="180" height="80"> </applet> </center> </body> </html> 25 JCreator e le applet nuovo es.: AppletScrittore es.: 4I1\applet Basic Java Applet 26 JCreator e le applet pagina HTML inserimento dell’Applet 27 JCreator e le applet applet creata automaticamente 28 JCreator e le applet 1° compilare l’applet (si crea il file .class) 29 JCreator e le applet 2° eseguire la pagina HTML 30 JCreator e le applet Viene aperta la finestra di comando e l’appletviewer nella quale è visualizzata solo l’applet. P.s.: se si vuole vedere la pagina HTML si deve aprirla con un browser!!! 31 JCreator e le applet Uso corretto di Jcreator (Workspace e Project) 1. Configure – Options – Directories: nella Default Project Directory inserire la directory di lavoro della classe – Apply - OK 2. New – Workspaces: scegliere Workspace name (es. Applet) – OK 3. Selezionare il Workspace - New – Projects – Basic Java Applet: dare il Project name (es. AppletScrittore) Viene così creata una struttura di directory: Nome Workspace Nome Project • • • Applet contiene un file Applet.jcw (definizione del workspace) AppletScrittore contiene un file AppletScrittore.jcp (definizione del project) e AppletScrittore.java (il file sorgente) classes contiene il file AppletScrittore.htm e (quando verrà creato) AppletScrittore.class 32 ESERCITAZIONE 1 Creare la propria directory di lavoro Definirla in JCreator come la Default Project Directory Creare in JCreator un Workspace (es. Applet) Creare in JCreator un nuovo progetto per ogni esercizio Provare la prima Applet (AppletScrittore), utilizzando quella generica creata da Jcreator, modificandone il testo, la posizione del testo, la dimensione dell’applet, aggiungendo altri testi, ecc. Realizzare l’AppletDisegnatore con un disegno a piacere, provando ad utilizzare diversi metodi di Paint(), diversi colori di sfondo, ecc. Realizzare un applet a piacere, scelto tra le applicazioni già realizzate, che utilizzi bottoni, campi di testo, ecc. 33 Un applet con parametri E’ possibile passare dei parametri dalla pagina HTML all’applet: la pagina web che contiene un applet può specificare parametri per l’applet, mediante elementi PARAM un applet può accedere ai parametri specificati dalla pagina web che lo contiene un applet può accedere alle dimensioni dell’area dedicata alla sua visualizzazione dalla pagina web che lo contiene Esempio (generico): <APPLET CODE=“AppletConParametri” WIDTH=200 HEIGHT=100> <PARAM NAME=nomedelparametro VALUE=valoredelparametro> </APPLET> 34 Un applet con parametri Un esempio di pagina HTML con due applet (anzi: due istanze di un applet) alle quali passa dei parametri: <HTML> <HEAD> <TITLE>Applet con parametri</TITLE> </HEAD> <BODY> <P>Vengono create due istanze dell'applet AppletConParametri.</P> <APPLET CODE="AppletConParametri.class“ WIDTH=200 HEIGHT=100> <PARAM NAME=descrizione VALUE="Applet largo"> </APPLET> <APPLET CODE="AppletConParametri.class“ WIDTH=100 HEIGHT=200> <PARAM NAME=descrizione VALUE="Applet alto"> </APPLET> </BODY> </HTML> 35 Un applet con parametri Questa è l’applet: import java.awt.Graphics; /* Applet che visualizza la sua descrizione (parametro della * pagina HTML) in un rettangolo che ha le sue dimensioni. */ public class AppletConParametri extends Applet { String desc; // descrizione dell'applet int larg, alt; // larghezza e altezza dell'applet public void init() {/* Inizializza l'applet. */ this.desc = this.getParameter("descrizione"); this.larg = this.getWidth(); Acquisisce il valore this.alt = this.getHeight(); del parametro Acquisiscono Width “descrizione” e Height dell’applet } public void paint(Graphics g) {/* Visualizza la descrizione */ g.drawRect(0, 0, this.larg-1, this.alt-1); g.drawString(desc, this.larg/2, this.alt/2); } } 36 Un applet con parametri Questo è il risultato: 37 Accesso al contesto L’applet può interagire con il “contesto”, cioè con l’ambiente del web browser, attraverso il metodo: public AppletContext getAppletContext() ad esempio: getAppletContext().showDocument(url) sostituisce la pagina corrente del browser con quella indicata (url) getAppletContext().showDocument(url,dove) sostituisce la pagina corrente del frame (dove) (o nella finestra) con quella indicata (url) getAppletContext().getAudioClip(url) scarica una clip audio (url) getAppletContext().getImage(url) scarica un’immagine (url) 38 Un esempio Un Applet che apre una pagina HTML: import import import import java.awt.*; java.awt.event.*; java.applet.Applet; java.net.*; Serve per l’URL public class ApriFinestra extends Applet implements ActionListener { Button b = new Button("Aprimi"); URL u; public void init() { try {u = new URL(getDocumentBase(),"ApriFinestra.htm");} catch (MalformedURLException e) { System.out.println("URL errato"); } add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent e) { target getAppletContext().showDocument(u,"_blank"); } } 39 ESERCITAZIONE 2 Realizzare l’AppletConParametri, che usi i parametri passategli dall’Html per definire le dimensioni e il testo (che deve essere centrato nell’applet); realizzare una pagina Html che richiami diverse volte lo stesso applet, con diverse dimensioni e testi. Eseguire con un browser la pagina Html realizzata. Realizzare un applet che apra una nuova finestra del browser con un’altra pagina Html a piacere. Eseguire con un browser la pagina Html realizzata. Realizzare una struttura a due Frame in Html; in un frame ci deve essere un applet che apra una nuova pagina nel secondo frame. Eseguire con un browser la pagina Html realizzata. 40 ESERCITAZIONE 3 Realizzare un applet-menu per una struttura a Frame in Html; in un frame ci deve essere una pagina Html con un applet che contenga diversi bottoni che aprano nuove pagine nel frame di destra. Creare le pagine Html relative. Eseguire con un browser la pagina Html realizzata. Generalizzare l’applet-menu, rendendolo parametrico: dall’Html si deve poter passare come parametri il numero dei bottoni, le scritte sui bottoni, le pagine da caricare. Far cambiare il colore al bottone corrispondente alla pagina che è stata aperta, disabilitarlo, rimettere il cursore normale. 41 Swing o Awt? L’uso del pacchetto Swing per gli Applet presenta delle differenze (e dei problemi) rispetto all’uso di Awt: • si deve importare Swing: • • • • import javax.swing.*; si estende un JApplet: public class HelloSwing extends JApplet… JApplet (di Swing) è una sottoclasse di Applet non si può usare il metodo paint (ma se si importa anche Awt è fattibile) per aggiungere bottoni o altri componenti si deve usare: getContentPane().add(btn); (invece di add(btn)) 42 Swing o Awt? • non si può disegnare direttamente sulla JApplet, ma si deve creare una classe apposita che contenga il paintComponent: class Disegna extends JPanel { public void paintComponent(Graphics g) { } • … } la classe così creata va istanziata e aggiunta al JApplet: Disegna areadisegno = new Disegna(); setContentPane(area); 43 Un esempio “Swing” import java.awt.*; import javax.swing.*; public class ScriviStringhe extends JApplet { String message; Font[] font; Disegna area; public void init() { message = “Sono un applet Java!"; Font[] font = new Font[5]; font[0] = new Font("Serif", Font.BOLD, 14); font[1] = new Font("SansSerif", Font.BOLD + Font.ITALIC, 24); font[2] = new Font("Monospaced", Font.PLAIN, 20); font[3] = new Font("Dialog", Font.PLAIN, 30); font[4] = new Font("Serif", Font.ITALIC, 36); area = new Disegna(); area.setBackground(Color.black); setContentPane(area); } 44 Un esempio “Swing” class Disegna extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); int width = getSize().width; int height = getSize().height; for (int i = 0; i < 25; i++) { int fontNum = (int)(5*Math.random()); g.setFont(font[fontNum]); float hue = (float)Math.random(); g.setColor( Color.getHSBColor(hue, 1.0F, 1.0F) ); int x,y; x = -50 + (int)(Math.random()*(width+40)); y = (int)(Math.random()*(height+20)); g.drawString(message,x,y); } } } } 45 Repaint • Il metodo paint() (o paintComponent()) viene eseguito automaticamente una volta sola all’avvio; se si vuole modificare qualche elemento del disegno è necessario rieseguirlo con il metodo repaint(). • Ovviamente in questo caso il disegno deve essere “parametrizzato” cioè si devono usare variabili il cui valore viene modificato, ad esempio da eventi (bottoni, ecc.) 46 Un esempio di repaint() Quest’applet modifica il colore di sfondo, oltre al contenuto e al colore di un TextField, facendo click su di un bottone: import java.awt.*; import java.awt.event.*; import java.applet.Applet; public class Ridisegna extends Applet implements ActionListener { int numeroClick; TextField testo; String txt[] = new String[] {"rosso", "giallo", "blue", "ciano", "verde", "arancione"}; Color col[]= new Color[] {Color.red, Color.yellow, Color.blue, Color.cyan, Color.green, Color.orange}; Color cols[]= new Color[] {Color.yellow, Color.blue, Color.cyan, Color.red, Color.gray, Color.black}; 47 Un esempio di repaint() public void init() { numeroClick=0; Button bottone = new Button("Cambia"); add(bottone); testo = new TextField(txt[numeroClick],10); add(testo); testo.setForeground(col[numeroClick]); testo.setBackground(cols[numeroClick]); bottone.addActionListener(this); } public void paint(Graphics g) { setBackground(col[numeroClick]); } public void actionPerformed(ActionEvent e) { numeroClick++; numeroClick=numeroClick%6; testo.setText(txt[numeroClick]); setBackground(col[numeroClick]); testo.setForeground(col[numeroClick]); testo.setBackground(cols[numeroClick]); repaint(); } } 48 ESERCITAZIONE 4 Provare l’esempio di repaint() Ridisegna. Realizzare altri applet che usano repaint per: 1. Modificare le dimensioni di un cerchio (con due bottoni “+” e “-” che ne aumentano e ne diminuiscono le dimensioni; 2. Spostare un oggetto grafico (ad esempio un testo, una label o un quadratino) in una posizione definita da due campi di testo (X e Y). 49 paint(), repaint() e update() • • • • L’istruzione repaint() apparentemente non fa altro che richiamare la paint(); in realtà richiama update() La update() fa due cose: • pulisce lo schermo • esegue la paint() Se si vuole evitare di cancellare lo schermo (ad esempio per poter aggiungere oggetti senza ridisegnare tutto) si può ridefinire la update(), in modo che richiami solo la paint(): public void update(Graphics g){ paint(g); } A questo punto la repaint()non ripulisce più lo schermo 50 MouseListener e MouseAdapter • • Per gestire gli eventi del mouse si può creare una classe di ascolto che estenda la MouseListener o la MouseMotionListener: Class AscoltatoreMouse implements MouseListener { public void mousePressed(MouseEvent e) {}; public void mouseReleased(MouseEvent e) {}; public void mouseEntered(MouseEvent e) {}; public void mouseExited(MouseEvent e) {}; public void mouseClicked(MouseEvent e) {}; } Class AscoltatoreMovMouse implements MouseMotionListener { public void mouseDragged(MouseEvent e) {}; public void mouseMoved(MouseEvent e) {}; } Le classi così definite devono definire tutti i metodi del mouse (anche se vuoti) 51 MouseListener e MouseAdapter • • Ovviamente il metodo che interessa va implementato; ad esempio: public void mousePressed(MouseEvent e) { X=e.getX(); Y=e.getY(); repaint(); }; Esistono le classe MouseAdapter e MouseMotionAdapter che possono essere estese e non è necessario definire tutti metodi: Class AscoltatoreMouse extends MouseAdapter { public void mousePressed(MouseEvent e) { … }; } 52 MouseListener e MouseAdapter • Le classi così create vanno ovviamente instanziate ed aggiunte all’applet; ad es.: AscoltatoreMouse am = new AscoltatoreMouse(); addMouseListener(am); • • • Per gli eventi della tastiera esistono KeyListener e KeyAdapter, vari metodi, ad es.: Public void keyPressed(KeyEvent e) KeyEvent ha il metodo getKeyCode() con il quale è possibile conoscere il tasto premuto Alcuni tasti sono definito da costanti. Ad esempio le frecce sono KeyEvent.VK_UP KeyEvent.VK_DOWN KeyEvent.VK_LEFT KeyEvent.VK_RIGHT 53 Un esempio Applet che aggiunge un pallino ad ogni clic import java.awt.*; import java.applet.*; import java.awt.event.*; public class Pallini extends Applet { int X,Y; public void init() { MioAscoltatoreMouse al = new MioAscoltatoreMouse(); addMouseListener(al); } public void paint(Graphics g) { g.setColor(Color.red); g.fillOval(X,Y,10,10); } public void update(Graphics g){ paint(g); } private class MioAscoltatoreMouse extends MouseAdapter { public void mousePressed(MouseEvent e){ X=e.getX(); Y=e.getY(); repaint(); } } } 54 ESERCITAZIONE 5 Provare l’applet Pallini L’applet disegna un pallino fin dall’inizio: evitare che questo avvenga (ad es. usando un boolean…) L’ultimo pallino inserito potrebbe essere spostato a mano con le frecce della tastiera Aggiungere un mouseDragged che disegni il pallino in modo continuo finchè il bottone del mouse è premuto Aggiungere un campo di testo nel quale inserire le dimensioni del pallino da disegnare 55 Animazione • • • Molto spesso un applet viene utilizzata per realizzare un’animazione Le animazioni possono essere realizzate in diversi modi, in genere utilizzando i Thread, cioè la possibilità esistente in Java di far partire dei processi contemporaneamente. Una soluzione semplificata è quella offerta dalla classe Timer del package Swing, che consente di eseguire un’azione in modo ripetitivo: int ritardo = 1000; //millisecondi ActionListener esecutore = new ActionListener() { public void actionPerformed(ActionEvent evt) { //…azione da ripetere… } }; Timer timer = new Timer(ritardo, esecutore); … timer.start(); 56 Animazione Timer ha diversi metodi, tra i quali: • start() lo fa partire • stop() lo fa terminare • isRunning() restituisce true il Timer è attivo, false se non lo è • restart() lo fa ripartire • setDelay(int delay) ridefinisce il ritardo 57 Un esempio import import import import java.awt.*; java.awt.event.*; java.applet.Applet; javax.swing.*; public class AnimaPallina extends Applet implements ActionListener { int x,y,i; Button bottone new Button("Via"); int ritardo = 100; ActionListener esecutore = new ActionListener() { public void actionPerformed(ActionEvent evt) { azioneTimer(); } }; Timer timer = new Timer (ritardo, esecutore); public void init() { add(bottone); bottone.addActionListener(this); x=10; y=10; } 58 Un esempio public void actionPerformed(ActionEvent e) { timer.start(); } public void paint(Graphics g) { g.setColor(Color.red); g.fillOval(x,y,10,10); } public void azioneTimer(){ x+=10; y+=10; repaint(); if (y==200){timer.stop();} } } 59 ESERCITAZIONE 6 Provare l’applet AnimaPallina. Aggiungere un bottone “Stop” che interrompa il timer. Far muovere la pallina dentro un rettangolo, facendola rimbalzare sui bordi Aggiungere due bottoni per aumentare e diminuire la velocità Realizzare con il timer un cronometro (pulsanti “Start” e “Stop”, indicazione al decimo di secondo) 60 I Thread In Java è possibile la multiprogrammazione cioè è possibile far partire dei processi che girano in parallelo col processo che li ha fatti partire. Il tutto viene gestito attraverso l'oggetto Thread. Il processo da eseguire va indicato nel metodo run dello stesso oggetto, mentre i metodi start e stop possono essere usati per far partire/fermare il processo in parallelo. Di solito si evita di usare il metodo stop (il cui uso è deprecato) e si fa fermare il Thread usando una tecnica diversa. Per usare un Thread in un applet abbiamo bisogno di ridefinire un metodo di una classe diversa dalla classe madre: in questo caso il metodo run di Thread mentre la classe madre è Applet. 61 I Thread Vediamo una possibile struttura di un Thread entro un applet: import java.applet.*; import java.awt.*; import java.awt.event.*; Instanzio un oggetto mioThread, passando eventuali parametri public class nomeApplet extends Applet { mioThread t; public void init () { t = new mioThread(… parametri …); new Thread(t).start(); Dà il via al Thread t … } public void paint (Graphics g) { t.disegna(g); Richiama un metodo … di mioThread } 62 I Thread Definizione di mioThread class mioThread implements Runnable { … obbligatorio mioThread(… parametri …) { … costruttore } public void run() { Metodo run(): contiene quello che … fa il Thread e, eventualmente, repaint(); richiama repaint() } public void disegna(Graphics g) { … Eventuali metodi di mioThread } … I metodi start() e stop() esistono } } anche se non sono ridefiniti 63 I Thread Un esempio (la solita pallina): import import import public java.applet.*; java.awt.*; java.awt.event.*; class AnimaPallina extends Applet { Pallina p1; int lar, alt; public void init () { lar = this.getWidth(); alt = this.getHeight(); p1 = new Pallina(Color.RED, 50, 1); new Thread(p1).start(); } public void paint (Graphics g) { p1.disegna(g); } class Pallina implements Runnable { static final int RAGGIO=10; int x,y; int deltaX=10; int deltaY=10; Color colore; int ritardo, dir; 64 I Thread Pallina(Color colore, int ritardo, int dir) { this.colore=colore; this.ritardo=ritardo; this.dir = dir; } public void run() { while (true) { x += deltaX*dir; y += deltaY; if (x>=(lar-RAGGIO*2) || x<0) deltaX=-deltaX; if (y>=(alt-RAGGIO*2) || y<0) deltaY=-deltaY; try {Thread.sleep(ritardo);} catch (InterruptedException e) {e.printStackTrace();} repaint(); } } public void disegna(Graphics g) { g.setColor(colore); g.fillOval(x, y, RAGGIO*2, RAGGIO*2); } } } 65 ESERCITAZIONE 6 Provare l’applet AnimaPallina con i Thread. Inserire un bottone Start (per far partire l’animazione) e un bottone Stop (per fermarla) Aggiungere altre palline-Thread di vari colori e con varie direzioni Modificare la classe Pallina per passarle anche la posizione iniziale (x, y) Animare con ritardi casuali le varie palline Realizzare una “corsa di palline”: movimento orizzontale, ritardi casuali, individuare quale pallina arriva prima… 66