Gestione di finestre e bottoni in Java

La volta scorsa abbiamo visto come funzionano le applet e come passargli parametri tramite l'HTML. Abbiamo anche visto alcuni metodi per disegnare testi e linee colorate, che abbiamo animato seguendo i movimenti del mouse.
Per rendere l'applet interattiva abbiamo gestito gli "eventi" relaviti al mouse: ne esistono molti altri, ma durante la navigazione l'utente usa principalmente il mouse, quindi non è il caso di richiedere altri eventi, come ad esempio la pressione di un tasto.
Col mouse però è possibile fare molte cose, specie se si dispone di bottoni, menù a tendina e altre interfacce proprie dei sistemi operativi intuitivi.
Java ha l'AWT (Abstract Windows Toolkit), che come dice il nome e' un sistema di finestre, bottoni ecc., implementato in modo che sia "astratto" dalle piattaforme specifiche, come X-Windows, Win95, MacOS, ma che tuttavia visualizzi interfacce standard su tali implementazioni "pratiche", e diverse tra loro.
l'AWT definisce oggetti astratti come "bottone" e "finestra", i quali sono istanziati sui diversi sistemi operativi come essi sono soliti rappresentarli. Se si apre una finestra con Java, essa su Win95 avrà i gadget caratteristici di Win95, per intenderci, e avrà quelli del MacOS se è eseguita su MAC.
Anche gli eventi del mouse (che abbiamo già usato) fanno parte dell'AWT. Infatti, una volta creato un bottone, la sua pressione sarà considerata anch'essa un evento di tipo "action", al quale potremo associare un'operazione da svolgere.
Il posizionamento dei singoli elementi AWT all'interno dell'area dell'applet meriterebbe una disgressione sul LayoutManager, ma nel nostro caso la soluzione migliore è disabilitare il posizionamento automatico, e fornire manualmente la posizione in termini di coordinate x,y assolute, tramite il metodo reshape().


l'AWT in pratica.

Proponiamoci di fare un'applet che abbia un bottone alla cui pressione venga stampato un certo testo.
Nel metodo init() si deve istanziare un oggetto di tipo Button, decidendo quale sarà la sua etichetta, e aggiungerlo alla "superficie" dell'applet:

Button ButSalve = new Button("Salve");

Questo istanzia un bottone di nome ButSalve, la cui etichetta e' "Salve". Per aggiungere il bottone basta usare il metodo add():

add(ButSalve);

Ma in che punto dell'applet viene aggiunto il nostro bottone? Questo dipende dal tipo di LayoutManager, oppure se non ne è attivato alcuno, occorre posizionarlo manualmente. Se non si specifica niente viene adottato il BorderLayout, quindi dobbiamo eplicitamente disabilitare il LayourManager scrivendo:

setLayout(null);

A questo punto dobbiamo posizionare manualmente il bottone:

ButSalve.reshape(50,50,100,40);

I parametri che si devono passare a reshape() sono, nell'ordine: coordinata x,y dell'angolo in alto a sinistra, larghezza ed altezza.
Piazzare un bottone non è utile se non si fa in modo che si attivi qualche funzione in caso di pressione o, più precisamente, nel caso in cui il metodo action() sia chiamato dall'evento della pressione:

public boolean action(Event ev, Object argom) { ... }

Il metodo action() però può essere chiamato da eventi non dipendenti da un bottone, quindi come prima cosa occorre accertarsi che sia chiamato da un bottone. Per fare ciò possiamo controllare se variabile "target" dell'evento è una istanza della classe Button, grazie all'operatore "instanceof":

if(ev.target instanceof Button) { ... }

Se l'evento è causato da un bottone, occorrere inoltre accertarsi che sia proprio il nostro:

if(argom.equals("Salve")) { ... }

Dato che nel nostro caso l'applet ha un unico bottone, questo ultimo controllo si può considerare superfluo, ma vedremo dopo che avendo due o più bottoni diviene indispensabile.
Il listato 1 e il listato 2 sono rispettivamente il sorgente Java e l'HTML dell'applet che ci siamo proposti di fare.


Inseriamo Checkbox e Choice.

Ora che abbiamo visto l'esempio di un bottone, possiamo agevolmente costruire una interfaccia più complessa, comprendente elementi diversi.
I Checkbox ad esempio sono dei pulsantini quadrati che diventano barrati in caso di selezione. Servono ad indicare condizioni booleane (ossia riportano i soli due stati di vero o falso) e per costruirli basta fornire al costruttore il testo che sarà stampato a lato, e lo stato iniziale (barrato o meno). Se si passa solo il testo, di default il Checkbox sarà inizializzato come deselezionato:

Checkbox opz1 = new Checkbox("Opzione 1");

Quando vogliamo sapere lo stato del Checkbox, basta usare il suo metodo getState(), mentre per cambiarlo si usa setState().
Il Choice invece è un menù a "tendina", dove normalmente è visibile solo l'elemento correntemente selezionato, a meno che non si clicki sul pulsantino di allargamento che si trova a destra: questo infatti fa visualizzare tutta la lista per permettere una nuova selezione.
Per istanziare un Choice si procede come di consueto:

Choice menu1 = new Choice();

Dopo però occorre aggiungere gli elementi uno ad uno:

menu1.addItem("Scelta 1");
menu1.addItem("Scelta 2")
;

Il menù visualizzerà le stringhe nello stesso ordine.
Per sapere quale elemento è selezionato, si può usare il metodo getSelectedIndex(), col quale otteniamo l'indice numerico ("Scelta 1" nel nostro caso darebbe 0, "Scelta 2" darebbe 1 ecc.); oppure getSelectedItem() per sapere la stringa.
Per selezionare automaticamente un elemento si usa il metodo select().
In listato 2 e listato 3 trovate una interfaccia simile ad un FORM che utilizza tutte le classi e i metodi trattati.

Fabio Ciucci
fabioc@anfiteatro.it


Scarica il listato 1: Bottone1.java

Scarica il listato 2: bottone1.html

Scarica il listato 3: Interfaccia1.java

Scarica il listato 4: interfaccia1.html che esegue Interfaccia1.class


Torna all' indice degli articoli