Sviluppo di Interfacce Grafiche in Java. Concetti di Base ed Esempi.
|
|
|
- Rosangela Gallo
- 9 anni fa
- Visualizzazioni
Transcript
1 SAPIENZA Università di Roma Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica Dispensa didattica Sviluppo di Interfacce Grafiche in Java. Concetti di Base ed Esempi. Versione di Marzo M. de Leoni, M. Mecella, S. Saltarelli
2 Creative Commons License Deed Attribuzione - Non commerciale - Non opere derivate 2.5 Italia Tu sei libero: di riprodurre, distribuire, comunicare al pubblico, esporre in pubblico, rappresentare, eseguire e recitare questa opera Alle seguenti condizioni: Attribuzione. Devi attribuire la paternità dell opera nei modi indicati dall autore o da chi ti ha dato l opera in licenza. Non commerciale. Non puoi usare questa opera per fini commerciali. Non opere derivate. Non puoi alterare o trasformare quest opera, nè usarla per crearne un altra. Ogni volta che usi o distribuisci questa opera, devi farlo secondo i termini di questa licenza, che va comunicata con chiarezza. In ogni caso, puoi concordare col titolare dei diritti d autore utilizzi di quest - opera non consentiti da questa licenza. Niente in questa licenza indebolisce o restringe i diritti degli autori. Le utilizzazioni consentite dalla legge sul diritto d autore e gli altri diritti non sono in alcun modo limitati da quanto sopra. Questo è un riassunto in linguaggio accessibile a tutti del Codice Legale (la licenza integrale) disponibile all indirizzo:
3 2 Indice 1 Introduzione Il package Swing Top Level Container Paranoramica di alcuni widget L ereditarietà per personalizzare i frame Layout Management Progettazione della GUI con le gerarchie di contenimento Progettazione top down di interfacce grafiche Esempio di Progettazione Top-Down Realizzare finestre di dialogo con JOptionPane La Gestione degli Eventi Implementazione dell event delegation Un esempio: elaborare gli eventi del mouse Uso di adapter nella definizione degli ascoltatori La gestione degli eventi Azione Accedere dall ascoltatore agli oggetti di una finestra Condividere gli ascoltatori per più oggetti Conclusioni e Commenti Finali
4 1 Introduzione 3 1 Introduzione Uno dei problemi più grossi emersi durante la progettazione di Java fu senza dubbio la realizzazione di un toolkit grafico capace di funzionare con prestazioni di buon livello su piattaforme molto differenti tra loro. La soluzione adottata nel 1996 fu AWT(Abstract Window Toolkit), un package grafico che mappa i componenti del sistema ospite con apposite classi dette peer, scritte in gran parte in codice nativo. In pratica, ogni volta che il programmatore crea un componente AWT e lo inserisce in un interfaccia grafica, il sistema AWT posiziona sullo schermo un oggetto grafico della piattaforma ospite, e si occupa di inoltrare ad esso tutte le chiamate a metodo effettuate sull oggetto Java corrispondente, ricorrendo a procedure scritte in buona parte in codice nativo; nel contempo, ogni volta che l utente manipola un elemento dell interfaccia grafica, un apposita routine (scritta sempre in codice nativo) crea un apposito oggetto Event e lo inoltra al corrispondente oggetto Java, in modo da permettere al programmatore di gestire il dialogo con il componente e le azioni dell utente con una sintassi completamente Object Oriented e indipendente dal sistema sottostante. A causa di questa scelta progettuale, il set di componenti grafici AWT comprende solamente quel limitato insieme di controlli grafici che costituiscono il minimo comune denominatore tra tutti i sistemi a finestre esistenti: un grosso limite rispetto alle reali esigenze dei programmatori. In secondo luogo, questa architettura presenta un grave inconveniente: i programmi grafici AWT assumono un aspetto ed un comportamento differente a seconda della JVM su cui vengono eseguite, a causa delle macroscopiche differenze implementative esistenti tra le versioni di uno stesso componente presenti nelle diverse piattaforme. Spesso le interfacce grafiche realizzate su una particolare piattaforma mostrano grossi difetti se eseguite su un sistema differente, arrivando in casi estremi a risultare inutilizzabili. Il motto della Sun per Java era scrivi (il codice) una volta sola ed eseguilo ovunque ; nel caso di AWT questo si era trasformato in scrivi una volta sola e correggilo ovunque. 2 Il package Swing Nel 1998, con l uscita del JDK 1.2, venne introdotto il package Swing, i cui componenti erano stati realizzati completamente in Java, ricorrendo unicamente alle primitive di disegno più semplici, tipo traccia una linea o disegna un cerchio, accessibili attraverso i metodi dell oggetto Graphics, un oggetto AWT utilizzato dai componenti Swing per interfacciarsi con la
5 2 Il package Swing 4 Component Container JComponent Window JFrame JPanel JDialog Panel JApplet java.awt javax.swing Fig. 1: Diagramma UML di base del package Swing. piattaforma ospite. Le primitive di disegno sono le stesse su tutti i sistemi grafici, e il loro utilizzo non presenta sorprese: il codice java che disegna un pulsante Swing sullo schermo di un PC produrrà lo stesso identico risultato su un Mac o su un sistema Linux. Questa architettura risolve alla radice i problemi di uniformità visuale, visto che la stessa identica libreria viene ora utilizzata, senza alcuna modifca, su qualunque JVM. Liberi dal vincolo del minimo comune denominatore, i progettisti di Swing hanno scelto di percorrere la via opposta, creando un package ricco di componenti e funzionalità spesso non presenti nella piattaforma ospite. Il procedimento di disegno è ovviamente più lento perché la JVM deve disegnare per proprio conto tutte le linee degli oggetti grafici e gestirne direttamente il comportamento, però è più coerente. Le classi Swing sono definite nel pacchetto javax.swing, il cui nome javax indica estensione standard a Java. Inizialmente Swing venne rilasciato, infatti, come estensione per poi divenire un omponente standad di Java 2. Per motivi di compatibilita il nome del pacchetto javax non venne corretto in java. Gli oggetti grafici Swing derivano dai corrispettivi AWT; quindi è possibile utilizzare oggetti Swing, ove erano previsti i oggetti antenati. Swing usa ancora alcuni elementi AWT per disegnare; anche la gestione degli eventi è fatta per la maggior parte da classi AWT. La Figura 1 riassume molto sinteticamente le classi base del package Swing e come queste derivino da classi AWT. Ogni oggetto grafico (una finestra, un bottone, un campo di testo,... ) è implementato come classe del package javax.swing. Ogni classe che identifica un oggetto Swing deriva
6 3 Top Level Container 5 per lo più dalla classe javax.swing.jcomponent; si stima che esistono circa 70 o più oggetti diversi. Gli oggetti grafici utilizzati per disegnare le interfacce vengono chiamati anche controlli oppure tecnicamente widget. JComponent eredita da java.awt.container, una sorta di controllo che di default è vuoto e il cui scopo è offrire la possibilità di disporre altri componenti all interno. Non a caso la classe AWT Window e le sottoclassi Swing JFrame e JDialog, le cui istanze rappresentano finestre, sono sottoclasse di Container. La cosa più sorprendente è che, siccome JComponent deriva da Container, è possibile inserire all interno di un qualsiasi widget qualsiasi altro. Ad esempio - sebbene poco utile - è possibile aggiungere un campo di testo all interno di un bottone oppure - molto usato - un Container all interno di un altro Container. La classe Container (e ogni sottoclasse) definisce un metodo per aggiungere un controllo ad un Container: void add ( Component ) ; Il metodo prende come parametro un oggetto Component che è la superclasse di qualsiasi oggetto o container Swing o AWT. 3 Top Level Container I top level container sono i componenti all interno dei quali si creano le interfacce grafiche: ogni programma grafico ne possiede almeno uno, di solito un JFrame, che rappresenta la finestra principale. Ogni top level container possiede un pannello (accessibile tramite il metodo getcontentpane()) all interno del quale vanno disposti i controlli dell interfaccia grafca. Esistono tre tipi principali di top level Container: JFrame, JApplet e JDialog. Il primo viene solitamente usato come finestra principale per il programma, il secondo è utilizzato per costruire Applet da visualizzare nella finestra di un web browser mentre il terzo serve a creare le finestre di dialogo con l utente. In questa dispensa ci si focalizzerà solamente sui JFrame. Un oggetto della classe JFrame può essere creato usando i costruttori: JFrame ( ) ; JFrame ( S t r i n g t i t o l o F i n e s t r a ) ; Il primo costruisce un JFrame senza titolo; il secondo permette di specificarlo. È sempre possibile impostare il titolo ricorrendo al metodo settitle(string s). Due importanti proprietà dell oggetto sono la dimensione e la posizione, che possono essere impostate sia specificando le singole componenti sia mediante oggetti Dimension e Point del package AWT: public void s e t S i z e ( Dimension d ) ; public void s e t S i z e ( int width, int h e i g h t ) ;
7 3 Top Level Container 6 Fig. 2: Anatomia di un Frame Swing. public void s e t L o c a t i o n ( Point p ) ; public void s e t L o c a t i o n ( int x, int y ) ; Ricorrendo al metodo setresizable(boolean b) è possibile stabilire se si vuole permettere all utente di ridimensionare la finestra manualmente. Infine, vi sono tre metodi piuttosto importanti: public void pack ( ) ; public void s e t V i s i b l e ( boolean b ) ; public void s e t D e f a u l t C l o s e O p e r a t i o n ( int o p e r a t i o n ) ; Il primo ridimensiona la finestra tenendo conto delle dimensioni ottimali di ciascuno dei componenti presenti all interno. Il secondo permette di visualizzare o di nascondere la finestra. Il terzo imposta l azione da eseguire alla pressione del bottone close, con quattro impostazioni disponibili: JFrame.DO NOTHING ON CLOSE (nessun effetto), JFrame.HIDE ON CLOSE (nasconde la finestra), JFrame.DISPOSE ON CLOSE (chiude la finestra e libera le risorse di sistema) e JFrame.EXIT ON CLOSE (chiude la finestra e conclude l esecuzione del programma). Per impostazione di default, un JFrame viene costruito non visibile e di dimensione 0 x 0. Per questa ragione, affinchè la finestra sia visibile, è necessario chiamare i metodi setsize() o pack() per specificare la dimensione e mettere a true la proprietà Visible chiamando il metodo: setvisible(true). Per poter lavorare con i Frame Swing, è opportuno conoscere il linea generale la struttura della superficie. La superficie di un frame Swing è coperta da quattro lastre: Glass Pane La lastra di vetro è nascosta di default ed ha il compito di catturare gli eventi di input sulla finestra. Normalmente è completamente trasparente a meno che venga implementato il metodo paintcomponent del GlassPane. Poichè è davanti a tutte le altre, qualsiasi oggetto disegnato su questa lastra nasconde qualsiasi altro disegnato sulle altre
8 3 Top Level Container 7 import javax. swing. ; import java. awt. ; public class A p p l i c a t i o n public static void main ( S t r i n g args [ ] ) JFrame win ; win = new JFrame ( Prima f i n e s t r a ) ; Container c = win. getcontentpane ( ) ; c. add (new JLabel ( Buona Lezione ) ) ; win. s e t S i z e ( 2 0 0, ) ; win. s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame. EXIT ON CLOSE ) ; win. s e t V i s i b l e ( true ) ; Listato 1: La prima finestra Content Pane La lastra dei contenuti è la più importante perchè è quella che ospita i componenti che volete visualizzare nella finestra e la maggior parte dei programmatori Java lavora solo su questa Layered Pane Contiene la lastra dei contenuti ed eventualmente i menu. I menu, infatti, non vengono mai aggiunti al Content Pane ma a questa lastra. Root Pane La lastra radice ospita la lastra di vetro insieme con la lastra dei contenuti e i bordi della finestra. Per maggiori dettagli si faccia riferimento a books/tutorial/uiswing/components/rootpane.html. Quindi, un componente, quale un pulsante, un immagine o altro, non viene aggiunto direttamente alla finestra ma alla lastra dei contenuti. Di conseguenza, occorre per prima cosa procurarsi un riferimento all oggetto ContentPane, mediante la chiamata al metodo: public Container getcontentpane ( ) ; Come era da aspettarsi, il ContentPane è un Container perchè predisposto a contenere altri componenti. A questo punto, come per ogni altro Container, è possibile aggiungere ad esso un componente con il metodo add già descritto. A questo punto è possibile disegnare la prima finestra. Il codice descritto nel Listato 1 mostra la finestra in Figura 3.
9 4 Paranoramica di alcuni widget 8 Fig. 3: La prima finestra. 4 Paranoramica di alcuni widget I nomi delle classi per la maggior parte dei componenti dell interfaccia utente Swing iniziano con la J. JTextField è un campo di testo Swing. Tale classe eredita da TextField, l obsoleto analogo del package AWT. Per costruire un campo di testo occorre fornirne l ampiezza, cioè il numero approssimato di caratteri che vi aspettate verranno inseriti dall utente. JTextField xfield=new JTextField ( 5 ) ; Gli utenti possono digitare anche un numero maggiore di caratteri ma sempre 5 contemporaneamente saranno vicini: i 5 attorno alla posizione del cursore nel campo. Sarebbe opportuno etichettare ciascun campo di testo in modo che l utente sappia cosa scriverci. Ogni etichetta è un oggetto di tipo JLabel che viene costruito, sfruttando il costruttore con un parametro stringa; tale parametro rappresenta il testo dell etichetta: JLabel xfield=new JLabel ( x = ) ; Inoltre vorrete dare all utente la possibilità di inserire informazione in tutti i campi di testo prima di elaborarli per cui avete bisogno di un pulsante che l utente possa premere per segnalare che i dati sono pronti per essere elaborati. Un pulsante è un oggetto JButton che può essere costruito fornendo una stringa che fungerò da etichetta, un immagine come icona o entrambe JButton movebutton=new JButton ( Move ) ; JButton movebutton= new JButton (new ImageIcon ( hand. g i f ) ) ;
10 4 Paranoramica di alcuni widget 9 Fig. 4: Alcuni Bottoni delle Swing. JButton movebutton= new JButton ( Move,new ImageIcon ( hand. g i f ) ) ; JCheckBox è una sottoclasse di JButton che crea caselle di controllo, con un aspetto simile a quello delle caselle di spunta dei questionari. Il suo funzionamento è analogo a quello della superclasse, ma di fatto tende a essere utilizzato in contesti in cui si offre all utente la possibilità di scegliere una o più opzioni tra un insieme, come avviene per esempio nei pannelli di controllo. I costruttori disponibili sono gli stessi della superclasse, quindi non sarà necessario ripetere quanto è stato già detto. JCheckBox check1=new JCheckBox ( JCheck ) ; JRadioButton è una sottoclasse di JButton, dotata dei medesimi costruttori. Questo tipo di controllo, chiamato pulsante di opzione, viene usato tipicamente per fornire all utente la possibilità di operare una scelta tra un insieme di possibilità, in contesti nei quali un opzione esclude l altra. I costruttori disponibili sono gli stessi della superclasse. Per implementare il comportamento di mutua esclusione, è necessario registrare i JRadioButton che costituiscono l insieme presso un istanza della classe ButtonGroup, come viene mostrato nelle righe seguenti: JRadioButton radiobutton1=new JRadioButton ( R1 ) ; JRadioButton radiobutton2=new JRadioButton ( R2 ) ; JRadioButton radiobutton2=new JRadioButton ( R3 ) ; ButtonGroup group = new ButtonGroup ( ) ; group. add ( radiobutton1 ) ; group. add ( radiobutton2 ) ; group. add ( radiobutton3 ) ;
11 4 Paranoramica di alcuni widget 10 import javax. swing. ; import java. awt. ; public class A p p l i c a t i o n public static void main ( S t r i n g args [ ] ) JFrame win ; win = new JFrame ( Esempio d i JComboBox ) ; S t r i n g l i s t a []=new S t r i n g [ 1 0 ] ; for ( int i =0; i <l i s t a. l e n g t h ; i ++) l i s t a [ i ]= Elemento numero +i ; JComboBox cbox=new JComboBox( l i s t a ) ; Container c = win. getcontentpane ( ) ; c. add ( cbox ) ; win. s e t S i z e ( 2 0 0, ) ; win. s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame. EXIT ON CLOSE ) ; win. s e t V i s i b l e ( true ) ; Listato 2: Esempio di uso dei ComboBox Ogni volta che l utente attiva uno dei pulsanti registrati presso il ButtonGroup, gli altri vengono automaticamente messi a riposo. I JComboBox offrono all utente la possibilità di effettuare una scelta a partire da un elenco elementi, anche molto lungo. A riposo il componente si presenta come un pulsante, con l etichetta corrispondente al valore attualmente selezionato. Un clic del mouse provoca la comparsa di un menu provvisto di barra laterale di scorrimento, che mostra le opzioni disponibili. Se si imposta la proprietà editable di un JComboBox a true esso si comporterà a riposo come un JTextField, permettendo all utente di inserire valori non presenti nella lista. È possibile creare un JComboBox usando i seguenti costruttori: JComboBox ( ) ; JComboBox( Object [ ] items ) ; Il secondo costruttore permette di inizializzare il componente con una lista di elementi di qualsiasi tipo (ad esempio String). Se viene aggiunto al ComboBox un oggetto generico (ad esempio un oggetto Libro), allora il valore corrispondente visualizzato nella lista delle opzioni è quello ottenuto chiamando sull oggetto il metodo tostring(). Quindi se si desidera aggiungere oggetti generici (magari definiti all interno del programma), bisognerà
12 5 L ereditarietà per personalizzare i frame 11 Fig. 5: Uso di ComboBox. avere la cura di ridefinire tale metodo. Un gruppo di metodi permette di aggiungere, togliere o manipolare gli elementi dell elenco, così come si fa con un Vector: public void additem ( Object anobject ) ; public void removeitem ( Object anobject ) public void removeitemat ( int anindex ) ; public void removeallitems ( ) ; public Object getitemat ( int index ) ; public int getitemcount ( ) ; public void insertitemat ( Object anobject, int index ) Per ottenere l elemento correntemente selezionato, è disponibile il metodo: public Object g e t S e l e c t e d I t e m ( ) ; La Figura 5 mostra un esempio di suo uso. Il Listato 2 rappresenta il codice corrispondente. 5 L ereditarietà per personalizzare i frame Aggiungendo ad un frame molti componenti dell interfaccia utente, il frame stesso può diventare abbastanza complesso: per frame che contengono molti componenti è opportuno utilizzare l ereditarietà. Infatti, se il software che si sta sviluppando contiene molte finestre ricche di componenti ci si troverebbe a dover fronteggiare una soluzione il cui caso limite è di un metodo main che contiene la definizione di tutte le finestre del programma. Senza arrivare a
13 5 L ereditarietà per personalizzare i frame 12 import javax. swing. ; import java. awt. ; class MyFrame extends JFrame JLabel j l = new JLabel ( Buona Lezione ) ; public MyFrame ( ) super ( Prima f i n e s t r a ) ; Container c = this. getcontentpane ( ) ; c. add ( j l ) ; this. s e t S i z e ( 2 0 0, ) ; this. s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame. EXIT ON CLOSE ) ; this. s e t V i s i b l e ( true ) ; public class A p p l i c a t i o n public static void main ( S t r i n g args [ ] ) MyFrame = new MyFrame ( ) ; Listato 3: Esempio con l ereditarietà questa situazione, si otterrebbero moduli sono molto accoppiati e poco coesi; inoltre, gli stessi moduli sarebbero poco leggibili e non sarebbe facile manutenerli. In parole povere, non si sfrutterebbe le potenzialità dell Object Orientation: non sarebbe possibile permette l information hiding dei contenuti dei frame e dei controlli in essi contenuti; non sarebbe nemmeno sfruttato l incapsulamento delle implementazione, mettendo insieme concetti eterogenei e finestre diverse tra loro. Il Listato 3 produce la stessa finestra in Figura 3 sfruttando l ereditarietà. La differenza rispetto agli esempi già visti non è da poco: a questo punto ogni finestra diventa una nuova classe che, ereditando da JFrame, è un modello per le finestre. É opportuno definire gli oggetti che mappano i widgets come variabili di instanza (nel l esempio l unico widget è una etichetta (JLabel). La definizione della finestra e dei componenti contenuti viene fatta direttamente nel costruttore (o in metodo chiamati da questo). La prima istruzione chiama il costruttore della superclasse che prende come parametro una stringa;
14 6 Layout Management 13 in questo modo è possibile impostare il titolo della finestra. Infatti, se non fosse stato esplicitamente chiamato il costruttore ad un parametro String, sarebbe stato chiamato implicitamente il costruttore della superclasse di default (quello senza parametri) prima di continuare l esecuzione di quello della classe derivata. Il costruttore senza parametri avrebbe impostato a vuoto il titolo della finestra. 1 Il resto del costruttore è simile alla tecnica di definizione delle finestre degli esempi precedenti con l unica differenza che i metodi sono chiamati su this (cioè se stesso) perchè a questo punto i metodi da chiamare sono quelli ereditati dalla superclasse JFrame. 6 Layout Management Quando si dispongono i componenti all interno di un Container sorge il problema di come gestire il posizionamento: infatti, sebbene sia possibile specificare le coordinate assolute di ogni elemento dell interfaccia, queste possono cambiare nel corso della vita del programma allorquando la finestra principale venga ridimensionata. In molti Container i controlli sono inseriti da sinistra verso destra con su una ipotetica riga: può non essere sempre la politica per la GUI (Graphic User Interface) desiderata. Per semplificare il lavoro di impaginazione e risolvere questo tipo di problemi possibile ricorrere ai layout manager, oggetti che si occupano di gestire la strategia di posizionamento dei componenti all interno di un contenitore. Un gestore di layout è una qualsiasi classe che implementa l interfaccia LayoutManager; ogni container nasce con un certo Layout Manager ma è possibile assegnare il più opportuno per quel Container con il metodo: public void setlayout ( LayoutManager m) ; Il primo layout da essere citato è il gestore a scorrimento (Flow Layout) che sono inseriti da sinistra verso destra con la loro Preferred Size, cioè la dimensione minima necessaria a disegnarlo interamente. Usando il paragone con un editor di testi, ogni controllo rappresenta una parola che ha una sua propria dimensione. Come le parole in un editor vengono inseriti da sinistra verso destra finchè entrano in una riga, così viene fatto per i controlli inseriti da sinistra verso destra. Quando un componente non entra in una riga viene posizionato in quella successiva. I costruttori più importanti di oggetti FlowLayout sono i seguenti: public FlowLayout ( ) ; public FlowLayout ( int a l l i n ) ; 1 A dire il vero, sarebbe stato possibile impostare il titolo della finestra in un secondo momento modificando la proprietà Title: settitle( Prima Finestra );
15 6 Layout Management 14 (a) (b) Fig. 6: Aspetto grafico del frame definito nel Listato 4 e comportamento del Flow Layout rispetto al ridimensionamento Il secondo costruttore specifica l allineamento dei controlli su una riga; il parametro può essere una delle seguenti costanti che rispettivamente allineano a sinistra, centro o destra: FlowLayout. LEFT FlowLayout.CENTER FlowLayout. RIGHT Il costruttore di default imposta l allineamento centrale. Il Listato 4 mostra un esempio di uso del Flow Layout. L aspetto del frame risultato è mostrato in Figura 6. É opportuno osservare come l allineamento dei componenti del frame si adatti durante l esecuzione quando la stessa finestra viene ridimensionata (vedi situazione 6(b)). Ovviamente se non esiste nessun allineamento per i componenti del frame tale che tutti siano contemporaneamente visibile, allora alcuni di questi risulteranno in parte o del tutto non visibili; per esempio, la finestra è troppo piccola. Il gestore a griglia (GridLayout) suddivide il contenitore in una griglia di celle di uguali dimensioni. Le dimensioni della griglia vengono definite mediante il costruttore: public GridLayout ( int rows, int columns ) in cui i parametri rows e columns specificano rispettivamente le righe e le colonne della griglia. A differenza di quanto avviene con FlowLayout, i componenti all interno della griglia assumono automaticamente la stessa dimensione, dividendo equamente lo spazio disponibile. L esempio descritto nel Listato 5 permette di illustrare il funzionamento di questo pratico layout manager; il risultato è in Figura 7. Il gestore a bordi (BorderLayout) suddivide il contenitore esattamente in cinque aree, disposte a croce, come nella Figura 8. Ogni zona può contenere uno ed un solo widget (o Container): un secondo widget inserito in una zona sostituisce il precedente. Se una o più zone non vengono riempite, allora i componenti nelle altre zone sono estesi a riempire le zone vuote. Il
16 6 Layout Management 15 import javax. swing. ; import java. awt. ; public c l a s s MyFrame extends JFrame JButton uno=new JButton ( Uno ) ; JButton due=new JButton ( Due ) ; JButton t r e=new JButton ( Tre ) ; JButton quattro=new JButton ( Quattro ) ; JButton cinque = new JButton ( Cinque ) ; public MyFrame ( ) super ( Flow Layout ) ; Container c = this. getcontentpane ( ) ; c. setlayout (new FlowLayout ( ) ) ; c. add ( uno ) ; c. add ( due ) ; c. add ( t r e ) ; c. add ( quattro ) ; c. add ( cinque ) ; s e t S i z e ( 3 0 0, ) ; s e t V i s i b l e ( true ) ; public class A p p l i c a t i o n public static void main ( S t r i n g args [ ] ) MyFrame = new MyFrame ( ) ; Listato 4: Uso del Flow Layout
17 6 Layout Management 16 public c l a s s MyFrame extends JFrame public MyFrame ( ) super ( Grid Layout ) ; Container c = this. getcontentpane ( ) ; c. setlayout (new GridLayout ( 4, 4 ) ) ; for ( int i = 0 ; i <15; i ++) c. add (new JButton ( S t r i n g. valueof ( i ) ) ; s e t S i z e ( 3 0 0, ) ; s e t V i s i b l e ( true ) ; Listato 5: Uso del Grid Layout Fig. 7: Aspetto grafico del frame definito nel Listato 5.
18 6 Layout Management 17 Fig. 8: Le aree di una disposizione a bordi BorderLayout è il gestore di layout di default per la Lastra dei Contenuti di un JFrame. Il programmatore può decidere in quale posizione aggiungere un controllo utilizzando la variante presente nei Container: public void add ( Component c, S t r i n g s ) ; dove il primo parametro specifica il componente da aggiungere e il secondo indica la posizione. I valori validi per il secondo parametro sono le costanti: BorderLayout.NORTH BorderLayout.SOUTH BorderLayout.CENTER BorderLayout.EAST BorderLayout.WEST Si osservi l esempio nel Listato 6. In aggiunta ai layout managers descritti in questa dispensa ne esistono ulteriori che sono standard Java: 2 BoxLayout Questo manager pone i componenti in una singola riga o colonna. Esso rispetta le dimensioni preferite e permette al programmatore di decidere l allineamento CardLayout Quando viene utilizzato questo layout manager, il container può contenere componente differenti in momenti diversi. Per esempio è possibile utilizzare un Combo Box per determinare quale pannello/- container interno viualizzare. In alternativa è possibile utilizzare un JTabbedPane (non descritto in questa dispensa), che fornisce una simile funzionalità utilizzando una interfaccia grafica simile ad un cartella di un archivio con diverse linguette. 2 All indirizzo è possibile leggere tutti i dettagli sul loro funzionamento
19 6 Layout Management 18 public c l a s s MyFrame extends JFrame JButton nord = new JButton ( Nord ) ; JButton c e n t r o = new JButton ( Centro ) ; JButton ovest=new JButton ( Ovest ) ; public MyFrame ( ) super ( Border Layout ) ; Container c = this. getcontentpane ( ) ; c. setlayout (new BorderLayout ( ) ) ; c. add ( nord, BorderLayout.NORTH) ; c. add ( centro, BorderLayout.CENTER) ; c. add ( ovest, BorderLayout.WEST) ; s e t S i z e ( 3 0 0, ) ; s e t V i s i b l e ( true ) ; Listato 6: Uso del Border Layout GridBagLayout GridBagLayout è un layout manager molto sofisticato. Il suo funzionamento è simile al GridLayout ma con la possibilità che certi widget occupino più celle della griglia. SpringLayout SpringLayout è molto flessibile ed è pensato soprattutto per essere utilizzato con tool automatici che permettono al programmatore di disegnare finestra come in un programma di grafica e automaticamente generano i codice relativo. Esso permette di specificare precisamente la relazione tra i bordi dei componenti. Ad esempio, è possibile specificare che il bordo sinistro di un componente è ad una certa distanza dal bodo destro di un secondo componente. Mentre chiunque può definire un proprio layout semplicemente implementando l interfaccia LayoutManager, è anche possibile disattivare ogni layout manager è utilizzare il cosiddetto posizionamento assoluto. Sebbene sia possibile posizionare senza un layout manager, questa soluzione dovrebbe essere evitata quanto più possibile. Un layout manager rende più semplice modificare l aspetto dei componenti, che può in parte dipendere dalla piattaforma ospite, tenendo in conto la dimensione dei fonti, delle finestre. Inoltre i layout manager sono in grado di riorganizzare automaticamente il riposizionamento dei widget quando la finestra cambia di dimensione.
20 6 Layout Management 19 Tuttavia ci sono casi in cui è consigliabile l uso di un posizionamento senza layout manager poichè l aspetto che si desidera ottenere non è facilmente realizzabile come combinazione di altri layout manager. Per aggiungere componenti senza un manager occorre seguire i seguenti passi: 1. Impostare il layout manager a chiamando: miocontainer. setlayout ( null ) ; 2. Per ogni componente che si desidera aggiungere, occorre specificare la posizione in pixel dell angolo superiore sinistro, insieme con la larghezza e l altezza desiderata. La posizione in pixel è determinata relativamente all angolo superiore sinistro del container nel quale si desidera aggiungere il componente. Il seguente esempio specifica per il componente b1 una posizione a partire dalla coordinata (10,10), una larghezza di 30 pixel ed un altezza di 40: b1. setbounds (10, 10, 30, 4 0 ) ; 3. Aggiungere ogni componente al container come viene fatto solitamente. In generale la posizione e la dimensione non è mai data come valore assoluto ma è sempre parametrica rispetto alle dimensione delle finestre/container e degli altri controlli: Dimension b1size=b1. g e t P r e f e r r e d S i z e ( ) ; b1. setbounds (10, 10, b1size. width, b1size. h e i g h t ) ; Dimension b2size=b2. g e t P r e f e r r e d S i z e ( ) ; b2. setbounds (10+ b1size. width, 10, b2size. width, b2size. h e i g h t ) ; In questo caso si desidera posizionare il widget b1 a partire dalla coordinata (10,10) e farlo di una dimensione pari a quella preferibile. Inoltre, si vuole che il b2 sia affiancato a b1. Di conseguenza, la coordinata x della posizione di b2 sarà pari a quella di b1 cui viene aggiunta una quantità pari alla dimensione di b1. Il Listato 7 mostra un esempio completo dell uso di questo layout, il cui risultato è mostrato in Figura 9. Comunque, è ancora importante sottolineare che il posizionamento assoluto può creare problemi quando la finestra viene ridimensionata. Per questa ragione nel proseguo di questa dispensa ignoreremo sempre questo layout.
21 6 Layout Management 20 public c l a s s MyFrame extends JFrame JButton b1 = new JButton ( uno ) ; JButton b2 = new JButton ( nessuno ) ; JButton b3 = new JButton ( centomila ) ; JButton b4 = new JButton ( che a l t r o?? ) ; public MyFrame ( ) super ( Null Layout ) ; Container c = this. getcontentpane ( ) ; c. setlayout ( null ) ; Dimension b1size=b1. g e t P r e f e r r e d S i z e ( ) ; b1. setbounds (10, 10, b1size. width, b1size. h e i g h t ) ; Dimension b2size=b2. g e t P r e f e r r e d S i z e ( ) ; b2. setbounds (10+ b1size. width, 10, b2size. width, b2size. h e i g h t ) ; Dimension b3size=b3. g e t P r e f e r r e d S i z e ( ) ; b3. setbounds (10+ b1size. width+b2size. width, 10, b3size. width, b3size. h e i g h t ) ; Dimension b4size=b4. g e t P r e f e r r e d S i z e ( ) ; b4. setbounds (10, 10+b1Size. height, b1size. width+b2size. width+b3size. width, b4size. h e i g h t ) ; c. add ( b1 ) ; c. add ( b2 ) ; c. add ( b3 ) ; c. add ( b4 ) ; s e t S i z e ( 3 0 0, ) ; s e t V i s i b l e ( true ) ; Listato 7: Uso del Null Layout Fig. 9: Aspetto grafico del frame definito nel Listato 7.
22 7 Progettazione della GUI con le gerarchie di contenimento 21 7 Progettazione della GUI con le gerarchie di contenimento I gestori di layout permettono maggiore versatilità nell inserimento dei controlli nelle finestre. Tuttavia nella stragrande maggioranza delle situazioni un intera finestra non può seguire un unico layout. Si prenda, ad esempio, in considerazione il frame in Figura 10. Non è difficile convincersi che la parte in alto contenente una sorta di tastierino numerico segue un Grid- Layout mentre i bottoni in basso seguono un FlowLayout centrato. Poichè Fig. 10: Un frame più complesso ogni Container può seguire uno ed un unico layout, occorre predisporre più Container, uno per ogni zona che ha un layout differente. Ovviamente ad ogni Container possono essere aggiunti direttamente i controlli oppure altri Container. La lastra dei contenuti è il Container radice ed altri si possono aggiungere all interno. I Container (insieme con i componenti contenuti) aggiunti in un altro Container si comporteranno come ogni altro widget la cui dimensione preferita è quella minima necessaria a visualizzare tutti i componenti all interno. Per creare nuovi Container conviene utilizzare la classe javax.swing.jpanel che eredita da java.awt.container. La forza di questa soluzione è data dall alta modularità: è possibile usare un layout per il pannello interno e un altro layout per il ContentPane. Il pannello interno verrà inserito nella finestra coerentemente con il layout della lastra dei contenuti. Inoltre all interno pannelli interni se ne possono inserire
23 7 Progettazione della GUI con le gerarchie di contenimento 22 altri con loro layout e così via, come nel gioco delle scatole cinesi. Il numero di soluzioni diverse sono praticamente infinite. Ad esempio per il frame in Figura 10 è possibile creare due contenitoripannelli JPanel: uno per contenere il tastierino numerico organizzato il GridLayout ed un altro il FlowLayout per i tre bottoni in basso. La lastra dei Contenuti viene lasciata in BorderLayout: al centro viene aggiunto il pannello tastierino ed a sud il pannello con i tre bottoni. 7.1 Progettazione top down di interfacce grafiche Durante la progettazione delle interfacce grafiche, può essere utile ricorrere a un approccio top down, descrivendo l insieme dei componenti a partire dal componente più esterno per poi procedere a mano a mano verso quelli più interni. Si può sviluppare una GUI come quella dell esempio precedente seguendo questa procedura: 1. Si definisce il tipo di top level container su cui si vuole lavorare (tipicamente un JFrame). 2. Si assegna un layout manager al content pane del JFrame, in modo da suddividerne la superficie in aree più piccole. 3. Per ogni area messa a disposizione dal layout manager è possibile definire un nuovo JPanel. Ogni sotto pannello può utilizzare un layout manager differente. 4. Ogni pannello identificato nel terzo passaggio può essere sviluppato ulteriormente, creando al suo interno ulteriori pannelli o disponendo dei controlli. Il risultato della progettazione può essere rappresentato con un albero della GUI. L obiettivo di tale albero è mostrare come i Container (a partire dalla lastra dei contenuti) sono stati suddivisi per inserire i componenti o altri Container. Ogni componente (o Container) è rappresentato da un nodo i cui figli sono i componenti (o i Container) contenuti all interno e il padre è il componente che lo contiene. Una volta conclusa la fase progettuale, si può passare a scrivere il codice relativo all interfaccia: in questo secondo momento, è opportuno adottare un approccio bottom up, realizzando dapprima il codice relativo ai componenti atomici, quindi quello dei contenitori e infine quello del JFrame.
24 7 Progettazione della GUI con le gerarchie di contenimento 23 Fig. 11: Un frame d esempio JFrame BorderLayout nordpnl FlowLayout centropnl GridLayout (2,1) sudpnl FlowLayout infolbl opz1chk opz2chk okbtn Fig. 12: Un frame più complesso cancbtn Esempio di Progettazione Top-Down Un esempio finale viene mostrato per riassumere quanto è stato finora detto. Si inizierà mostrando la progettazione top-down dell interfaccia e si concluderá mostrandone la realizzazione bottom-up. Si consideri la semplice finestra in Figura 11. L albero della GUI corrispondente è in Figura 12. Il codice per mostrare tale finestra è nel Listato 8. Si osservi l invocazione del metodo pack() che sostituisce il metodo setsize(x,y) e che imposta la dimensione della finestra alla minima necessaria a visualizzare tutti i controlli. Inoltre si osservi come le due istruzioni successive hanno lo scopo di centrare la finestra sullo schermo. Il metodo getscreensize() chiamato sulla classe Singleton 3 Toolkit del package java.awt restituisce un riferimento ad un oggetto java.awt.dimension. Questo possiede due proprietà Width e Height che, nel caso specifico, conterranno la dimensione dello schermo in pixel. L istruzione successiva sposta la finestra al centro dello schermo con il 3 Una classe Singleton è tale che di essa esista sempre al più una instanza.
25 7 Progettazione della GUI con le gerarchie di contenimento 24 public c l a s s MyFrame extends JFrame JPanel nordpnl = new JPanel ( ) ; JPanel centropnl = new JPanel ( ) ; JPanel sudpnl = new JPanel ( ) ; JLabel i n f o L b l = new Label ( S e l e z i o n a r e : ) ; JCheckBox opz1chk = new JCheckBox ( Opz1 ) ; JCheckBox opz2chk = new JCheckBox ( Opz2 ) ; JButton okbtn=new JButton ( OK ) ; JButton cancbtn=new JButton ( Annulla ) ; public MyFrame ( ) super ( Esempio ) ; centropnl. setlayout (new GridLayout ( 2, 1 ) ) ; centropnl. add ( opz1chk ) ; centropnl. add ( opz2chk ) ; nordpnl. add ( i n f o L b l ) ; sudpnl. add ( okbtn ) ; sudpnl. add ( cancbtn ) ; getcontentpane ( ). add ( nordpnl, BorderLayout.NORTH) ; getcontentpane ( ). add ( centropnl, BorderLayout.CENTER) ; getcontentpane ( ). add ( sudpnl, BorderLayout.SOUTH) ; pack ( ) ; Dimension dim= T o o l k i t. g e t D e f a u l t T o o l k i t ( ). g e t S c r e e n S i z e ( ) ; s e t L o c a t i o n ( ( dim. getwidth() this. getwidth ( ) ) / 2, ( dim. getheight () this. getheight ( ) ) / 2 ) ; s e t V i s i b l e ( true ) ; Listato 8: Il codice della figura 11
26 8 Realizzare finestre di dialogo con JOptionPane 25 metodo setlocation(int x,int y) dove x, y sono le coordinate dell angolo in alto a sinistra. 8 Realizzare finestre di dialogo con JOptionPane La classe JOptionPane del package Swing permette di realizzare facilmente finestra modali di input, di allarme o di conferma. Le API di JOptionPane mettono a disposizione tre tipi di pannelli: Confirm, Input e Message Dialog. Il primo viene usato quando si deve chiedere all utente di effettuare una scelta tra un gruppo di possibilità, il secondo torna utile quando si deve richiedere l inserimento di una stringa di testo mentre il terzo viene usato per informare l utente. La classe JOptionPane fornisce un gruppo di metodi statici che permetto di creare facilmente queste finestre ricorrendo ad una sola riga di codice. In questo paragrafo ci si concentrerà sull uso di un sottoinsieme di tali metodi, nella convinzione che essi permettano di risolvere la stragrande maggioranza delle situazioni in modo compatto ed elegante. Una finestra di conferma personalizzata si costruisce utilizzando il seguente metodo statico che ammette due forme: int showconfirmdialog ( Component parent, Object Message ) int showconfirmdialog ( Component parent, Object Message, S t r i n g t i t l e, int optiontype, int messagetype ) Il metodo restituisce uno dei seguenti valori a seconda se il bottone premuto è rispettivamente Si, No, Annulla, Ok: JOptionPane. YES OPTION JOptionPane. NO OPTION JOptionPane.CANCEL OPTION JOptionPane. OK OPTION Una finestra di messaggio si costruisce con il seguente metodo statico che ammette due forme: void showmessagedialog ( Component parent, Object Message ) void showmessagedialog ( Component parent, Object Message, S t r i n g t i t l e, int messagetype ) Una finestra di input si ottiene con il seguente metodo statico che ammette tre forme: Object showinputdialog ( Component parent, Object Message ) Object showinputdialog ( Component parent, Object Message, S t r i n g t i t l e, int messagetype ) Object showinputdialog ( Component parent, Object Message, S t r i n g t i t l e, int messagetype, Icon icon,
27 8 Realizzare finestre di dialogo con JOptionPane 26 import javax. swing. JOptionPane ; public class A p p l i c a t i o n public static void main ( S t r i n g args [ ] ) JOptionPane. showmessagedialog ( null, Ciao!, F i n e s t r a di messaggio, JOptionPane. INFORMATION MESSAGE) ; int yn=joptionpane. showconfirmdialog ( null, S a l v a r e l e modifiche?, S e l e z i o n e, JOptionPane. YES NO CANCEL OPTION, JOptionPane.QUESTION MESSAGE) ; i f ( yn==joptionpane. NO OPTION) return ; S t r i n g prova ; prova=( S t r i n g ) JOptionPane. showinputdialog ( null, s t a t o di r e s i d e n z a :, S e l e z i o n e, JOptionPane.INFORMATION MESSAGE, null, null, I t a l i a ) ; S t r i n g x []= a, b, c, d, e, f, g ; prova=( S t r i n g ) JOptionPane. showinputdialog ( null, S c e g l i l opzione :, S e l e z i o n e, JOptionPane.INFORMATION MESSAGE, null, x, x [ 3 ] ) ; Listato 9: Esempi di uso delle finestre di dialogo Object [ ] SelectedValues, Object i n i t i a l V a l u e ) Il metodo restituisce la stringa (come Object e quindi su cui è necessario fare il cast) inserita nell InputDialog oppure null se è stato premuto il bottone annulla. I parametri dei metodi appena illustrati sono descritti in Tabella 1. La sezione si conclude con il Listato 9 dove vengono illustrati alcuni esempi di uso delle finestre di dialogo.
28 9 La Gestione degli Eventi 27 9 La Gestione degli Eventi Fig. 13: La gestione ad event delegation La gestione degli eventi grafici in Java segue il paradigma event delegation (conosciuto anche come event forwarding). Ogni oggetto grafico è predisposto ad essere sollecitato in qualche modo dall utente e ad ogni sollecitazione genera eventi che vengono inoltrati ad appositi ascoltatori, che reagiscono agli eventi secondo i desideri del programmatore. L event delegation presenta il vantaggio di separare la sorgente degli eventi dal comportamento a essi associato: un componente non sa (e non è interessato a sapere) cosa avverrà al momento della sua sollecitazione: esso si limita a notificare ai propri ascoltatori che l evento che essi attendevano è avvenuto, e questi provvederanno a produrre l effetto desiderato. Ogni componente può avere più ascoltatori per un determinato evento o per eventi differenti, come anche è possibile installare uno stesso ascoltatore su più componenti anche diversi a patto che entrambi possono essere sollecitati per generare l evento. L operazione di installare lo stesso ascoltatore su più controlli (che quindi si comporteranno nello stesso modo se sollecitati dallo stesso evento) è frequente: si pensi alle voci di un menu che vengono replicate su una toolbar per un più facile accesso ad alcune funzionalità frequenti 9.1 Implementazione dell event delegation Il gestore delle finestre può generare un numero enorme di eventi (sono eventi muovere il mouse nella finestra, spostare o ridimensionare una finestra, scri-
29 9 La Gestione degli Eventi 28 vere o abbandonare un campo di testo,... ). Molte volte si è interessati a pochi di questi eventi. Per fortuna, il programmatore può considerare solo gli eventi di cui ha interesse, gestendoli con un ascoltatore opportuno, ignorando completamente tutti gli altri che di default verranno gestiti come eventi vuoti. Quando accade un evento per il quale esiste un ricevitore, la sorgente dell evento chiama i metodi da voi forniti nell ricevitore, dando, in un oggetto di una classe evento, informazioni più dettagliate sull evento stesso. In generale sono coinvolte tre classi: La classe del ricevitore. Implementa una particolare interfaccia del tipo XXXListener tipica degli eventi di una certa classe. I metodi dell interfaccia che la classe dell ascoltatore implementa contengono il codice eseguito allo scatenarsi degli eventi di una classe che l ascoltatore intercetta. Grazie al fatto che ogni ascoltatore è caratterizzato da una particolare interfaccia Java, qualsiasi classe può comportarsi come un ascoltatore, a patto che fornisca un implementazione per i metodi definiti dalla corrispondente interfaccia listener L origine dell evento. É il componente che genera l evento che si vuole gestire su cui si vuole installare l ascoltatore. Ogni componente dispone per ogni evento supportato di due metodi: void addxxxlistener ( XXXListener a s c o l t a t o r e ) ; void removexxxlistener ( XXXListener a s c o l t a t o r e ) ; La classe evento. Contiene le informazioni riguardanti le caratteristiche dell evento generato. Gli oggetti di questa classe sono istanziati direttamente dai componenti che notificano eventi agli ascoltatori. Formalmente sono parametri di input dei metodi dell interfaccia implementata dall ascoltatore. Nel momento in cui il componente viene sollecitato, esso chiama gli ascoltatori in modalità callback, passando come parametro della chiamata un apposita sottoclasse di Event. Queste classi contengono tutte le informazioni significative per l evento stesso e possono essere utilizzate per modificare il comportamento dell ascoltatore in base alle informazioni sull evento scatenato Le classi che permettono di gestire gli eventi generati dai componenti Swing sono in gran parte gli stessi utilizzati dai corrispondenti componenti AWT, e si trovano nel package java.awt.event. Alcuni componenti Swing, tuttavia, non hanno un omologo componente AWT: in questo caso le classi necessarie a gestirne gli eventi sono presenti nel package javax.swing.event.
30 9 La Gestione degli Eventi Un esempio: elaborare gli eventi del mouse Per chiarire il funzionamento, a prima vista complesso, della gestione degli eventi Swing, verra fatto un esempio. In particolare, vogliamo realizzare un meccanismo per spiare gli eventi del mouse su una finestra e stamparli. Una classe che desidera catturare gli eventi del mouse deve implementare l interfaccia MouseListener definita nel package java.awt.event che è così definita: public interface MouseListener void mouseclicked ( MouseEvent e ) ; void mouseentered ( MouseEvent e ) ; void mouseexited ( MouseEvent e ) ; void mousepressed ( MouseEvent e ) ; void mousereleased ( MouseEvent e ) ; dove MouseEvent è la corrispondente classe evento il cui scopo è dare informazioni aggiuntive sull evento del mouse. Infatti, questa definisce due metodi che permettono di conoscere le coordinate del mouse allo scatenarsi dell evento (i primi due) e un terzo metodo che permette di determinare quale bottone del mouse è stato premuto: int getx ( ) ; int gety ( ) ; int g e t M o d i f i e r s ( ) Nel codice del Listato 10 viene mostrata l implementazione della spia. Si noti come la classe ascoltatore MouseSpy implementi l interfaccia MouseListener e come la classe definisca due metodi vuoti: mouseentered e mouseexited. La definizione dei due metodi vuoti ha lo scopo di dichiarare che gli eventi legati all entrata e all uscita del mouse dall area della finestra devono essere ignorati. In effetti, ignorare gli eventi è già il comportamento di default e quindi tale dichiarazione è superflua. La ragione per cui è stata comunque dichiarata la gestione di tali eventi è legata al linguaggio Java: affinché una classe implementi una interfaccia, tale classe deve implentare tutti i metodi dell interfaccia. E questo vale anche in questo caso: la classe MouseSpy deve implementare tutti i metodi dell interfaccia MouseListener per poter dichiarare di implementarla. Nella Tabella 2 sono riassunti gli ascoltatori più importanti. Per ulteriori dettagli si consiglia di consultare la documentazione Java Swing.
31 9 La Gestione degli Eventi 30 import java. awt. event. ; import javax. swing. ; public class MouseSpy implements MouseListener public void mouseclicked ( MouseEvent e ) System. out. p r i n t l n ( C l i c k su ( +e. getx()+, +e. gety ()+ ) ) ; public void mousepressed ( MouseEvent e ) System. out. p r i n t l n ( Premuto su ( +e. getx ()+, +e. gety()+ ) ) ; public void mousereleased ( MouseEvent e ) System. out. p r i n t l n ( R i l a s c i a t o su ( +e. getx()+, +e. gety ()+ ) ) public void mouseentered ( MouseEvent e ) public void mouseexited ( MouseEvent e ) public c l a s s MyFrame extends JFrame public MyFrame ( ) super ( MouseTest ) ; this. addmouselistener (new MouseSpy ( ) ) ; s e t S i z e ( 2 0 0, ) ; s e t V i s i b l e ( true ) ; Listato 10: Primo esempio della gestione degli eventi
32 9 La Gestione degli Eventi 31 public interface WindowListener public void windowopened ( WindowEvent e ) ; public void windowclosing ( WindowEvent e ) ; public void windowclosed ( WindowEvent e ) ; public void windowiconified ( WindowEvent e ) ; public void windowdeiconified ( WindowEvent e ) ; public void windowactivated ( WindowEvent e ) ; public void windowdeactivated ( WindowEvent e ) ; Listato 11: L interfaccia MouseListener c l a s s WindowClosedListener extends WindowAdapter public void windowclosed ( WindowEvent e ) // c o d i c e da e s e g u i r e a l l a chiusura d e l l a f i n e s t r a Listato 12: Esempio dell uso degli Adapter 9.3 Uso di adapter nella definizione degli ascoltatori Alcuni componenti grafici generano eventi così articolati da richiedere, per la loro gestione, ascoltatori caratterizzati da più di un metodo. Si è già visto che MouseListener, ne definisce tre. L interfaccia WindowListener (vedi Listato 11) ne dichiara addirittura sette, ossia uno per ogni possibile cambiamento di stato della finestra. Si è detto che se si desidera creare un ascoltatore interessato a un solo evento (per esempio uno che intervenga quando la finestra viene chiusa), esso dovrà comunque fornire un implementazione vuota anche dei metodi cui non è interessato. Nei casi come questo è possibile ricorrere agli adapter: classi di libreria che forniscono un implementazione vuota di un determinato ascoltatore. Per esempio, il package java.awt.event contiene la classe WindowAdapter, che fornisce un implementazione vuota di tutti i metodi previsti dall interfaccia. Una sottoclasse di WindowAdapter, pertanto, è un valido WindowListener, con in più il vantaggio di una maggior concisione. Si veda l esempio 12
33 10 La gestione degli eventi Azione 32 Fig. 14: La finestra ottenuta dal Listato La gestione degli eventi Azione La maggior parte dei componenti Swing generano eventi, noti come eventi azione, che possono essere catturati da un ActionListener. Essa definisce un unico metodo: public interface A c t i o n L i s t e n e r public void actionperformed ( ActionEvent ae ) ; L oggetto ActionEvent da informazioni aggiuntive sull evento generato. Ad esempio, definisce il metodo Object getsource() che restituisce l oggetto che ha generato l evento. La maggior parte dei widget java sono predisposti per generare eventi azione. Ad esempio quando si clicca su un bottone, si preme INVIO in un campo di testo, si seleziona una voce di un menu oppure si seleziona/deseleziona una voce di una checkbox o un radiobutton, viene generato un evento azione. Si potrebbe obiettare che, la gestione del click di un bottone, potrebbe essere fatta usando un mouselistener. Il vantaggio di utilizzare un evento azione risiede nel fatto che è possibile cliccare su un bottone anche con la tastiera (anche se in quel caso non è un vero click!): l utente con il tasto TAB potrebbe spostarsi sulla schermata, mettere il focus su un bottone e qui premere la barra spaziatrice per voler cliccare sul bottone. É possibile installare uno stesso ascoltatore, ad esempio, per un bottone della toolbar e una voce di menu. Il vantaggio risiede nel fatto che sia la voce del menu che il bottone hanno lo stesso ascoltatore invece che due ascoltatori separati che fanno la stessa cosa. Un primo esempio di uso degli eventi azione è nel Listato 13. Il comportamento è quello in Figura 14: quando l utente seleziona uno dei bottoni della finestra MyFrame viene aperta una finestra di dialogo con il testo del bottone premuto. Su ogni bottone è installato lo stesso ascoltatore per gli eventi azione. Alla pressione di un bottone viene eseguito il metodo action-
34 11 Accedere dall ascoltatore agli oggetti di una finestra 33 Fig. 15: La finestra ottenuta dal Listato 14 Performed, il quale si fa restituire con il metodo getsource() il bottone premuto (si noti il cast giacchè il metodo lo restituisce come riferimento ad Object). A partire dal bottone premuto, con il metodo gettext() viene restituito il testo visualizzato nel bottone. 11 Accedere dall ascoltatore agli oggetti di una finestra L approccio finora descritto funziona abbastanza bene anche se presenta ancora alcune problematiche. Il primo problema è legato al fatto che la finestra e i suoi ascoltatori sono divisi in classi separate. Supponiamo di avere ascoltatori per gestire gli eventi scatenati da alcuni componenti installati in una data finestra. Essendo le due classi formalmente indipendenti tra loro, per quanto detto, non è possibile accedere dagli ascoltatori a tutti i componenti della finestra (tranne il componente che ha generato l evento). Supponiamo di voler realizzare una finestra come quella in Figura 15. Alla pressione del bottone OK il contenuto del campo di testo deve essere visualizzato in un message dialog box. Si consideri il codice nel Listato 14. Nell ascoltatore definiamo un nuovo JTextField text. Quest approccio non funziona perchè il campo di testo definito è un nuovo campo di testo e non quello della finestra. Quindi la pressione del bottone mostrerà sempre una finestra dal contenuto vuoto perchè di default un campo di testo viene inizializzato con il contenuto vuoto. Un primo approccio è utilizzare una classe interna. Una classe interna è definita all interno di un altra classe e può accedere a tutte le variabili e i metodi di istanza della classe esterna (anche a quelli privati). Si consideri il Listato 15 che fa uso della classi interne: l istruzione text = txt nell ascoltatore fa sì che il riferimento text punti allo stesso campo di testo riferito da txt. Quindi quando nel codice successivo, l ascoltatore chiede text.gettext() ottiene effettivamente il codice richiesto. Questa tecnica è accettabile se l ascoltatore esegue poche operazioni e pochi ascoltatori esistono. Altrimenti la classe MyFrame diventa eccessiva-
35 11 Accedere dall ascoltatore agli oggetti di una finestra 34 public c l a s s MyFrame extends JFrame private JButton uno = new JButton ( Uno ) ; private JButton due = new JButton ( Due ) ; private JButton t r e = new JButton ( Tre ) ; private JButton quattro = new JButton ( Quattro ) ; private JButton cinque = new JButton ( Cinque ) ; A s c o l t a t o r e l i s t e n e r = new A s c o l t a t o r e ( ) ; public MyFrame ( )... Container c = this. getcontentpane ( ) ; c. add ( uno ) ; uno. addactionlistener ( l i s t e n e r ) ;... c. add ( cinque ) ; cinque. addactionlistener ( l i s t e n e r ) ; public class A s c o l t a t o r e implements A c t i o n L i s t e n e r public void actionperformed ( ActionEvent event ) JButton b = ( JButton ) event. getsource ( ) ; JOptionPane. showmessagedialog ( null, È s t a t o premuto +b. gettext ( ) ) ; Listato 13: Esempio uso di ActionPerformed
36 11 Accedere dall ascoltatore agli oggetti di una finestra 35 public c l a s s MyFrame extends JFrame JPanel c e n t r o = new JPanel ( ) ; JPanel sud = new JPanel ( ) ; JTextField txt = new JTextField ( 2 0 ) ; JButton button = new JButton ( Premi ) ; public MyFrame ( ) super ( Esempio ) ; c e n t r o. add ( txt ) ; sud. add ( button ) ; getcontentpane ( ). add ( centro, BorderLayout.CENTER) ; getcontentpane ( ). add ( sud, BorderLayout.SOUTH) ; button. addactionlistener (new L i s t e n ( ) ) ;... class L i s t e n implements A c t i o n L i s t e n e r public void actionperformed ( ActionEvent e ) JTextField t e x t = new JTextField ( ) ; JOptionPane. showmessagedialog ( null, t e x t. gettext ( ) ) ; Listato 14: Un esempio che non funziona
37 11 Accedere dall ascoltatore agli oggetti di una finestra 36 public c l a s s MyFrame extends JFrame JPanel c e n t r o = new JPanel ( ) ; JPanel sud = new JPanel ( ) ; JTextField txt = new JTextField ( 2 0 ) ; JButton button = new JButton ( Premi ) ; public MyFrame ( ) super ( Esempio ) ; c e n t r o. add ( txt ) ;... button. addactionlistener (new L i s t e n ( ) ) ;... class L i s t e n implements A c t i o n L i s t e n e r public void actionperformed ( ActionEvent e ) JTextField t e x t = txt ; JOptionPane. showmessagedialog ( null, t e x t. gettext ( ) ) ; Listato 15: Una soluzione che funziona con le classi interne
38 12 Condividere gli ascoltatori per più oggetti 37 mente grande. Inoltre il codice ottenuto diventa poco leggibile perchè si tende ad accorpare classi che rappresentano concetti diversi. La soluzione preferibile è quella in cui l ascoltatore definisce un costruttore che prende come parametro un riferimento alla finestra con i componenti richiesti. Il costruttore memorizza tale riferimento come variabile di classe. La classe ascoltatore resta comunque esterna: essa accede ai widget della finestra tramite tale riferimento e l operatore punto. Ovviamente i widget non devono essere memorizzati privati. La soluzione è descritta nel Listato 16. Nel codice viene anche mostrato una grande potenzialità degli eventi azione: l evento azione del campo di testo è gestito nello stesso modo della finestra. Ne risulta, di conseguenza, che la pressione del bottone e la pressione del tasto ENTER sul campo di testo vengono gestiti dallo stesso ActionListener e quindi gestiti nello stesso modo. 12 Condividere gli ascoltatori per più oggetti La tecnica più naive per gestire più eventi associati ad un controllo è quello di creare una classe ascoltatore per ogni oggetto e per ogni classe di eventi da gestire per quello oggetto. Ciò vorrebbe dire che se dovessimo gestire l evento di pressione di X bottoni, dovrebbe realizzare X classi che implementano ActionListener. Ovviamente è nella pratica improponibile prevedere una classe per ogni bottone, voce del menu e così via. Infatti, consideriamo per esempio un applicazione con 5 finestre, ognuna con 5 bottoni. Supponiamo che una di tali finestre abbia anche 3 voci del menu di 4 opzioni ciascuno. Ciò significherebbe che avremmo 37 classi solo per gestire la pressione dei bottoni o della voci del menu! L idea più elegante è raggruppare gli oggetti su cui ascoltare in classi, prevedendo un ascoltatore condiviso per tutti gli oggetti della stessa classe. Da questo punto in poi consideriamo solo gli eventi actionlistener senza perdere di generalità. Lo stesso approccio si applica in tutti gli altri casi. I componenti della stessa classe, ovviamente, condivideranno lo stesso metodo actionperformed. A meno che tutti i componenti della stessa classe si devo comportare nello stesso modo allo scatenarsi dell evento azione, occore essere in grado di capire quale oggetto ha generato l evento. Questo al fine di capire quale comportamente adottare. Esistono due modi per capire chi ha generato l evento: 1. Attraverso il metodo getsource() della classe ActionEvent che restituisce un riferimento all oggetto che ha scatenato l evento. In questo
39 12 Condividere gli ascoltatori per più oggetti 38 public c l a s s MyFrame extends JFrame JPanel c e n t r o = new JPanel ( ) ; JPanel sud = new JPanel ( ) ; JTextField txt = new JTextField ( 2 0 ) ; JButton button = new JButton ( Premi ) ; L i s t e n a s c o l t=new L i s t e n ( this ) ; public MyFrame ( ) super ( Esempio ) ; c e n t r o. add ( txt ) ;... button. addactionlistener ( a s c o l t ) ; txt. addactionlistener ( a s c o l t ) ;... class L i s t e n implements A c t i o n L i s t e n e r MyFrame frame ; public L i s t e n (MyFrame aframe ) frame = aframe ; public void actionperformed ( ActionEvent e ) JTextField t e x t = frame. txt ; JOptionPane. showmessagedialog ( null, t e x t. gettext ( ) ) ; Listato 16: La soluzione migliore
40 12 Condividere gli ascoltatori per più oggetti 39 modo è possibile utilizzare un approccio di tipo switch/case: se il riferimento punta a X, allora chiama un metodo privato che corrisponde alla gestione di pressione del bottone X; se il riferimento punta a Y, allora chiama il metodo per Y. E cosi via. E ovviamente chiaro se questa approccio è fattibile se è possibile confrontare i riferimenti ottenuti con il metodo getsource() con i riferimenti memorizzati internamente alla classe che estende JFrame e che disegna la finestra con i bottoni X, Y e gli altri. Questo approccio è generalmente fattibile, quindi, con le classi interne. 2. Utilizzando la proprietà actioncommand, implementata per ogni componente, che permette di associare una stringa identificativa univoca ad ogni componente che scatena un evento azione. A questo punto è possibile definire all interno del metodo actionperformed un approccio di tipo switch/case sugli actioncommand. Se lo actioncommand dell oggetto è ACTX (che è stato associato ad X) allora l ascoltatore esegue una certa porzione di codice, se lo actioncommand è ACTY fa un altra cosa. E così via. In questo nuovo contesto non è più necessario per l ascoltatore di avere accesso ai riferimenti. Si consideri, ad esempio, la porzione di condice nel Listato 17 dove ci sono tre voci di menu UpOpt, DownOpt, RandomOpt. Le tre voci del menu hanno associati lo stesso ascoltatore con lo stesso metodo actionperformed. All interno del metodo la discriminazione su come l ascoltatore si deve comportare in funzione del metodo invocato è fatto analizzando i riferimenti. L istruzione src=e.getsource() restituisce un riferimento all oggetto che ha generato l evento. Se tale riferimento è uguale a UpOpt (entrambi puntano allo stesso oggetto corrispondente alla voce del menu Up, allora la voce del menu scelta è Up. Quindi viene eseguita la porzione di codice relativa a tale voce. Lo stesso per le altre voci. L ascoltatore è realizzato come classe interna in modo tale da poter realizzare l uguaglianza tra i puntato e verificare se coincidono. Come si è detto, l approccio con le classi interne ha molti svantaggi. la metodologia che vogliamo qui introdurre per capire chi ha generato l evento non deve assumere classi interne e, quindi, non può basarsi sull uguaglianza tra puntatori. Quando si usano classi esterne, è possibile capire il componente che ha notificato l evento associando ai diversi componenti un diverso valore della proprietà actioncommand. Nell esempio nel Listato 18 i possibili valori per le proprietà actioncommand sono memorizzate come costanti stringa, cioè public final static, della classe ascoltatore Listener. Ad ogni oggetto da predisporre per gestire
41 12 Condividere gli ascoltatori per più oggetti 40 public c l a s s MyFrame extends JFrame... JMenuItem UpOpt = new JMenuItem ( Up ) ; JMenuItem DownOpt = new JMenuItem ( Down ) ; JMenuItem RandomOpt = new JMenuItem ( Random ) ; L i s t e n e r a s c o l t a t o r e = new L i s t e n e r ( ) ; public MyFrame ( )... UpOpt. addactionlistener ( a s c o l t a t o r e ) ; DownOpt. addactionlistener ( a s c o l t a t o r e ) ; RandomOpt. addactionlistener ( a s c o l t a t o r e ) ;... class L i s t e n e r implements A c t i o n L i s t e n e r public void actionperformed ( ActionEvent e ) Object s r c = e. getsource ( ) ; i f ( s r c == UpOpt) c o d i c e d e l l a voce d e l menu Up else i f ( s r c == DownOpt) c o d i c e d e l l a voce d e l menu Down else i f ( s r c == RandomOpt) c o d i c e d e l l a voce d e l menu Random Listato 17: Ascoltatore condiviso come classe Interna
42 12 Condividere gli ascoltatori per più oggetti 41 public c l a s s MyFrame extends JFrame... JMenuItem UpOpt = new JMenuItem ( Up ) ; JMenuItem DownOpt = new JMenuItem ( Down ) ; JMenuItem RandomOpt = new JMenuItem ( Random ) ; L i s t e n e r a s c o l t = new L i s t e n e r ( ) ; public MyFrame ( )... UpOpt. addactionlistener ( a s c o l t ) ; UpOpt. setactioncommand ( L i s t e n e r.upopt) ; DownOpt. addactionlistener ( a s c o l t ) ; DownOpt. setactioncommand ( L i s t e n e r.downopt) ; RandomOpt. addactionlistener ( a s c o l t ) ; RandomOpt. setactioncommand ( L i s t e n e r.randomopt)... Listato 18: Il JFrame per usare ascoltatori esterni gli eventi azione viene associato un valore per la actioncommand presi tra tali costanti stringa. Questo viene fatto grazie al metodo void setactioncommand ( S t r i n g ) ; Il metodo actionperformed dell actionlistener legge il valore della proprietà actioncommand del componente che ha notificato l evento e, in funzione del valore letto, sceglie la porzione di codice da eseguire. Eventualmente è possibile associare lo stesso actioncommand a componenti gestiti dallo stesso ascoltatore se si desidera che questi gestiscano l evento azione nello stesso modo. Questo cosa è molto utile quando si desidera replicare la voce di un dato menu con un bottone da inserire nella toolbar della finestra: per fare sì che sia la voce del menu che il bottone nella toolbar gestiscano l evento nello stesso modo è sufficiente associare ad entrambi lo stesso actioncommand. Torniamo indietro a considerare la finestra descritta nel Listato 18. Il suo scheletro è nel Listato 19. Si possono osservare sempre tre parti in questo tipo di ascoltatori: La parte che definisce le costanti stringa (le tre dichiarazioni di oggetti pubblici, costanti 4 e statici) 4 In Java è possibile definire che il valore di un riferimento non può cambiare dichiarandolo final. Questo ovviamente non è sufficiente per dichiarare un oggetto costante. Tuttavia nel caso di oggetti String le due cose coincidono dato che gli oggetti stringa sono
43 12 Condividere gli ascoltatori per più oggetti 42 public class L i s t e n e r implements A c t i o n L i s t e n e r public f i n a l static S t r i n g UPOPT = up ; public f i n a l static S t r i n g DOWNOPT = down ; public f i n a l static S t r i n g RANDOMOPT = random ; public void actionperformed ( ActionEvent e ) S t r i n g com = e. getactioncommand ( ) ; i f (com == UPOPT) upopt ( ) ; else i f ( s r c == DOWNOPT) downopt ( ) ; else i f ( s r c == RANDOMOPT) randomopt ( ) ; private void upopt ( )... private void randomopt ( )... private void downopt ( )... Listato 19: Ascoltatore condiviso come classe Interna Il metodo actionperformed che gestisce l evento. Questo metodo in questi casi non fa nient altro che leggere il valore della proprietà actioncommand dell oggetto che ha generato l evento. In funzione del valore della proprietà (e quindi dell oggetto scatenante), viene attivata una gestione separata che consiste nell invocare metodi diversi. I diversi metodi privati che eseguono effettivamente le operazioni associate all attivazione dei diversi controlli/widget. immutabili: non può cambiare il riferimento, nè può cambiare il valore dell oggetto puntato
44 13 Conclusioni e Commenti Finali Conclusioni e Commenti Finali Questa dispensa ha descritto le funzionalità più comuni del pacchetto JavaSwing. JavaSwing è un pacchetto estremamente vasto, che va dalla definizione delle interfacce e del disegno 2D, fino alla gestione dell interazione nei più minimi dettagli. Di conseguenza, è praticamente impossibile toccare tutti gli argomenti in questa dispensa. È opportuno concludere la trattazione con alcune osservazioni su una corretta interazione tra le interfacce grafiche e la logica applicativa (ad es., la realizzazione del diagramma delle classi). Una buon approccio metodologico si basa su un concetto cardine: la logica applicativa non deve essere strettamente accoppiata con il codice delle classi delle interfacce grafiche. Quindi, all interno delle classi della logica applicativa non si devono avere riferimenti, nè avere accesso alle classi che descrivono le interfacce grafiche. D altronde, non è possibile specificare una modalità di accesso private per le variabili di istanza delle classi che ereditano da JFrame. Infatti, se così fosse, gli ascoltatori non avrebbero accesso ai componenti delle finestre, a meno di definire complessi e numerosi metodi getter/setter. Un buon tradeoff consiste nel mettere le classi delle interfacce e i relativi ascoltatori in un package diverso dalla logica applicativa (ad esempio gui), specificando un modalità di accesso package alle variabili di istanza delle classi che ereditano da JFrame. 5 In questo modo le classi della logica applicativa non hanno alcun accesso ai campi delle classi JFrame, dato che si trovano i package diversi. Viceversa gli ascoltatori possono, poiché si trovano nello stesso package. Infatti, gli ascoltatori sono gli unici che, da un lato, possono accedere alla logica applicative e, dall altro, possono aggiornare opportunamente l aspetto e i contenuti delle finestre grafiche. In aggiunta è possibile definire per ogni finestra e tutti i listener associati ai widget della finestre un opportuno sotto package (ad esempio gui.nomefinestra) in modo da limitare il raggio di azione dei diversi ascoltatori alla sola finestra. 5 Si ottiene la modalità di accesso package quando la descrizione del tipo delle variabili d istanza non è preceduta da nessuna modalità di accesso: public, private o protected.
45 13 Conclusioni e Commenti Finali 44 parent Message title messagetype Questo parametro serve a specificare il frame principale; esso verrà bloccato fino al termine dell interazione. Ponendo a null questo parametro la finestra verrà visualizzata al centro dello schermo e risulterà indipendente dal resto dell applicazione. Questo campo permette di specificare una stringa da visualizzare come messaggio oppure, in alternativa, una qualunque sottoclasse di Component Questo parametro è utilizzato per specificare il titolo della finestra modale. Attraverso questo parametro è possibile influenzare l aspetto complessivo della finestra, per quanto riguarda il tipo di icona e il layout. Il parametro può assumere uno dei seguenti valori: JOptionPane.ERROR MESSAGE JOptionPane.INFORMATION MESSAGE JOptionPane.WARNING MESSAGE JOptionPane.QUESTION MESSAGE JOptionPane.PLAIN MESSAGE optiontype I Confirm Dialog possono presentare diversi gruppi di opzioni per scegliere i bottoni da visualizzare nella finestra modale: JOptionPane.YES NO OPTION JOptionPane.YES NO CANCEL OPTION JOptionPane.OK CANCEL OPTION icon SelectedValues initialvalue Ogni istanza della classe Icon rappresenta un icona. In questo caso l oggetto passato sarà visualizzato come icona di un Input Dialog. Nella maggior parte dei casi questo parametro può essere messo a null in modo tale che sia scelta l icona di default. Questa parametro permette di impostare i possibili valori, tipicamente stringhe, che possono selezionati attraverso l Input Dialog. I valori selezionabili sono inseriti in un ComboBox in modo tale che nessun altro valore è ammissibile. Se questo parametro viene messo a null allora il ComboBox è sostituito da un campo di testo e qualsiasi valore è ammesso. Questo parametro permette di stabilire il valore di default, tipicamente una stringa. Tab. 1: Spiegazione dei parametri dei metodi di JOptionPane
46 13 Conclusioni e Commenti Finali 45 ActionListener Definisce 1 metodo per ricevere eventi-azione ComponentListener Definisce 4 metodi per riconoscere quando un componente viene nascosto, spostato, mostrato o ridimensionato FocusListener Definisce 2 metodi per riconoscere quando un componente ottiene o perde il focus KeyListener Definisce 3 metodi per riconoscere quando viene premuto, rilasciato o battuto un tasto MouseMotionListener Definisce 2 metodi per riconoscere quando il mouse e trascinato o spostato MouseListener Se ne è già parlato... TextListener Definisce 1 metodo per riconoscere quando cambia il valore di un campo testo WindowListener Definisce 7 metodi per riconoscere quando un finestra viene attivata, chiusa, disattivata, ripristinata, ridotta a icona, ecc. Tab. 2: Gli ascoltatori più importanti
Prof. Pagani Corrado ESERCITAZIONI JAVA
Prof. Pagani Corrado ESERCITAZIONI JAVA PRIMA APPLICAZIONE CONSOLE Eseguire somma e media tra tre numeri ES 1 CODICE Non programmo sfruttando il paradigma ad oggetti (ho solo il metodo main che è static
I Layout Manager di java. Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni
I Layout Manager di java Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni Creazione di interfacce complesse con i layout manager La posizione di un componente aggiunto
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE INTRODUZIONE L interfaccia grafica del programma è composta dai cosiddetti componenti GUI (Graphics User Interface); essi sono dei componenti che servono
L Abstract Windowing Toolkit. Le GUI in Java. Il Frame. Cenni sull ereditarietà. Gianpaolo Cugola - Sistemi Informativi in Rete
Le GUI in Java L Abstract Windowing Toolkit Fino ad ora abbiamo usato le classi del pacchetto JavaBook per realizzare semplici interfacce grafiche (GUI) Si tratta di classi facili da usare...... ma che
Sviluppo di Interfacce Grafiche in Java
Sviluppo di Interfacce Grafiche in Java Massimiliano de Leoni (con la supervisione del docente Massimo Mecella) Università di Roma La Sapienza - Sede di Latina Corso di Progettazione del Software A.A.
Riassunto. GUI in Java con l AWT 1. Cos è una GUI. Oggi: GUI in Java, l AWT. GUI in Java. Un esempio. Stefano Mizzaro 1
Riassunto GUI in Java con l AWT 1 Stefano Mizzaro Dipartimento di matematica e informatica Università di Udine http://www.dimi.uniud.it/mizzaro [email protected] Programmazione, lezione 23 15 febbraio
GUI e java swing. Elmenti della GUI. Eventi e listener contenitori componenti layout manager. caratteristiche speciali
GUI e java swing Raffaella Brighi, a.a. 2005/06 Corso di Laboratorio II. A.A. 2005-06 CdL Operatore Informatico Giuridico. Elmenti della GUI Eventi e listener contenitori componenti layout manager caratteristiche
Programmazione in rete e laboratorio
Programmazione in rete e laboratorio 2001-02 JAVA Alberto Martelli PROGRAMMAZIONE GRAFICA Molti programmi interagiscono con l utente attraverso una interfaccia grafica GUI - Graphical User Interface Java
La nostra finestra dovrebbe essere come mostra la figura: Diamo innanzitutto un occhiata alle componenti principali di input/output:
Esercitazione N4: Costruzione di una applicazione GUI utilizzando i componenti di base per realizzare l input e l output e cioè Label, TextBox, TextArea Button e Panel (Pannelli) I componenti che utilizzeromo
Riassunto. GUI in Java con l AWT 1. Oggi: GUI in Java, l AWT. Oggi. GUI in Java. Cos è una GUI. Stefano Mizzaro 1
Riassunto GUI in Java con l AWT 1 Stefano Mizzaro Dipartimento di matematica e informatica Università di Udine http://www.dimi.uniud.it/mizzaro/ [email protected] Programmazione, lezione 20 20 novembre
Eventi di azione. // con interfaccia per eventi di azione
Eventi di azione (Interfaces ActionListener, Classes ActionEvent) Sono generati quando si premono bottoni, si selezionano voci di menù, si preme invio mentre si scrive in un campo di testo. In awt sono
Eventi e listener per i componenti grafici
Eventi e listener per i componenti grafici Raffaella Brighi, a.a. 2005/06 Corso di Laboratorio II. A.A. 2005-06 CdL Operatore Informatico Giuridico. Eventi e listener Eventi e listener (ascoltatori) sono
L INTERFACCIA GRAFICA DI EXCEL
Dopo l avvio del foglio elettronico apparirà un interfaccia grafica nella quale verrà aperta una nuova cartella di lavoro alla quale il PC assegnerà automaticamente il nome provvisorio di Cartel1. La cartella
Sviluppo di Interfacce Grafiche in Java. Concetti di Base ed Esempi.
SAPIENZA Università di Roma Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica Dispensa didattica Sviluppo di Interfacce Grafiche in Java. Concetti di Base ed Esempi. M. de Leoni, M. Mecella,
Programmazione Java: Interfacce grafiche (GUI)
Programmazione Java: Interfacce grafiche (GUI) [email protected] http://www.di.univaq.it/romina.eramo/tlp ( 1 ) (GUI) Interfacce grafiche Rendere facili le cose semplici e possibili le cose difficili
Java GUI. Swing Java
Java GUI Swing Java 1 Introduzione n Componenti grafici di Java (Swing) Utilizzo di alcuni dei metodi per creare semplici finestre grafiche Accesso ai JavaDoc per usare meglio gli oggetti già pronti n
Programmazione ad Oggetti. JFrame è la classe di base per le finestre Fornisce tutte le caratteristiche di una finestra vuota
Programmazione ad Oggetti Interfacce grafiche V 1.2 Marco Torchiano 2005 JFrame JFrame è la classe di base per le finestre Fornisce tutte le caratteristiche di una finestra vuota Barra del titolo Pulsanti
Le classi in java. Un semplice programma java, formato da una sola classe, assume la seguente struttura:
Le classi in java Un semplice programma java, formato da una sola classe, assume la seguente struttura: class Domanda static void main(string args[]) System.out.println( Quanti anni hai? ); La classe dichiarata
PROVA FINALE Ingegneria del software
PROVA FINALE Ingegneria del software Ing. Jody Marca [email protected] Laboratorio N 3 Cosa faremo oggi 2 Interfaccia grafica e SWING Lettura e scrittura di Files di properties Internazionalizzazione
Capitolo 2. Figura 21. Inserimento dati
Capitolo 2 INSERIMENTO DI DATI In ogni cella del foglio di lavoro è possibile inserire dati che possono essere di tipo testuale o numerico, oppure è possibile inserire formule le quali hanno la caratteristica
Grafica swing in Java
Grafica swing in Java JFrame Costruttori public JFrame() Crea un nuovo Frame inizialmente invisibile public JFrame(Stringtitle) Crea un nuovo frame, inizialmente invisibile, con un testo specificato. Metodi
14Ex-Cap11.qxd :20 Pagina Le macro
14Ex-Cap11.qxd 21-12-2006 11:20 Pagina 203 11 Le macro Creare le macro Registrare una macro Eseguire una macro Riferimenti assoluti e relativi nelle macro Assegnare un pulsante a una macro Modificare una
Grafici. 1 Generazione di grafici a partire da un foglio elettronico
Grafici In questa parte analizzeremo le funzionalità relative ai grafici. In particolare: 1. Generazione di grafici a partire da un foglio elettronico 2. Modifica di un grafico 1 Generazione di grafici
Corso di Algoritmi e Strutture dati Programmazione Object- Oriented in Java (Parte I)
Corso di Algoritmi e Strutture dati Programmazione Object- Oriented in Java (Parte I) Ing. Gianluca Caminiti Sommario ( OOP ) Programmazione Object-Oriented Incapsulamento, Ereditarietà, Polimorfismo Richiami
L interfaccia grafica in Java
L interfaccia grafica in Java Java possiede due package per la creazione di interfacce grafiche java.awt javax.swing AWT (Abstract Widget Toolkit) presente già in Java 1.0, migliorato in Java 1.1. Invariato
Gestione del testo. Dreamweaver e il testo. Richiamare la pagina
Gestione del testo 04 In questo capitolo In questo capitolo imparerai a utilizzare gli strumenti di formattazione del testo. Imparerai come impostare uno stile a un testo per un titolo o un paragrafo.
Presentazione con PowerPoint
Presentazione con PowerPoint L applicazione PowerPoint permette di creare documenti da mostrare su diapositive per presentazioni. Sarai facilitato nell utilizzo di PowerPoint perché molti pulsanti e molte
Programmazione in Java e gestione della grafica. Lezione 21
Programmazione in Java e gestione della grafica Lezione 21 2 Parliamo ( ancora ) di Eventi della GUI (Eventi del mouse e della tastiera) 3 Gestione degli eventi del mouse Eventi del Mouse Creo un oggetto
INSERIRE I DATI NEL DATABASE
13-Cap10_DWCS3.qxd 18-11-2009 11:43 Pagina 201 CAPITOLO10 INSERIRE I DATI NEL DATABASE In questo capitolo In questo capitolo imparerai a interagire con i contenuti del database gestiti nel sito. In particolare
Le basi della grafica in Java. Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni
Le basi della grafica in Java Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni Elaborazione classica o imperativa L elaborazione è concentrata nel momento centrale, durante
3.5.1 PREPARAZ1ONE I documenti che si possono creare con la stampa unione sono: lettere, messaggi di posta elettronica, o etichette.
3.5 STAMPA UNIONE Le funzioni della stampa unione (o stampa in serie) permettono di collegare un documento principale con un elenco di nominativi e indirizzi, creando così tanti esemplari uguali nel contenuto,
nome di un menu per visualizzarlo e poi selezionate facendo clic sul comando che vi interessa.
1 (conoscere le basi di Excel) < I controlli della. Finestra > La finestra di apertura di Excel presenta una cartella di lavoro vuota; la finestra del programma occupa tutto lo spazio dello schermo, mentre
Corso di Laurea Ingegneria Civile Fondamenti di Informatica. Dispensa 07. Oggetti e Java. Marzo Programmazione Java 1
Corso di Laurea Ingegneria Civile Fondamenti di Informatica Dispensa 07 Oggetti e Java Marzo 2010 Programmazione Java 1 Contenuti Il linguaggio Java Applicazioni Java e il metodo main Esempi di applicazioni
Cultura Tecnologica di Progetto
Cultura Tecnologica di Progetto Politecnico di Milano Facoltà di Disegno Industriale - FOGLI DI CALCOLO - A.A. 2003-2004 2004 Foglio Elettronico Un foglio elettronico è un potente strumento di calcolo,
DEFINIZIONI SMART E RELATIVE ESERCITAZIONI
DEFINIZIONI SMART E RELATIVE ESERCITAZIONI A B C D E 1 2 3 4 5 6 7 8 9 MODULO 3 Creazione e gestione di fogli di calcolo MODULO 3 CREAZIONE E GESTIONE DI FOGLI DI CALCOLO Gli elementi fondamentali del
Campo Minato. in java
Campo Minato in java Il gioco campo rettangolare o quadrato suddiviso in tanti quadratini Il giocatore deve sminare il campo, cliccando sui quadratini, col tasto destro o col tasto sinistro il gioco cliccando
Excel 2. Master Universitario di II livello in MANAGER NELLE AMMINISTRAZIONI PUBBLICHE A.A Prof.ssa Bice Cavallo
Excel 2 Master Universitario di II livello in MANAGER NELLE AMMINISTRAZIONI PUBBLICHE A.A. 2013-2014 Prof.ssa Bice Cavallo Grafici Excel offre diversi tipi di grafici standard (Area, Barre, Istogramma,
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE La Gestione degli Eventi Ogni oggetto grafico è predisposto ad essere sollecitato in qualche modo dall utente (per esempio un pulsante può essere premuto).
Corso sul linguaggio Java
Corso sul linguaggio Java Modulo L6 (JAVA9) 1 Introduzione alle applet 1 Prerequisiti Architettura client/server Elementi di base HTML Programmazione Java Utilizzo package awt di Java 2 1 Introduzione
19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo
19 - Eccezioni Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/ milazzo milazzo di.unipi.it Corso
Figura 1 - Finestra Tabella
Capitolo IV Oggetti Creare una tabella Creare una tabella per inserire dei dati Per inserire una tabella premere il pulsante Tabella presente nella sezione Tabella della barra Inserisci. Viene visualizzata
DISPENSA ACCESS (OFFICE 2010 BETA)
DISPENSA ACCESS (OFFICE 2010 BETA) 2. LE RELAZIONI. Una relazione può essere definita come un legame tra due tabelle basato sul valore di uno o più campi di ciascuna delle due tabelle. Di solito i campi
L interfaccia grafica con Java
L interfaccia grafica con Java 1/24 L interfaccia utente serve per la comunicazione tra utente e programma Distinguiamo le interfacce tra quelle a caratteri e quelle grafiche Le GUI (Graphical user interface)
LE MASCHERE. Maschera standard. Maschera semplice. Questa maschera però non consente di nascondere alcuni campi e visualizza i record uno ad uno.
LE MASCHERE Inserire i dati direttamente in tabella non è agevole. Questa operazione normalmente viene svolta utilizzando le maschere. I vantaggi offerti dalle maschere sono: Aspetto grafico più accattivante
La classe java.lang.object
La classe java.lang.object In Java: Gerarchia di ereditarietà semplice Ogni classe ha una sola super-classe Se non viene definita esplicitamente una super-classe, il compilatore usa la classe predefinita
Programmazione Orientata agli Oggetti in Linguaggio Java
Programmazione Orientata agli Oggetti in Linguaggio Java Programmazione Grafica: Componenti versione 1.0 Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)
Guida pratica per la creazione di un documento Word accessibile Sommario
Guida pratica per la creazione di un documento Word accessibile Sommario Introduzione... 2 Proprietà... 2 Stili e formattazione... 2 Creazione di un sommario... 3 Collegamenti ipertestuali... 3 Colori...
Progettazione multimediale
Progettazione multimediale Le tabelle 1 Obiettivi Perché si usano le tabelle Le proprietà delle tabelle Inserimento e modifica delle proprietà 2 Perché si usano le tabelle Una pagina Web è formata da testo
11-Cap :40 Pagina Tabelle pivot
11-Cap08 29-08-2003 9:40 Pagina 147 8Tabelle pivot Creare tabelle pivot per riassumere i dati Strutturare la tabella pivot Mostrare i dati per categoria Rimuovere dati da una tabella pivot Cambiare la
Automatizzare le attività con le macro di Visual Basic
Automatizzare le attività con le macro di Visual Basic Se non si ha esperienza con le macro, non c'è da preoccuparsi. Una macro è semplicemente un insieme registrato di sequenze di tasti e di istruzioni,
Introduzione a PowerPoint
Introduzione a PowerPoint PowerPoint è una potente applicazione per la creazione di presentazioni, ma per utilizzarla nel modo più efficace è necessario innanzitutto comprenderne gli elementi di base.
6. Editor Divi. Il layout. Guida Sintetica Wordpress //
6. Editor Divi Divi è un editor visuale che utilizza il sistema drag and drop per creare layout di pagina con facilità. Nella fase di creazione di una nuova pagina o un nuovo articolo, si avrà la possibilità
Capitolo 18 - Progetto DWG Creazione del layout di stampa
Capitolo 18 - Progetto DWG Creazione del layout di stampa Avviate MasterChef dall icona presente sul vostro Desktop. Nota: Se state utilizzando una versione dimostrativa, una volta caricato il programma,
Note APRIRE IL PROGRAMMA EXCEL
APRIRE IL PROGRAMMA EXCEL 1. Fai clic sul pulsante Start. 2. Fai scorrere l elenco dei programmi e a seconda della versione del tuo Windows: a. Fai clic su Microsoft Office e/o b. Fai clic su Microsoft
Impaginare con InDesign: le tabelle
Impaginare con InDesign: le tabelle Perchè scrivere un articolo solo per parlare delle tabelle in InDesign? Se hai letto l articolo dedicato ai paragrafi lo puoi immaginare: trattiamo un eccezione alla
Interfacce. Esempio: interfaccia I con una sola funzione g() public interface I {
Interfacce Una interfaccia è un astrazione per un insieme di funzioni pubbliche delle quali si definisce solo la segnatura, e non le istruzioni. Un interfaccia viene poi implementata da una o più classi
Introduzione. Java. G. Prencipe
Java creare finestre G. Prencipe [email protected] Introduzione L obiettivo originale delle librerie per interfacce grafiche utente (GUI) in Java1.0 era di permettere al programmatore di costruire interfacce
