8. GUI : Graphics User Interface

appunti java
pag.82
8. GUI : Graphics User Interface
Un linguaggio ad oggetti ha come obiettivo principale quello di fornire al
programmatore classi per la gestione di ambienti grafici a finestre. Se fino a
questo momento ci si è occupati di sintassi e di fondamenti introduttivi di Java,
cercando di dare solidità ai concetti di Classe, Metodi, Ereditarietà, ora entreremo
nel vivo della programmazione di interfacce grafiche GUI.
Si affronteranno due ordini di problemi: primo con quali componenti e come
costruire una interfaccia grafica, secondo come gestire gli eventi del mouse, della
tastiera ecc. che consentono ad un programma di funzionare.
Se la programmazione imperativa con ForTran, Pascal o c si occupava quasi
esclusivamente di algoritmi per risolvere problemi di calcolo e solo in modo
rudimentale di interfacce di input e output rivolte all'utente, con Java il "peso" o
"quantità di codice" dedicata all'interfaccia utente diviene molto importante e ad
esso è necessario dedicare un capitolo introduttivo metodologico.
Il primo passo consiste nella scelta del Package di Java da utilizzare per costruire
interfacce grafiche. Con le versioni del jdk (java development kit) 1.0, 1.1 java
consentiva la costruzione di GUI usando i componenti grafici del package
java.awt. (abstract window toolkit). Con la versione 1.2 e soprattutto la 1.3 ad
awt si è aggiunto il package javax.swing. a cui faremo riferimento prevalente.
L'orientamento di usare il package swing è dovuto al fatto che questo permette di
generare oggetti grafici molto più raffinati rispetto ai corrispondenti dell'awt,
oggetti sostanzialmente identici ai componenti grafici di Windows Microsoft e agli
ambienti XWindow di Unix.
8.1. La gerarchia di classi grafiche
Se si esplora la documentazione awt e swing (come esercizio è opportuno
sfogliarla più volte per acquisire famigliarità con le sue classi) si nota
immediatamente una lunga sequenza di classi. Analizzando solo quelle principali,
possiamo distinguere alcune entità grafiche famigliari a chi usa un computer:
FINESTRE : simili o identiche a quelle di Windows, la classe Frame (awt) e la
JFrame (swing).
PULSANTI : con o senza icona, la classe Button (awt) e la JButton (swing).
CAMPI di TESTO : la classi TextField, TextArea (awt) e le JTextField, JTextArea
del package swing.
I legami di ereditarietà tra le classi principali di awt e swing sono schematizzati
nella tabella della pagina successiva.
appunti java
pag.83
pag. 83
Object
Component
awt
Container
Window
Frame
JFe
Dialog
JDialog
JPasswordField
swing
JComponent
JtextComponent
JTextField
JAbstractButton
JTextArea
JLabel
JToolBar
JToolTip
JFileChoser
JColorChoser
JButton JMenuItem JToggleButton
JChekBox
JRadioButton
Dalla gerarchia di classi si nota che i due packages awt e swing hanno una relazione. In swing esistono due tipi di
Container di alto livello "Top Level Container" che sono rispettivamente JFrame e JDialog indispensabili per aggiungere
componenti e costruire la GUI di un'applicazione Java. Tutti gli altri componenti grafici discendono da JComponent
figlio di Component e Container dell'awt. Il significato di questa discendenza da JComponent implica che qualunque
oggetto grafico ha la caratteristica di essere sia un Component che un Container, ovvero può contenere o essere
contenuto in oggetti di tipo JComponent. Ne consegue per esempio che un JButton può contenere un JtextField anche
se questa possibilità non è molto utile.
Si sono indicate con sfondo grigio le classi che si impareranno ad usare in questo capitolo, rimandando alle applicazioni
o a successivi esempi l'uso di altre Classi. Appreso il metodo di costruzione di una GUI lo si potrà facilmente estendere ai
diversi componenti indicati nella gerarchia.
appunti java
pag.84
8.1.1. Costruzione di GUI
Qualsiasi GUI per quanto banale si "appoggia" sempre su una finestra di
Windows ecco come crearla usando JFrame di swing.
La classe JFrame (vedi manuale) ha diversi costruttori e alcuni metodi essenziali :
Nome
Campi o attributi
Costruttori
Metodi
Pckage e
Gerarchia
JFrame
Vedi
Sono
molteplici
e
(protected)
inacessibili
documentazione all’utilizzatore.
Identificatori:
JFrame( );
JFrame( String titolo );
Invocazione:
JFrame f=new JFrame( );
JFrame f=new JFrame("titolo");
Effetti:
Crea un oggetto JFrame identificato da f senza
nessun titolo o con titolo.
Identificatore
void setSize(int larga, int alta);
void setBounds(int x, int y, int larga, int alta);
void setVisible(boolean bo);
void setDefaultCloseOperation(int operaz);
Invocazione:
• f.setSize(200, 100);
• f.setBounds(20,50, 200, 100);
• f.setVisible(true);
• f.setDefaultCloseOperation(Jframe.DISPOSE_O
N_CLOSE);
Effetti::
• il primo metodo dimensiona la finestra
collocandola con l'angolo alto a sinistra nel
punto di coordinate schermo (0,0) con
larghezza di 200 pixel e altezza di 100.
• Il secondo metodo colloca l'angolo alto a
sinistra della finestra nel punto di coordinate
schermo (20,50) mantenendo larghezza e
altezza di 200 e 100 pixel.
• Il terzo rende visibile la finestra. Se non si
invoca questo metodo la finestra rimane
"invisibile" ma allocata correttamente in
memoria.
• Il quarto attiva l'ascoltatore di eventi riferito
alla chiusura della finestra. I parametri
ammessi sono i segunti: DISPOSE_ON_CLOSE,
HIDE_ON_CLOSE, DO_NOTHING_ON_CLOSE,
EXIT_ON_CLOSE.
Il primo distrugge la frame in memoria ma non
interrompe il programma. Il secondo nasconde
la finestra senza distruggerla. Il terzo disabilita
la chiusura; il click non chiude. Il quarto (solo
con jdk1.3) chiude correttamente il processo
Java.
javax.swing
java.awt.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
java.swing.JFrame
appunti java
pag.85
esempio 1: "creare una finestra di Windows di dimensione 300x200 e posizionarla
alle coordinate 100,100".
Codice:
Esecuzione:
Commenti:
Si nota che facendo click sul pulsante di chiusura la finestra scompare ma il
programma non termina; infatti nella barra di stato della finestra di RealJava
compare la scritta "External process in progress". Per chiudere la finestra di
esecuzione del processo si deve cliccare sul pulsante "stop" della finestra di
output dell'editor. Questa non è una modalità corretta per interrompere
l'esecuzione di un programma, è necessario indicare esplicitamente che l'evento
"clik" sul pulsante di chiusura deve interrompere il programma Java. Questo lo si
ottiene con la costante EXIT_ON_CLOSE (attivo solo nella versione 1.3 del jdk).
L'esempio mostrato è piuttosto banale ma evidenzia la semplicità con la quale si
può generare un oggetto finestra con tutte le caratteristiche grafiche del sistema
Windows e che si comporta (ridimensionamento, riduzione ad icona e chiusura
programma) come la finestra di un'applicazione professionale.
appunti java
pag.86
Quando la GUI si complica, anche di poco, è opportuno che il programma
principale non esegua tutte le azioni desiderate ma sia soltanto il punto di avvio
da cui lanciare l'applicazione e che tutto sia rimandato ad una apposita classe,
sottoclasse di JFrame, che con i metodi opportuni esegua quanto desiderato
dall'utente. Il precedente programma sarebbe metodologicamente più corretto se
codificato come sottoclasse di JFrame.
esempio 2. "codificare l'apertura di una finestra come quella dell'esempio 1
utilizzando una sottoclasse di JFrame."
Codifica:
Commenti:
Il grafo ad albero mostra la dipendenza gerarchica dei metodi invocati:
super()
main()
cap08 es 02()
disegna frame()
gestisci eventi()
La prima cosa da notare è che il main() invoca soltanto il costruttore della classe
cap08_es_02(). Tutto è rimandato al metodo costruttore; questo invoca in
sequenza (1) super() costruttore della classe genitrice Jframe che alloca la
finestra; (2) disegna_frame() che si occupa della costruzione della finestra grafica
con tutti i componenti necessari; (3) gestisci_eventi() che gestisce in modo
elementare l'evento di chiusura della Frame.
Questa struttura gerarchica sarà mantenuta anche per tutti i programmi
successivi per dare ordine logico al programma che si intende realizzare. Nel
costruttore saranno pertanto sempre presenti i metodi disegna_Frame e
gestione_Eventi.
La nota (0) mostra la parola chiave extends che consente di dichiarare una
sottoclasse di Jframe. Il contrutto è stato illustrato anche nel precedente capitolo
che trattava l'ereditarietà.
appunti java
pag.87
La nota (4) mostra l'attivazione di un metodo di Jframe, non usato nel primo
esempio. Questo ha lo scopo di impedire che l'utente ridimensioni la finestra.
Evidentemente tale metodo non è necessario invocarlo se si desidera mantenere il
ridimensionamento della finestra del programma. Eseguendo il programma si
nota che la frame disegnata in questo caso non dispone dei pulsanti di
ridimensionamento e riduzione ad icona.
esempio 3: "Aggiungere alla GUI dell'esempio 2 un campo di input dei dati di tipo
JtextField".
Come prima operazione è necessario consultare la documentazione on line per
sapere come si crea un JtextField (costruttori) e di quali metodi essenziali è
dotato:
Nome
Campi o attributi
Costruttori
Metodi
JTextField
Vedi
Sono
molteplici
e
(protected)
inacessibili
documentazione all’utilizzatore.
Identificatori:
JTextField( );
JTextField( String testo );
Invocazione:
JTextField t=new JTextField( );
JTextField t=new JTextField("default");
Effetti:
Crea un oggetto JTextField identificato da t senza
nessun testo di default o con testo.
Identificatore
Tutti i metodi relativi ai Component come:
void setBounds(int x, int y, int larga, int alta);
Invocazione:
• t.setBounds(20,50, 80, 20);
Effetti::
Pckage e
Gerarchia
javax.swing
• il metodo dimensiona e posiziona il campo.
java.awt.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JTextComponent
javax.swing.JTextField
Codifica:
import javax.swing.*;
import java.awt.*;
// (0)
class cap08_es_03 extends JFrame {
JTextField testo=new JTextField();
// (1) costruttore di JtextField
public cap08_es_03() {
super("esempio_3");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,300,200);
Container cpane=getContentPane();
cpane.setLayout(null);
testo.setBounds(50,50,60,20);
cpane.add(testo);
setResizable(false);
setVisible(true);
}
//
//
//
//
(2)
(3)
(4) metodo di tutti i Component
(5) metodo di tutti i Container
appunti java
pag.88
public void gestisci_eventi() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
cap08_es_03 Mio_prg=new cap08_es_03();
}
}
Esecuzione:
Commenti:
La nota (0) indica come si importa il package awt per consentire all'istruzione
della riga (2) di utilizzare un oggetto Container che non è contenuto in swing.
La nota (1) evidenzia che nella sezione "Attribiti" della classe vengono sempre
definiti e creati tutti i componenti grafici che si useranno, in questo caso solo un
JtextField.
La nota (2) evidenzia il metodo getContentPane() con il quale si acquisisce dalla
Jframe creata il suo pannello dei contenuti. Questo non è altro che un oggetto di
tipo Container. Questa acquisizione è sempre necessaria per applicare al pannello
della Frame i componenti grafici da disegnare.
Nella successiva istruzione (3) si dichiara che il layout deve essere null per
consentire di utilizzare coordinate assolute di posizionamento degli oggetti.
La (4) definisce la posizione dell'angolo in alto a sinistra e dimensiona il campo di
testo creato. Infine la (5) addiziona al pannello della frame il campo. Le altre
istruzioni rimangono inalterate rispetto all'esempio due.
esempio 4: "Aggiungere alla GUI dell'esempio 3 un'etichetta di descrizione del
campo di input e un secondo campo per i dati di input. Inserire quindi un pulsante e
un pulsante con icona".
Come prima operazione è necessario consultare la documentazione on line per
sapere come si crea un'etichetta JLabel (costruttori) e un Jbutton con o senza
icona e individuare i metodi essenziali di cui i due oggetti sono dotati:
appunti java
Nome
Campi o attributi
Costruttori
pag.89
JLabel
Vedi document.
Identificatori:
Invocazione:
Effetti:
Metodi
Identificatore
Pckage e
Gerarchia
javax.swing
Nome
Campi o attributi
Costruttori
JButton
Vedi document.
Identificatori:
Invocazione:
Effetti:
Metodi
Identificatore
Pckage e
Gerarchia
javax.swing
JLabel( );
JLabel( String testo );
JLabel( Image icon );
JLabel lb=new Jlabel ("Input: ");
JLabel lb =new JLabel (icon)
Crea un oggetto JLabel identificato da lb con la
scritta "Input: ", la seconda con un'icona.
Tutti i metodi relativi ai Component
Vedi documentazione.
java.awt.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JLabel
JButton( );
JButton( String testo );
JButton( Image icon );
JButton bt=new JButton ("Esegui");
JButton bt =new JButton (icon)
Crea un oggetto JButton identificato da bt con la
scritta "Esegui", la seconda con un'icona.
Tutti i metodi relativi ai Component
Vedi documentazione.
java.awt.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.AbstractButton
javax.swing. Jbutton
Codifica:
import javax.swing.*;
import java.awt.*;
class cap08_es_04 extends JFrame {
JTextField testo_1=new JTextField();
JTextField testo_2=new JTextField();
JLabel etic=new JLabel("input:");
JButton but_1=new JButton("Esegui");
Icon ico=new ImageIcon("grillo.gif");
JButton but_2=new JButton(ico);
public cap08_es_04() {
super("esempio_4");
disegna_frame();
gestisci_eventi();
}
//
//
//
//
//
nuovi
nuovi
nuovi
nuovi
nuovi
componenti
componenti
componenti
componenti
componenti
appunti java
pag.90
public void disegna_frame() {
setBounds(100,100,280,200);
Container cpane=getContentPane();
cpane.setLayout(null);
etic.setBounds(30,20,60,20);
// nuovi posizionamenti
testo_1.setBounds(80,20,80,20);
// nuovi posizionamenti
testo_2.setBounds(170,20,80,20);
// nuovi posizionamenti
but_1.setBounds(80,60,80,80);
// nuovi posizionamenti
but_2.setBounds(170,60,80,80);
// nuovi posizionamenti
cpane.add(etic);
// aggiunta al panel
cpane.add(testo_1);
// aggiunta al panel
cpane.add(testo_2);
// aggiunta al panel
cpane.add(but_1);
// aggiunta al panel
cpane.add(but_2);
// aggiunta al panel
setResizable(false);
setVisible(true);
}
public void gestisci_eventi() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
cap08_es_04 Mio_prg=new cap08_es_04();
}
}
Esecuzione:
eseguendo il programma si ottiene la finerstra seguente:
Commenti:
Lo schema con il quale si disegna la GUI si ripete arricchito di tutti i componenti
desiderati. I campi consentono l'immissione di dati; i pulsanti, se cliccati,
mostrano il loro effetto dinamico ma non succede nulla. La GUI non basta per
ottenere un programma, è necessario gestire gli eventi relativi all'invio dei dati
(tasto Return) o relativi al click dei pulsanti. Il prossimo paragrafo completerà
questa parte fondamentale della trattazione per trasformare una "bella interfaccia
grafica" in una GUI funzionante guidata dagli eventi.
appunti java
8.1.2.
pag.91
Gestione degli eventi
In questo paragrafo si cercherà di approfondire il significato della parola evento,
strettamente legata alla programmazione grafica e ai linguaggi ad oggetti. Si
completerà la costruzione di una GUI con la gestione degli eventi che consentirà
finalmente, ad un programma, di sortire risultati concreti in un "ambiente
grafico" gradevole.
Un evento può essere, per esempio, uno dei seguenti fatti:
• La pressione di un tasto della tastiera (esempio Return);
• Il click del mouse eseguito dall'utente su un componente grafico;
• Il movimento del mouse su un componente ecc.
In ambiente java ogni componente grafico (detto observable) non compie azioni
proprie ma si limita a "notificare" ad un proprio oggetto ascoltatore (detto
observer) che un certo evento ha avuto luogo. Sarà l'ascoltatore che avrà il
compito di eseguire le azioni desiderate dal programmatore. Lo schema che segue
ha una validità generale e mostra che ogni observable può essere dotato di uno o
più observer con questo compito.
In generale nella gestione degli eventi sono convolte tre entità che sono classi o
interfacce :
• una entità Oserbvable (un Button, una Frame, un TextField ecc.)
• una entità Event (ActionEvent, WindowEvent, FocusEvent, KeyEvent,
MouseEvent, MouseMotionEvent)
• una entità Observer (ActionListener, WindowListener, FocusListener,
KeyListener, MouseListener, MouseMotionListener)
Event
Observable
getEvent()
Observer
listener Vector
actionPerformed(Event)
addListener(Observer)
Un oggetto Observable è un’entità nota e utilizzata anche nel precedente
paragrafo, si tratta di uno qualsiasi dei componenti grafici di una GUI; gli eventi
invece sono noti solo intuitivamente. Un evento è una Classe che appartiene a
una delle due categorie seguenti: Evento di basso livello, Evento di Semantica.
• Gli Eventi di basso livello, contenuti nel package java.awt.event, sono
rappresentati dalla seguente gerarchia grafica:
WindowEvent
KeyEvent
ComponentEvent
InputEvent
MouseEvent
FocusEvent
appunti java
pag.92
Queste classi di eventi definiscono le interazioni dell'utente riferite al sistema
delle Finestre; ad esempio WindowEvent è l'insieme delle azioni del mouse sui
pulsanti di una finestra di Window, pulsanti che si trovano in alto a destra e che
effettuano la chiusura, il ridimensionamento e la riduzione ad icona.
FocusEvent si riferisce alle azioni di selezione che danno o tolgono il "fuoco" ad
un componente grafico. Se si usa il tasto di tabulazione (o il mouse) il Fuoco può
essere spostato da un componente all'altro di una Frame, l'evento di attivazione o
disattivazione del fuoco sul componente (FocusGained, FocusLost) può essere
catturato e gestito.
KeyEvent raggruppa gli eventi prodotti dalla tastiera su un componente
(pressione di un tasto) quando il fuoco é attivo su di esso. Per esempio il tasto
Enter (o altro) quando il cursore è contenuto in un TextField.
MauseEvent riunisce tutti gli eventi del mouse riferiti a un componente grafico;
per esempio MouseClicked, MouseEntered, MouseExited, MouseDragged ecc.
•
Gli Eventi di Semantica si occupano dei dettagli di significato dell'azione che
ha avuto luogo. Si riferiscono ad eventi che esigono sempre l'esecuzione di una
specifica azione associata. Gli eventi sono contenuti nel package
java.awt.event.
ActionEvent
AdjustemenEvent
Supponiamo che su una finestra grafica ci siano tre Button e che ognuno di
questi, se premuto, debba eseguire una particolare azione, non è più sufficiente
sapere che è avvenuto un MouseClicked ma si deve individuare
contemporaneamente su quale Button è avvenuto e quindi quale azione attivare.
Se sulla Frame é presente un componente "barra di scorrimento" e si trascina il
suo cursore (AdjistementEvent) è necessario valutare il valore di questo
scorrimento ed eseguire l'attività conseguente.
• Observer
Gli ascoltatori (Observer) assumono il nome di Listener e non sono classi ma
Interfacce di Java.
Una interfaccia è simile ad una classe astratta, e quindi pur definendo metodi
opportuni, non ne implementa nessuno. Ne consegue che questi non possono
essere utilizzati se non vengono prima implementati dal programmatore.
Il programmatore utilizza un’interfaccia ha l'obbligo di ridefinire tutti i metodi
previsti in essa.
Una classe di Java può avere una sola classe genitrice (Astratta o Concreta)
infatti il linguaggio non ammette ereditarietà multipla; viceversa può
"implementare" molte Interfacce. L'interfaccia ha quindi anche la funzione di
"simulare" l'ereditarietà multipla in Java.
Gli ascoltatori (Interfacce) possono essere implementati dai diversi componenti
grafici per "ascoltare" le diverse classi di Eventi.
appunti java
pag.93
WindowListener (può essere associato a una JFrame)
FocusListener
(può essere associato a qualsiasi JComponent)
KeyListener
(può essere associato a qualsiasi JComponent)
MouseListener
(può essere associato a qualsiasi JComponent)
MouseMotionListener
(può essere associato a qualsiasi JComponent)
ActionListener (associato alla cattura di eventi semantici. Es su JButton)
Più in concreto, a una Jframe (è un Component) si possono associare, per
esempio, due tipologie di ascoltatori (observer): MouseListener che "ascoltano"
solo gli eventi di pressione dei tasti del mouse e MouseMotionListener che
"catturano" i click, il movimento e la posizione del mouse sull’oggetto.
Più correttamente Jframe può implementare le due Interfacce MouseListener e
MouseMotionListener secondo lo schema:
MouseListener
mouseClicked (MouseEvent)
mouseEntered (MouseEvent)
mouseExited (MouseEvent)
JFrame
MouseEvent
addMouseListener(MouseListener)
addMouseMotionListener(MouseMotionListener)
getClickCount(): int
getX(): int
getY(): int
MouseMotionListener
mouseDragged (MouseEvent)
mouseMoved (MouseEvent)
Ai componenti JTextField si possono associare le tipologie di ascoltatori
FocusListener che cattura gli eventiti di focalizzazione degli oggetti e
KeyListener che cattura l'evento relativo alla pressione dei tasti.
FocusListener
focusGained (FocusEvent)
focusLost (FocusEvent)
JTextField
FocusEvent
addFocusListener(FocusListener)
addKeyListener(KeyListener)
KeyEvent
KeyListener
keyPressed (KeyEvent)
keyReleased (KeyEvent)
appunti java
pag.94
Ai pulsanti JButton si associano di norma ascoltatori di eventi semantici
ActionListener che rilevano in particolare il click sul pulsante e consentono di
individuare quale sia il Button che ha subito il click e quindi quale azione
svolgere.
ActionEvent
getActionCommand(): String
ActionListener
JButton
actionPerformed(ActionEvent)
addActionListener(ActrionListener)
Ogni Interfaccia Listener cattura solo il gruppo di eventi suoi propri come
evidenzia lo schema:
Ascoltatore
WindowListener
Eventi catturati
windowClosed
windowOpened
windowCloseng
windowIconified
windowDeiconified
windowActived
windowDeactived
MouseListener
mouseClicked
mousePressed
mouseReleased
mouseExited
mouseEntered
MouseMotionListener
mouseDragged
mouseMoved
FocusListener
focusLost
focusGained
Keylistener
keyPressed
keyReleased
keyTyped
ActionListener
actionPerformed
Gli esempi che si svilupperanno nei prossimo paragrafi renderanno più chiari
questi schemi teorici e consentiranno di comprendere il meccanismo di
associazione Observable-Observer.
appunti java
pag.95
8.1.3. Esempi di programmi con GUI ad aventi
• Eventi di basso livello windowListener
Realizziamo un semplice programma che mostri in quali e quanti modi diversi
può essere gestita la chiusura di una JFrame.
I tre esempi che seguono mostrano tutti la stessa finestra vuota che ha l’evento di
interruzione del programma (windowClosing) funzionante. Tale evento si attiva
quando si “clicca” sul pulsante in alto a destra della Frame come da figura:
esempio 5_UNO: "realizzare una finestra che si chiuda correttamente quando
l'utente esegue il click sul pulsante di chiusura."
Codifica:
import javax.swing.*;
import java.awt.event.*;
public class cap08_es_05UNO extends JFrame
public cap08_es_05UNO(){
super("es_5_UNO");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setSize(300,100);
setVisible(true);
}
{
// gruppo di costruzione FRAME
public void gestisci_eventi() {
// Gruppo di gestione eventi:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Metodo rapido
}
// di chiusura senza possibilità di GESTIONE.
public static void main(String args[]) {
cap08_es_05UNO c=new cap08_es_05UNO();
}
}
NUTA: il metodo indicato per gestire il click di chiusura (in grassetto nel codice)
non è sempre accettabile. Infatti se nella Frame si sta gestendo un'applicazione
che esige il salvataggio del lavoro modificato, questa gestione "banale" non
consentirebbe, ed esempio, di segnalare all'utente che si sta chiudendo il
programma senza salvare. Di seguito indichiamo due modalità che consentono
anche di eseguire una "routine" prima dell'abbandono dell'applicazione all'atto
dell'invocazione dell'evento chiusura.
esempio 5_DUE: "realizzare una finestra che si chiuda correttamente quando
l'utente esegue il click sul pulsante di chiusura. "
appunti java
pag.96
Codifica:
import javax.swing.*;
import java.awt.event.*;
public class cap08_es_05DUE extends JFrame implements WindowListener { // (1)
// implements WindowLintener è l'INTERFACCIA di ASCOLTO EVENTI WINDOW
public cap08_es_05DUE(){
super("es_5_DUE");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setSize(300,100);
setVisible(true);
}
public void gestisci_eventi() {
addWindowListener(this);
}
// Istruzione che ASSOCIA
// l'ASCOLTATORE alla JFrame (2)
/* = (3) tutti gli eventi WINDOW DEVONO essere ridefiniti, al più VUOTI == */
public void windowActivated(WindowEvent ev) {}
public void windowOpened(WindowEvent ev) {}
public void windowClosed(WindowEvent ev) {}
public void windowClosing(WindowEvent ev) {
System.exit(0);
// UNICO EVENTO che produce effetti
}
// Si potrebbe inserire qui il codice di gestione. (4)
public void windowIconified(WindowEvent ev) {}
public void windowDeiconified(WindowEvent ev) {}
public void windowDeactivated(WindowEvent ev) {}
/* =================================================================== */
public static void main(String args[]) {
cap08_es_05DUE c=new cap08_es_05DUE();
}
}
Commento al codice:
Le note (1) e (2) mostrano come si debba fare per associare alla JFrame un
ascoltatore di eventi. La (1) mostra che è necessario implemetare l'interfaccia
WindowListener nel programma, la (2) come si dichiara l'associazione
dell'ascoltatore degli eventi alla JFrame.
Una interfaccia, come si è visto nel precedente paragrafo, è una classe astratta
che definisce tutti i metodi ma non li implementa. Spetta al programmatore
implementare con il codice opportuno tutti i metodi definiti in essa. Come si vede
nelle istruzioni comprese nella nota (3) gli eventi definiti nell'interfaccia
WindowListener sono SETTE e devono essere ridefiniti (implementati tutti) nel
codice del programma, al più VUOTI. Nel caso del nostro programma si vuole
eseguire la sola chiusura della Frame e per far questo è sufficiente l'invocazione
(4) dell'istruzione System.exit(0). All'interno di questo metodo potrebbe essere
inserito il codice che avvisa l'utente che il programma sta per essere chiuso e che
è opportuno salvare il lavoro. Questa necessità non poteva essere soddisfatta
dalla chiusura "banale" del primo esempio.
appunti java
pag.97
esempio 5_TER: "realizzare una finestra che si chiuda correttamente quando
l'utente esegue il click sul pulsante di chiusura."
Codifica:
import
import
import
public
java.awt.*;
java.awt.event.*;
javax.swing.*;
class cap08_es_05TER extends JFrame {
public cap08_es_05TER(){
super("es_5_TER");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setSize(300,100);
setVisible(true);
}
public void gestisci_eventi() {
// Gruppo di gestione eventi:
WindowAdapter wa=new ascoltaWindow(); // (1) l'ADATTATORE consente di
this.addWindowListener(wa);
// (2) gestire i soli EVENTI
// desiderati. In questo esempio SOLO WindowClosing
}
/* ==================================================================== */
public class ascoltaWindow extends WindowAdapter { // (3)la classe ADATTATORE
public void windowClosing(WindowEvent ev) {
// (4) UNICO EVENTO
System.exit(0);
// windowClosing.
}
// Si potrebbe inserire qui il codice di gestione.
}
/* ==================================================================== */
public static void main(String args[]) {
cap08_es_05TER c=new cap08_es_05TER();
}
}
Commento al codice:
A differenza dell'esempio due, questo si limita ad associare alla JFrame il solo
evento che si desidera ASCOLTARE. Questa metodologia sarà quella che
adotteremo in quanto è completa rispetto all'esempio UNO ed è più efficiente e
meno prolissa di quella dell'esempio DUE.
Le note (1) e (2) mostrano che è indispensabile creare una sottoclasse di nome
ascoltaWindow() della classe astratta WindowAdapter e associare tale classe alla
JFrame.
Le note (3) e (4) mostrano come si implementa la sottoclasse di WindowAdapter
ascoltaWindow() e come al suo interno venga gestito il solo metodo
windowClosing() che interessa in questo contesto.
• Eventi di basso livello MouseListener
Il movimento del mouse, la sua pressione o rilascio possono essere gestiti in
modo analogo a quanto visto per gli eventi WindowListener.
esempio 6_UNO: "realizzare una finestra che segnali l'ingresso o l'uscita del mouse
da essa e stampi un messaggio opportuno: <il mouse è ENTRATO> o <USCITO>".
Richiesta: utilizzare l'interfaccia WindowListener per la chiusura frame e Mouse
Listener per gli eventi mouse (con la metodologia dell'esempio 5_DUE).
appunti java
pag.98
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_06UNO extends JFrame implements WindowListener, MouseListener {
//(1) Si implementano DUE INTEFACCE ASCOLTATRICI di gruppi di EVENTI DISTINTI.
String msg="Il mouse è ";
// (2) parte costante del messaggio.
JLabel etic=new JLabel(msg+" nella posizione INIZIALE");
// (3) etichetta di output con parte variabile
public cap08_es_06UNO() {
super("es_6_UNO");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,250,150);
Container cpane=getContentPane();
cpane.setLayout(null);
etic.setBounds(30,20,250,20);
cpane.add(etic);
setResizable(false);
setVisible(true);
}
public void gestisci_eventi() {
addWindowListener(this);
// (a) associa a Jframe WindowListener
addMouseListener(this);
// (b) associa a Jframe MouseListener
}
/* ==(4) tutti gli eventi WINDOW devono essere ridefiniti, al più VUOTI === */
public void windowActivated(WindowEvent ev) {}
public void windowOpened(WindowEvent ev) {}
public void windowClosed(WindowEvent ev) {}
public void windowClosing(WindowEvent ev) {
System.exit(0); } // UNICO gestito.
public void windowIconified(WindowEvent ev) {}
public void windowDeiconified(WindowEvent ev) {}
public void windowDeactivated(WindowEvent ev) {}
/* ======================================================================= */
/* ==(5) tutti gli eventi MOUSE devono essere ridefiniti, al più VUOTI === */
public void mouseEntered(MouseEvent ev) {
// ENTERED GESTITO
etic.setText(msg+"ENTRATO");
}
public void mouseExited(MouseEvent ev) {
// EXITED GESTITO
etic.setText(msg+"USCITO");
}
public void mouseClicked(MouseEvent ev) {}
// VUOTO
public void mousePressed(MouseEvent ev) {}
// VUOTO
public void mouseReleased(MouseEvent ev) {} // VUOTO
/* ======================================================================= */
public static void main(String args[]) {
cap08_es_06UNO Mio_prg=new cap08_es_06UNO();
}
}
Esecuzione:
L’esecuzione produce la Finestra di figura: la prima mostra come si presenta
all’utente all’avvio, la seconda e la terza come muta il messaggio stampato a
seconda della posizione del mouse. Tale frame e identica per i due esempi 6_UNO
e 6_DUE.
appunti java
pag.99
esempio 6_DUE: "realizzare una finestra che segnali l'ingresso o l'uscita del mouse
da essa e stampi un messaggio opportuno: <il mouse è ENTRATO> o <USCITO>".
Richiesta: utilizzare la classe ADATTATORE WindowAdapter per la chiusura
frame e MouseAdapter per gli eventi mouse (con la metodologia dell'esempio
5_TRE).
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_06DUE extends JFrame {
String msg="Il mouse è ";
JLabel etic=new JLabel(msg+" nella posizione INIZIALE");
public cap08_es_06DUE() {
super("es_6_DUE");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,250,150);
Container cpane=getContentPane();
cpane.setLayout(null);
etic.setBounds(30,20,250,20);
cpane.add(etic);
setResizable(false);
setVisible(true);
}
public void gestisci_eventi() {
WindowAdapter wa=new ascoltaWindow();
addWindowListener(wa);
MouseListener md=new ascoltaMouse();
addMouseListener(md);
}
// a) ADATTATORE eventi Win
// b) ADATTATORE eventi Mouse
appunti java
pag.100
/* ==================== la classe ADATTATORE ascoltaWindow ============== */
public class ascoltaWindow extends WindowAdapter {
public void windowClosing(WindowEvent ev) {
System.exit(0);} // UNICO evento definito e gestito
}
/* ====================================================================== */
/* =================== la classe ADATTATORE ascoltaMouse =============== */
public class ascoltaMouse extends MouseAdapter {
public void mouseEntered(MouseEvent e) {
etic.setText(msg+"ENTRATO");
// EVENTO semantico Entered.
}
public void mouseExited(MouseEvent e) {
etic.setText(msg+"USCITO");
// EVENTO semantico Exited.
}
}
/* ===================================================================== */
public static void main(String args[]) {
cap08_es_06DUE Mio_prg=new cap08_es_06DUE();
}
}
Eventi di basso livello FocusListener
esempio 7: "realizzare una finestra (programma) con due campi JTextField che
accettino come input due interi ed eseguano la somma stampandola in una JLabel
di output sulla finestra stessa.” Richiesta: La somma deve essere eseguita
quando il "cursore" esce dal secondo campo (evento focusLost).
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_07 extends JFrame {
JTextField testo_1=new JTextField();
JTextField testo_2=new JTextField();
JLabel etic_1=new JLabel("input:");
String msg= "PRODOTTO=";
JLabel etic_2=new JLabel(msg);
public cap08_es_07() {
super("es_7");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,280,200);
Container cpane=getContentPane();
cpane.setLayout(null);
etic_1.setBounds(30,20,60,20);
etic_2.setBounds(30,60,230,20);
testo_1.setBounds(80,20,80,20);
testo_2.setBounds(170,20,80,20);
cpane.add(etic_1);
cpane.add(etic_2);
cpane.add(testo_1);
cpane.add(testo_2);
setResizable(false);
setVisible(true);
}
appunti java
public void gestisci_eventi() {
WindowAdapter wa=new ascoltaWindow();
this.addWindowListener(wa);
FocusAdapter fa=new ascoltaFuoco();
testo_2.addFocusListener(fa);
}
pag.101
// (0)
// (0)
/* ================ Ascolto del solo evento WindowClosig ================ */
public class ascoltaWindow extends WindowAdapter {
public void windowClosing(WindowEvent ev) {System.exit(0);}
}
/* ====================================================================== */
/* ============= Ascolto del solo evento focusLost =================== */
public class ascoltaFuoco extends FocusAdapter {
public void focusLost(FocusEvent e) {
testo_1.setRequestFocusEnabled(true);
// (1)
String t1=testo_1.getText();
// (2)
String t2=testo_2.getText();
// (3)
try { int n1=Integer.parseInt(t1);
// (4)
int n2=Integer.parseInt(t2);
// (5)
etic_2.setText(msg+" "+n1*n2);
// (6)
} catch (NumberFormatException ex) {
// (7)
etic_2.setText(msg+" Immetti NUMERI !!"); // (8)
}
}
}
/* ================================================================== */
public static void main(String args[]) {
cap08_es_07 Mio_prg=new cap08_es_07();
}
}
Commento al Codice:
Le righe di note (0) mostrano che l’ascoltatore di “focus”, che rileva l’uso del
tabulatore o del mouse per fare uscire il cursore da un textfield, è stato registrato
solo sul secondo campo <testo_2>; l’evento focus sarà notificato solo quando il
cursore esce da questo campo.
Le righe di note (1)…(8) sono il vero e proprio programma che sarà eseguito
quando si rileva un FocusLost().
La nota (1) evidenzia il metodo che sposta il focus sul campo testo_1 appena
questo viene tolto a testo_2. Fa passare il focus obbligatoriamente dal campo 1 al
campo 2;
le note (2) e (3) mostrano come si acquisisce il contenuto dei due campi.
Nel blocco try..catch, note (4..8), sono gestite le possibili eccezioni dovute alla
corretta trasformazione delle stringhe in numero.
Attenzione: quando si debbono gestire molti programmi corrispondenti a molti
eventi diversi sarebbe opportuno spostare il relativo codice in una “function
separata per una migliore leggibilità del programma. Si potrebbe scrivere il
metodo in questo modo:
public class ascoltaFuoco extends FocusAdapter {
public void focusLost(FocusEvent e) {
fai_prodotto();
}
}
appunti java
pag.102
e codificare la function fai_prodotto() nel modo seguente:
private static void fai_prodotto() {
testo_1.setRequestFocusEnabled(true);
// (1)
String t1=testo_1.getText();
// (2)
String t2=testo_2.getText();
// (3)
try { int n1=Integer.parseInt(t1);
// (4)
int n2=Integer.parseInt(t2);
// (5)
etic_2.setText(msg+" "+n1*n2);
// (6)
} catch (NumberFormatException ex) {
// (7)
etic_2.setText(msg+" Immetti NUMERI!!"); // (8)
}
}
Esecuzione:
Le tre Frame di figura mostrano: la uno come si presenta il programma all’avvio,
la due cosa stampa se si eseguono due tabulazioni senza immettere dati e la tre
se si tabula immettendo i dati correttamente.
•
Eventi di basso livello KeyListener
esempio 8: "realizzare una finestra (programma) con due campi JtextField che
accettino come input due interi ed eseguano la somma stampandola in un Jlabel di
output sulla finestra stessa.” Richiesta: La somma deve essere eseguita quando si
preme ENTER nel secondo campo (evento keyPressed). "
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_08 extends JFrame {
JTextField testo_1=new JTextField();
JTextField testo_2=new JTextField();
JLabel etic_1=new JLabel("input:");
String msg= "PRODOTTO=";
JLabel etic_2=new JLabel(msg);
appunti java
pag.103
public cap08_es_08() {
super("es_8");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,280,200);
Container cpane=getContentPane();
cpane.setLayout(null);
etic_1.setBounds(30,20,60,20);
etic_2.setBounds(30,60,230,20);
testo_1.setBounds(80,20,80,20);
testo_2.setBounds(170,20,80,20);
cpane.add(etic_1);
cpane.add(etic_2);
cpane.add(testo_1);
cpane.add(testo_2);
setResizable(false);
setVisible(true);
}
public void gestisci_eventi() {
WindowAdapter wa=new ascoltaWindow();
this.addWindowListener(wa);
KeyAdapter ka=new ascoltaKey();
testo_1.addKeyListener(ka);
testo_2.addKeyListener(ka);
}
/* ====================================================================== */
public class ascoltaWindow extends WindowAdapter {
public void windowClosing(WindowEvent ev) {System.exit(0);}
}
/* ====================================================================== */
/* =============== Ascolto del solo evento keyPressed =================== */
public class ascoltaKey extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER) { // (1)
if (testo_1.hasFocus())
// (2)
testo_2.requestFocus();
// (3)
else if (testo_2.hasFocus()) {
// (4)
testo_1.requestFocus();
String t1=testo_1.getText();
String t2=testo_2.getText();
try { int n1=Integer.parseInt(t1);
int n2=Integer.parseInt(t2);
etic_2.setText(msg+" "+n1*n2);
} catch (NumberFormatException ex) {
etic_2.setText(msg+" Immetti NUMERI !!");
}
}
} // fine gestione ENTER
} // fine Keypressed
} // fine class
/* ====================================================================== */
public static void main(String args[]) {
cap08_es_08 Mio_prg=new cap08_es_08();
}
}
appunti java
pag.104
Commento al codice:
Le uniche istruzione nuove rispetto all’esempio precedente sono le (1…4).
La nota (1) mostra che tutto il programma è condizionato al fatto che il tasto
premuto sia un Enter: if (e.getKeyCode()==KeyEvent.VK_ENTER).
La nota (2) mostra la condizione di presenza del focus sul campo UNO,
if(testo_1.hasFocus()), affinchè sia eseguita l’istruzione (3), che consiste nel
semplice spostamento del focus sul campo DUE.
La nota (4) mostra la condizione di presenza del focus sul campo DUE, if
(testo_2.hasFocus()), per l’esecuzione dei calcoli.
Esecuzione:
Visivamente la Frame non cambia rispetto al precedente esempio Sette, cambia
solo il comportamento nel senso che non è più sensibile al tasto di tabulazione
ma solo a quello di Invio.
• Eventi Semantici ActionListener
esempio 10: "realizzare una finestra (programma) con due campi JtextField che
accettino come input due interi, due distinti pulsanti (Jbutton) che consentano di
eseguire rispettivamente la Somma e il Prodotto stampandole in un Jlabel di output
sulla finestra stessa. (evento ActionEvent). "
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_10 extends JFrame {
JTextField testo_1=new JTextField();
JTextField testo_2=new JTextField();
JLabel etic_1=new JLabel("input: ");
String msg= "output: ";
JLabel etic_2=new JLabel(msg);
JButton but_1=new JButton("SUM");
Icon ico=new ImageIcon("grillo.gif");
JButton but_2=new JButton("MLT", ico);
public cap08_es_10() {
super("es_10");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
setBounds(100,100,350,200);
Container cpane=getContentPane();
cpane.setLayout(null);
etic_1.setBounds(30,20,60,20);
etic_2.setBounds(30,140,230,20);
testo_1.setBounds(80,20,120,20);
testo_2.setBounds(210,20,120,20);
but_1.setBounds(80,60,120,80);
but_2.setBounds(210,60,120,80);
cpane.add(etic_1);
cpane.add(etic_2);
cpane.add(testo_1);
cpane.add(testo_2);
cpane.add(but_1);
cpane.add(but_2);
setResizable(false);
setVisible(true);
}
appunti java
pag.105
public void gestisci_eventi() {
WindowAdapter wa=new ascoltaWindow();
this.addWindowListener(wa);
ascoltaButton ba=new ascoltaButton();
but_1.addActionListener(ba);
but_2.addActionListener(ba);
}
// (0)
// (1)
// (2)
/* ==================================================================== */
public class ascoltaWindow extends WindowAdapter {
public void windowClosing(WindowEvent ev) {System.exit(0);}
}
/* ==================================================================== */
/* =========== Ascolto di actionEvent per due Pulsanti Distinti ======== */
public class ascoltaButton implements ActionListener {
// (3)
public void actionPerformed(ActionEvent e) {
String se=e.getActionCommand();
// (4)
String t1=testo_1.getText();
String t2=testo_2.getText();
try {
int n1=Integer.parseInt(t1);
int n2=Integer.parseInt(t2);
if (se.equals("SUM"))
// (5)
etic_2.setText(msg+" Somma= "+(n1+n2));
else if (se.equals("MLT"))
// (6)
etic_2.setText(msg+" Prodotto="+n1*n2);
} catch (NumberFormatException ex) {
etic_2.setText(msg+" Immetti NUMERI !!");
}
} // fine action
} // fine class
/* ====================================================================== */
public static void main(String args[]) {
cap08_es_10 Mio_prg=new cap08_es_10();
}
}
Commento al codice:
Le note (1..3) mostrano che nello stesso ascoltatore sono registrati due pulsanti
but_1 e but_2. Potrebbero essere anche n.
La gestione degli ActionEvent avviene nell’unico metodo
public void actionPerformed(ActionEvent e);
La nota (4) evidenzia che per distinguere quale pulsante è stato premuto bisogna
analizzare ActionEvent con il metodo e.getActionCommand(); che restituisce
l’etichetta del pulsante premuto.
Le note (5) e (6) mostrano che a seconda del pulsante premuto SUM o MLT si
eseguiranno le due diverse operazioni.
Esecuzione:
Visivamente la Frame si presenta come nelle immagini seguenti.
appunti java
pag.106
Eventi Semantici ActionListener sui pulsanti di una toolBar
esempio 11: "realizzare una finestra (programma) dotandolo di una JToolBar con
tre pulsanti icona (Jbutton) che consentano di eseguire rispettivamente tre azioni
intuitive distinte. (eventi ActionEvent). "
Codifica:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class cap08_es_11 extends JFrame {
String fileIco[]={"new.gif", "save.gif", "open.gif"};
String etic[]={"Nuovo","Salva","Apri"};
ImageIcon icona[]=new ImageIcon[3];
JButton but[]=new JButton[3];
JToolBar barra=new JToolBar();
String msg="Evento=";
JLabel lb=new JLabel(msg);
//
//
//
//
//
public cap08_es_11() {
super("es_11");
disegna_frame();
gestisci_eventi();
}
public void disegna_frame() {
Container cpane=getContentPane();
cpane.setLayout(new BorderLayout());
for (int i=0; i<3; i++) {
icona[i]=new ImageIcon(fileIco[i]);
but[i]=new JButton(icona[i]);
but[i].setToolTipText(etic[i]);
barra.add(but[i]);
}
cpane.add("North",barra);
cpane.add("South",lb);
setBounds(100,100,400,300);
setVisible(true);
}
//
//
//
//
//
//
(5)
(6)
(7)
(8)
(9)
(10)
// (11)
// (12)
(0)
(1)
(2)
(3)
(4)
appunti java
pag.107
public void gestisci_eventi() {
WindowAdapter wa=new ascoltaWindow();
this.addWindowListener(wa);
ascoltaButton ba=new ascoltaButton();
for (int i=0; i<3; i++) {
// (13)
but[i].setActionCommand(etic[i]);
// (14)
but[i].addActionListener(ba);
// (15)
}
}
/* ================================================================ */
public class ascoltaWindow extends WindowAdapter {
public void windowClosing(WindowEvent ev) {System.exit(0);}
}
/* ================================================================ */
/* ==================== Gestione actionEvent ====================== */
public class ascoltaButton implements ActionListener {
public void actionPerformed(ActionEvent e) {
String se=e.getActionCommand();
// (16)
lb.setText(msg+" "+se);
// (17)
} // fine action
} // fine class
/* ================================================================ */
public static void main(String args[]) {
cap08_es_11 Mio_prg=new cap08_es_11();
}
}
Commento al Codice:
Le note (0 … 5) mostrano come si costruisce una JtollBar con molte icone.
La (0) mostra che ogni icona è caricata da un file e quindi è necessario assegnare
i nomi in un array di Stringhe;
La (1) mostra che ogni icona ha una etichetta con un nome simbolico che ha due
funzioni: viene mostrato quando il mouse si sofferma sull’icona e viene usato per
discriminare il nome dell’evento ActionEvent attivato dal click.
La (2) e (3) mostrano che è necessario costruire due array, uno per contenere le
“immagini grafiche caricate” ImageIcon[] e il secondo per manipolare gli oggetti
Button corrispondenti but[].
La (4) invoca il costruttore di una JtoolBar.
La (5) mostra che non esiste solo il Layout(null) utilizzato fino a questo momento.
Ne esistono molti che noi non tratteremo, ma in questo caso è necessario
utilizzare una distribuzione della ToolBar senza fare uso delle coordinate schermo
come fino ad ora si è fatto per i vari componenti GUI. Il BorderLayout consente di
collocare gli oggetti a North, East, South, West e Center senza dichiarare le
coordinate.
Il ciclo (6…10) assembla tutti i componenti della ToolBar: crea le singole icone, le
pone sui pulsanti, attiva la modalità SetToolTip() che mostra l’etichetta quanto il
cursore la sfiora e infine pone i singoli pulsanti sulla ToolBar con barra.add().
(11) e (12) indicano che le ToolBar sarà collocata a North mentre la Label di
output a South nella Jframe.
Il ciclo (13…15) mostra che ogni azione associata ad un’icona deve contenere uno
specifico comando etic[] corrispondente Al suo nome simbolico e che ad ogni
pulsante deve essere associato l’ascoltatore di ActionEvent.
appunti java
pag.108
(16…17) corrispondono alla cattura e discriminazione degli eventi e alla loro
stampa a fondo schermo. Per gestire diversi programmi si dovrebbero inserire al
posto della nota (17) una serie di selezioni che attivino ciascuna un diversa
routine corrispondente all’icona che ha catturato l’evento. Come ad esempio:
if (se.equals(“Apri”)) esegui_apri();
else if (se.equals(“Nuovo”)) esegui_nuovo();
else if (se.equals(“Salva”)) esegui_salva():
Esecuzione:
Le tre Frame di figura mostrano: la uno come si presenta il programma all’avvio,
la due cosa stampa se si clicca su “Salva” e infine mostra che la JToolBar può
essere spostata sulla frame nella posizione desiderata.
appunti java
pag.109
8.E – Esercizi
Costruzione di GUI senza eventi
8.1 Si esplorino i packages awt e swing. “per realizzare un programma costituito
da una finestra grafica Jframe non ridimensionabile 300x200, inserendo nella
parte alta tre campi (JtextField) in sequenza di dimensione 80x20 che contengano
ciascuno il testo predefinito <campo uno>, <campo due> e <campo tre>.”
Indicazioni: Il codice da cui desumere indicazioni è quello degli esempi 2 e 3
successivamente si tratta di esplorare la documentazione on line di Java
ricercando tra i metodi di Jframe le istruzioni di dimensionamento,
ridimensionamento e di JtextField per la creazione dei tre campi.
8.2 Si esplorino i packages awt e swing. “per realizzare un programma costituito
da una finestra grafica Jframe non ridimensionabile 200x200 con colore di sfondo
nero (Color.black), inserendo nel suo centro un’icona, scelta da un file <gif>
qualsiasi, inserita in una Jlabel .” Indicazioni:
Il codice da cui desumere indicazioni è quello degli esempi 2 e 4 successivamente
si tratta di esplorare la documentazione on line di Java ricercando tra i metodi di
Jframe (e antenati) le istruzioni di dimensionamento, ridimensionamento e
colorazione del Bkground e di Jlabel per la creazione di una label con icona.
8.3 Si esplorino i packages awt e swing. “per realizzare un programma costituito
da una finestra grafica Jframe non ridimensionabile 300x200, inserendo nella
parte alta un’etichetta (Jlabel) con il testo <Input:>, due campi (JtextField) in
sequenza di dimensione 80x20 che contengano ciascuno il testo predefinito <UNO>,
<DUE> e nella parte bassa un’altra etichetta con la scritta <Output:>.” Indicazioni:
Il codice da cui desumere indicazioni è quello degli esempi 2,3 e 4,
successivamente si tratta di esplorare la documentazione on line di Java
ricercando tra i metodi di Jframe , JtextField e JLabel.
8.4 Si esplorino i packages awt e swing. “per realizzare un programma costituito
da una finestra grafica Jframe non ridimensionabile 300x200, inserendo nella
parte alta un’etichetta (Jlabel) con il testo <Input:>, due campi (JtextField) in
sequenza di dimensione 80x20 che contengano ciascuno il testo predefinito <UNO>,
<DUE> e nella parte bassa un’altra etichetta con la scritta <Output:>. Nella parte
centrale inserisca due pulsanti (Jbutton) con la scritta <esegui>, <pulisci>.”
Indicazioni: Il codice da cui desumere indicazioni è quello degli esempi 2,3 e 4,
successivamente si tratta di esplorare la documentazione on line di Java
ricercando tra i metodi di Jframe , JtextField, Jlabel, JButton.
8.5 “Si desidera realizzare un programma costituito da una frame ridimensionabile
dall’utente che contenga gli stessi componenti dell’esercizio 8.4 ma che consenta di
conservare nell’ordine sequenziale l’etichetta di input i due campi i due pulsanti e
infine l’etichetta output.” Richieste:
Non utilizzare il setLayout(null) come nei precedenti esercizi la setLayout(new
flowLayout()); aggiungendo, uno dopo l’altro, tutti i componenti al pannello.
Provarne il comportamento ridimensionando la frame.
appunti java
pag.110
Costruzione di GUI con eventi
8.6 “realizzare un programma costituito da una finestra il cui sfondo cambi colore
all’entrata e all’uscita del mouse”. Indicazioni:
Utilizzando l’ascoltatore MouseListener come nell’esempio 6_DUE del capitolo
modificare opportunamente i due metodi di gestione degli eventi assegnando nei
due casi i colori rosso (Color.red) e verde (Color.green).
8.7 “realizzare un programma costituito da una finestra che consenta di immettere
un numero intero compreso tra 1 e 10 e stampi in campo di output un array di n
componenti intere comprese tra (-100 e 100) generate in modo random”. Richieste:
Utilizzare l’ascoltatore KeyListener come nell’esempio 8 del capitolo in modo che
alla pressione del tasto ENTER nel campo esegua quanto richiesto. Inserire le
etichette di commento per l’input e l’output e in controllo dell’input. La struttura
del programma e la gerarchia dei metodi deve essere quella adottata nel capitolo
come dal grafo ad albero:
disegna frame()
main()
e 8 07()
windowClosing()
gestisci Eventi()
keyPressed()
8.8 “Realizzare un programma costituito da una finestra che consenta di immettere
due numero naturali e stampi in campo di output sia il massimo comun divisore che
il minimo comune multiplo”. Richieste:
Utilizzare l’ascoltatore KeyListener come nell’esempio 8 del capitolo in modo che
alla pressione del tasto ENTER nel secondo campo esegua quanto richiesto.
Inserire le etichette di commento per l’input e l’output e il controllo dell’input.
Rispettare la scomposizione standard in metodi, separando come dal grafo il
codice dei due metodi MCD() ed mcm():
disegna frame()
main()
e 8 08()
windowClosing()
gestisci Eventi()
MCD()
keyPressed()
mcm()
main() chiama il costruttore di e_8_08() il quale nell’ordine solito invoca
disegna_frame() e gestisci_eventi(); gestisci_eventi() attiva come nell’esempio 8 il
metodo KeyPressed() che al suo interno richiamerà i due metodi statici MCD() e
mcm() con gli opportuni parametri e stamperà i valori restituiti.
8.9 “Realizzare un programma come quello dell’esercizio 8.7 con l’aggiunta di un
pulsante e di un secondo campo di output per permettere, che alla pressione del
pulsante, venga stampato nel nuovo campo di output l’array ordinato.” Richieste:
appunti java
pag.111
Utilizzare KeiListener per gestire l’evento che attiva il metodo crea_mostra() che
genera l’array e ActionListener per gestire la pressione del pulsante che attiva il
metodo ordina_stampa() secondo il grafo seguente:
disegna frame()
windowClosing()
gestisci Eventi()
keyPressed()
crea mostra()
actionPerformed()
ordina stampa()
e 8 09()
8.10 “Realizzare un programma come quello dell’esercizio 8.7 con l’aggiunta di un
pulsante e ma l’uso di un solo campo di output (JtextArea) per permettere, che alla
pressione del pulsante, venga stampato nel campo di output sia l’array disordinato
che quello ordinato separata da un commento opportuno.” Richieste:
Rispettare la scomposizione standard realizzando la seguente finestra di figura.