Mangiare Senza Glutine disponibile su App Store

Per altre informazioni scrivi a fabriziocaldarelli@negusweb.it

SWING: applicazioni grafiche in Java

Da Programmazione Software.


Introduzione a Swing

Swing è un vero e proprio framework di librerie grafiche per costruire le gui ai nostri programmi. Le precedenti librerie, AWT, sono state largamente superate da Java sia per quanto riguarda le performance, ma anche per il maggior numero di oggetti a disposizione.

Programmare l'interfaccia grafica in Java è qualcosa di straordinariamente interessante: si lavora ad un livello bassissimo con l'oggetto, come se si programmasse con le API del sistema operativo ospitante e al tempo stesso si ha a disposizione tutta la potenza e la flessibilità del linguaggio orientato agli oggetti.

Oggetto di questi appunti saranno tutti gli oggetti disponibili per la GUI, ma soprattutto la personalizzazione di questi oggetti. Vedremo come inserire questi risultati in un'ottica più ampia, che consenta di sfruttare tutte le capacità del Java, ovvero:

* Organizzazione del problema in classi atomiche, ognuna con un suo compito;
* Progettare le classi in modo che siano più generiche possibile;
* Svincolare completamente gli oggetti da altri oggetti, per favorire la riusabilità.


Questi punti di vista dovrebbero essere sempre tenuti in massima considerazione quando si programma, soprattutto quando si ha sotto i tasti un linguaggio di programmazione potente e versatile come il Java.

Farò sempre riferimento ai punti sopra citati per quanto riguarda la progettazione sempre più spinta degli oggetti che abbiamo a disposizione, con esempi brevi ma calzanti.

Chiudo questa introduzione nel sottolineare come Java sia il linguaggio ideale per la messa in opera dello stile di progettazione MVC (Model-View-Controller), ovvero il delegare l'operazione di raccolta e gestione dati ad un oggetto (model), l'operazione di visualizzazione ad un altro oggetto (view) ed infine l'operazione di controllo delle operazioni (input) dell'utente con un altro oggetto ancora (controller). Tutti gli esempi che farò saranno orientati verso questa "suddivisione dei compiti", proprio come dovrebbe essere un programma scritto ad oggetto. Ad un oggetto, una parte del programma che dovrebbe essere la più generale e riusabile possibile.

Infine, per ogni problema di solito c'e' sempre più di una soluzione, ma c'e' anche quella che, nel caso specifico (e proverò ad estendere il più possibile questo dominio), rappresenta la soluzione migliore, o sicuramente che meglio si adatta alla programmazione ad oggetti.


Le finestre con le Swing

La classe che in un'applicazione sviluppata con le Swing consente di inizializzare, gestire e visualizzare una finestra è JFrame. Ma com'e' strutturata una "finestra" che discende da JFrame? In un modo abbastanza intuitivo; infatti ogni "finestra" è in realtà costituita da tre pannelli (contenitori): Frame, Menu Bar e Content Pane. Le caratteristiche principali di questi tre pannelli:

* Il Frame contiene il Menu Bar ed il Content Pane;
* Il Menu Bar è utilizzato per ospitare la barra dei menù (quando richiesto);
* Il Content Pane è il pannello vero e proprio su cui il programmatore dispone i controlli; 

Più in particolare il Frame riporta le caratteristiche comuni di tutte le finestre in base al tipo di stile (LookAndFeel) scelto: bordi, barra del titolo, icone e pulsanti sulla barra del titolo; Il Menù Bar non ha molto di particolare, se non il fatto di trovarlo nella posizione consueta (in alto al Content Pane); Il Content Pane è la vera e propria area di lavoro del programmatore, perchè è qui che verranno posizionati tutti i controlli. Perchè questo tipo di astrazione per la struttura della finestra? Il motivo è semplice: generalizzazione e riusabilità (ma guarda!) Infatti, avendo a disposizione un pannello di contorno alla Menu Bar ed ai controlli (Content Pane) che si occupa della visualizzazione dei bordi, barra del titolo e icone della barra del titolo, siamo in grado di personalizzare le nostre finestre come vogliamo: basta scrivere un nostro "stile" (LookAndFeel, appunto) che vada ad impostare il bordo e la barra del titolo come piacciono a noi.

TopLevelDemo.gif Java ConceptualPains.gif

fonte: http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html

Ricordandoci che i programmi scritti in Java possono girare quasi su ogni piattaforma, questo genere di astrazione consente di utilizzare lo stile a cui noi siamo abituato: gli utenti Linux (XWindow) potranno usare lo stile GTK, gli utenti Windows potranno utilizzare lo stile Windows, e così via. Tutto questo senza cambiare nulla nel nostro codice, se non la libreria che fa riferimento allo stile da utilizzare!

L'applicazione dello stile non si ferma ai bordi ed alla barra del titolo, ma viene applicato anche ai colori ed alla forma dei controlli (pulsanti, liste, etichette).

