Nella lezione 8 abbiamo menzionato l'esistenza delle finestre di dialogo...
Finestra di dialogo = finestra secondaria di un'applicazione,
serve per mostrare informazioni e/o richiedere informazioni all'utente.
E' intesa come finestra temporanea.
Viene mostrata in seguito a una azione dell'utente su una
finestra chiamante.
Esempio: se aziono il bottone per la stampa mi appare la finestra
di dialogo che chiede quale stampante, quante pagine...
La finestra di dialogo contiene dispositivi (es. bottoni) con cui l'utente
la chiude dopo aver ricevuto e/o dato le informazioni stabilite.
Un dialogo dipende funzionalmente dalla finestra chiamante. La finestra chiamante di solito e' la finestra principale (frame) dell'applicazione, ma puo' essere anche un'altra finestra di dialogo, che a sua volta dipende, direttamente o tramite altre finestre di dialogo, dalla finestra principale (dialoghi a cascata).
La dipendenza funzionale comporta che:
Finestra adatta ad essere usata come finestra di dialogo.
Viene costruita come dipendente da un'altra finestra
(specificata in argomento al costruttore, ved. dopo).
Essendo intesa come finestra temporanea,
il sistema puo' mostrarla con tutte le decorazioni
o con un sotto-insieme (es. senza i dispositivi di controllo per
redimensionamento).
Costruttori della classe Dialog:
Un dialogo viene creato vuoto. Poi bisogna riempirlo esattamente come si fa con i frame (aggiungere con "add" tutti i componenti e poi dimensionare con "pack") poiche' entrambi sono finestre.
Metodi interessanti della classe Dialog:
La classe DialogExample.java realizza un'applicazione con due finestre:
import java.awt.*; import java.awt.event.*; class DialogExample extends Frame { Button apriDialogo; // su questa finestra Dialog mioDialogo; Button chiudiDialogo; // su finestra di dialogo DialogExample() { /* costruzione del contenuto di questa finestra */ apriDialogo = new Button("apri dialogo"); add(apriDialogo); pack(); /* costruzione della finestra di dialogo */ mioDialogo = new Dialog(this,"Finestra di dialogo",true); mioDialogo.setLayout(new GridLayout(2,1)); mioDialogo.add(new Label("ciao, sono una finestra di dialogo...")); mioDialogo.add(chiudiDialogo = new Button("chiudi dialogo")); mioDialogo.pack(); /* comportamento del bottone sulla finestra principale */ ActionListener apriListener = new ActionListener() { public void actionPerformed(ActionEvent e) { mioDialogo.setVisible(true); } }; apriDialogo.addActionListener(apriListener); /* comportamento del bottone sulla finestra di dialogo */ ActionListener chiudiListener = new ActionListener() { public void actionPerformed(ActionEvent e) { mioDialogo.setVisible(false); } }; chiudiDialogo.addActionListener(chiudiListener); } public static void main(String[] args) { DialogExample ee = new DialogExample(); ee.setVisible(true); } }
La classe DialogExample realizza la finestra principale, sotto-classe
di Frame.
Il costruttore della classe DialogExample
costruisce anche il dialogo e lo tiene nella variabile mioDialogo.
La callback del bottone apriDialogo presente sulla finestra principale
mostra il dialogo;
la callback del bottone chiudiDialogo presente sul dialogo
lo nasconde.
La finestra principale invece viene mostrata direttamente dal main.
Possiamo caricare un'immagine da file e visualizzarla in un'interfaccia grafica.
Per caricare un'immagine bisogna interpellate la libreria
per interfacce grafiche, che nel nostro caso e' la libreria Java
AWT (Abstract Window Toolkit).
Il toolkit AWT e' esso stesso e' un oggetto di classe Toolkit,
e si ottiene invocando il metodo getDefaultToolkit, che e' metodo
di classe nella classe Toolkit, e ritorna un oggetto di classe
Toolkit. Per esempio possiamo chiamare:
Toolkit tool = Toolkit.getDefaultToolkit();
A questo oggetto di classe Toolkit, cosi' ottenuto,
possiamo chiedere di caricare un'immagine da file.
I formati di file accettati sono gli stessi che si possono
inserire nella pagine web: GIF, JPEG.
L'immagine caricata e' un oggetto della classe Java Image.
Per caricare un'immagine dal file "pippo.gif" scriviamo:
Image img = tool.getImage("pippo.gif");
In realta' vi e' una complicazione.
Caricare un'immagine puo' essere un'operazione lunga.
Se il metodo "getImage" fosse "sincrono" la sua esecuzione dovrebbe
durare tutto il tempo del caricamento.
Invece il metodo "getImage" e' "asincrono", cioe' si esegue
istantameamente, mentre l'immagine non e' ancora stata caricata
(pero' Java si e' annotato che deve caricarla).
E' come dire: "ho comperato questo" mentre ho solo
spedito l'ordine, poi ci metteranno del tempo a consegnarmelo.
Java carichera' l'immagine per forza quando chiedero' di disegnarla (e' come mettere fretta al fornitore), non prima. Ma io prima di disegnare l'immagine ho bisogno di sapere per esempio quali sono le sue dimensioni. Sfortunatamente, siccome l'immagine non e' stata ancora caricata, risultano -1 x -1 pixel.
Allora: Devo forzare il caricamento per ottenere che l'immagine sia
caricata subito dopo "getImage" senza aspettare il momento
di disegnarla (che sarebbe troppo tardi).
Per forzare il caricamento uso un oggetto di classe MediaTracker.
MediaTracker track = new MediaTracker(this); | crea oggetto di classe MediaTracker |
track.addImage(img,0); | vi aggiunge l'immagine di cui voglio forzare il caricamento. all'interno del tracker questa immagine e' identificata dal codice 0 |
track.waitForID(0); | obbliga ad aspettare finche' l'immagine identificata dal codice 0 non viene caricata del tutto |
Ogni componente Java ha un metodo "paint" che Java usa per disegnare
a schermo il componente.
Da programma io non chiamo MAI tale metodo, lo chiama Java
automaticamente quando e' necessario.
Per es. quando la finestra viene resa visibile, quando viene
redimensionata ecc.
Il metodo paint e' nella superclasse Component ed e' ereditato da
tutte le classi di componenti.
Posso ridefinire l'implementazione di questo metodo per disegnare
un'immagine sullo sfondo del compomente.
Suppomiano che l'immagine sia contenuta nella variabile image:
public void paint(Graphics g) { super.paint(g); g.drawImage (image, 0, 0, width, height, this); }Dove l'argomento di "paint" rappresenta il sistema grafico (e' passato automaticamente da Java quando chiama la funzione paint).
La classe ExImage realizza un pannello (sotto-classe di Panel) che, invece di essere vuoto e a dimensione 0 x 0 pixel, e' pieno di un'immagine caricata da file e ha dimensioni pari all'immagine stessa.
La classe contiene:
Analogamente, posso realizzare un bottone, una label ecc. che ha un'immagine sullo sfondo.