Prima di passare a qualche riga di codice, se andate a spulciare le api delle Swing vedrete che la classe JFrame è contenuta nel package "javax.swing": andrà specificato questo import per poter utilizzare le JFrame. Ok passiamo a scrivere un programma per visualizzare, ad esempio, una finestra che riporta nella barra del titolo la scritta: "ciao mondo"!

Esempio (ciaomondo.java) - Finestra con "ciao mondo" nella barra del titolo

import javax.swing.JFrame;
 
class ciaomondo
{
	public static void main(String[] args) 
	{
		// Dichiaro la variabile che farà riferimento alla mia finestra
		JFrame f;
 
		// Inizializzo la variabile f
		f=new JFrame();
 
		// Imposta il titolo della finestra
		f.setTitle("ciao mondo");
 
		// Dimensiona la finestra a 300x300
		f.setSize(300,300);
 
		// Imposta l'operazione di chiusura di default		
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
		// Visualizza la finestra
		f.setVisible(true);
	}
}

Il programma è tutto contenuto nella main e nonostante la comprensione sia anche guidata dai commenti, analizziamo velocemente il codice:

* Nella riga 1, come anticipato, facciamo riferimento al package javax.swing.JFrame per poter utilizzare la classe JFrame;
* Nella riga 5 si entra nel programma;
* Nella riga 8 si dichiara la variabile f, di tipo JFrame, che sarà il riferimento alla nostra finestra;
* Nella riga 11 inizializziamo la variabile f. Il costruttore del JFrame utilizzato, non è l'unico; se consultate le api della classe JFrame, vi accorgerete che ce ne sono altri, tra cui uno JFrame(String), che consente di definire subito anche il titolo della finestra. Nel nostro caso, invece, ho preferito anche utilizzare un'istruzione per l'impostazione del titolo della finestra, tanto per utilizzare un altro metodo della classe JFrame;
* La riga 14 serve proprio ad impostare il titolo della finestra;
* La riga 17 serve ad impostare le dimensioni della finestra. Se non inserite quest'istruzione, la vostra finestra avrà inizialmente dimensioni (0,0), ovvero vedrete solo la barra del titolo;
* La riga 20 imposta l'operazione che deve essere eseguita quando si clicca sulla X di chiusura della finestra; in queso caso si esce dal programma. Notare che se non viene specificata quest'istruzione, alla pressione della X della finestra, la finestra scompare ma in realtà il programma rimane in esecuzione.
* La riga 23, infine, rende la finestra visibile. Senza quest'istruzione la finestra è invisibile. 

Questo è l'esempio più semplice che si possa fare con le Swing. La nostra finestra, così com'è, non contiene alcun controllo. Nella premessa vi ho detto che i controlli vanno inseriti nel "Content" Pane del Frame (tornate all'inizio di questa pagina se avete dubbi). Facciamo un esempio di una Label con la scritta ciao mondo:

Esempio (label_ciaomondo.java) - Finestra con una JLabel con la scritta "ciao mondo"

import javax.swing.JFrame;
import javax.swing.JLabel;
 
class label_ciaomondo
{
	public static void main(String[] args) 
	{
		// Inizializzo la finestra
		JFrame f=new JFrame("Label con ciao mondo");
 
		// Inizializzo una JLabel con la scritta "ciao mondo"
		JLabel l=new JLabel("ciao mondo");
 
		// Aggiungo la JLabel al content pane della finestra
		f.getContentPane().add(l);
 
		// Dimensiona la finestra a 300x300
		f.setSize(300,300);
 
		// Imposta l'operazione di chiusura di default		
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
		// Visualizza la finestra
		f.setVisible(true);
	}
}


Rispetto al programma precedente, ci sono queste due righe:

* La riga 12 semplicemente inizializza una JLabel con la scritta "ciao mondo";
* La riga 15, come precedentemente anticipato, aggiunge il controllo non al frame, ma al content pane del frame. Per fare questo, ovviamente, dobbiamo riferirci al content pane del frame. Per avere il riferimento del content pane del frame si usa il metodo getContentPane(); 


Aggiungendo i controlli in questo modo, il controllo occupa tutto il frame e non è di grande utilità. Questo perchè non abbiamo specificato il layout del nostro frame, ovvero il modo con cui devono essere posizionati e dimensionati i controlli nella finestra. Infatti, per il posizionamento dei controlli nella finestra, abbiamo diversi layout a cui possiamo fare riferimento, che fanno per noi il lavoro del posizionamento e del dimensionamento dei controlli. Tra questi anche il posizionamento assoluto, ovvero quello in cui noi da codice gestiamo posizione e dimensioni dei controlli. Per impostare il layout utilizziamo il metodo setLayout, in questo modo:

<variabile_frame>.setLayout(<oggetto_layout>);