GUI Java
GUI Java
Il primo package Java che gestisce gli elementi di una GUI 1 è awt. Gli elementi di una GUI si
distinguono in oggetti di due tipi:
• oggetti contenitori
• oggetti componenti
Java usa un sistema generico per gestire la grafica, definendo elementi grafici comuni (oggetti
componenti che possono essere contenitori) in modo da costruire programmi eseguibili su varie
piattaforme e con ambienti grafici differenti (Windows ha un modo di visualizzare le finestre e gli
altri elementi grafici diverso da quello usato da Linux o da MacOs cioè il sistema operativo della
Applet). Il secondo pakage Java che gestisce gli elementi di una GUI, detto swing, è un'estensione
di awt e permette la vera indipendenza dalla piattaforma.
Tra i tipici oggetti contenitori il package awt rende disponibili:
• frame (finestra): la classica finestra costituita da un’area rettangolare e da una barra del
titolo
• panel (pannello): la forma più comune di contenitore che può essere visualizzato sullo
schermo.
• canvas (area di disegno): una semplice superficie di disegno particolarmente utile per
visualizzare immagini o per effettuare altre operazioni grafiche.
I componenti sono oggetti con una propria rappresentazione grafica. Alcuni importanti componenti
della GUI di Java sono:
• Label (etichette)
• Button (pulsanti)
• TextField (campi di testo)
• TextArea (aree di testo)
• Checkbox (caselle di controllo)
Nella gerarchia di classi per i componenti ed i contenitori in Java si può notare che la radice della
maggior parte degli elementi
del package awt
è rappresentata
dalla classe astratta Component
(che a sua volta eredita dalla
superclasse Object,
superclasse di tutti
gli oggetti Java).
In realtà le classi
TextField
e TextArea ereditano
da TextComponent
con radice Component.
La classe Frame
Le classi per creare controlli eredita da Window
e la classeCanvas che eredita da
ereditano direttamente da Component. Container2.
1
Da libro Gallo-Salerno “Java – La programmazione a oggetti” ed. Minerva Italica [UD C3]
2
Containers [Link]
A differenza delle applicazioni, un Applet, non necessita di una finestra per essere eseguito infatti la
finestra è quella del browser a cui si aggiunge un pannello che rappresenta l’applet.
La classe Applet, infatti, eredita da Panel che eredita da Container la cui radice è appunto
Component.
L’inserimento degli oggetti all’interno dei contenitori si realizza con il metodo add() con la
sintassi:
[Link] (oggettoDaAggiungere)
Finestra o = new Finestra(); // creo oggetto che "ha - un" oggetto JFrame ed un oggetto JPanel
}
}
nb:
setDefaultCloseOperation([Link]);
questo metodo permette di modificare l'azione di default di Java di continuare ad eseguire l'applicazione che
ha generato il frame anche dopo aver clickato sull'apposito bottone di chiusura del frame; segue un elenco
del significato del campo flag :
EXIT_ON_CLOSE : terminazione del programma quando il frame viene chiuso
DISPOSE_ON_CLOSE : chiude e libera il solo oggetto frame, il processo continua
DO_NOTHING_ON_CLOSE : mantiene aperto il frame e continua il processo (ignoriamo l'evento)
HIDE_ON_CLOSE : chiude il frame e continua l'esecuzione
Per nascondere i frames: setVisible(false) - deprecato hide()
Creazione e uso dei componenti standard
La classe JLabel : un esempio
// Applicazione con uso dei componenti di una GUI
// in ambiente JCreator
// Uso di un pannello per introdurre
// componenti JLabel
// e gestione di layout con allineamento in griglia
import [Link].*;
import [Link].*;
private JFrame f ;
private Container c;
private JPanel p;
private JLabel l;
private JButton b1, b2;
private JTextField t1, t2;
private JTextArea a1, a2;
private JCheckBox c1, c2, c3;
private ButtonGroup g; // per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button
private JRadioButton rb1, rb2;
public Gui2 () { // costruttore
f = new JFrame("Finestra con componenti"); // crea frame invisibile
[Link](450,330); // misure in pixel per impostare le dimensioni
[Link](200,100); // e la posizione con (0,0) angolo sup. sin.
[Link](true); // per ridimensionare con mouse
c = [Link]();
p = new JPanel();
[Link] ([Link]); // sfondo colorato
l = new JLabel ("Etichetta");
b1 = new JButton ();
b2 = new JButton ("Bottone");
t1 = new JTextField (30);
t2 = new JTextField ("immetti il nome", 20);
a1 = new JTextArea(5, 20); // senza barre a scorrimento se non si inserisce in JScrollPane
a2 = new JTextArea("immetti una lista di nomi ", 5, 20);
[Link] ("Dimensionata con 5 righe e 20 colonne");
c1 = new JCheckBox();
c2 = new JCheckBox("Testo");
c3 = new JCheckBox("Testo attivato", true);
[Link]("Senza testo"); // per visualizzare, al passaggio del mouse, testo esplicativo
g = new ButtonGroup(); // per gestire selezione
rb1 = new JRadioButton("Lingua Francese", false);
rb2 = new JRadioButton("Lingua Francese", true);
[Link](rb1);
[Link](rb2);
[Link](l); // aggiunge al pannello un'etichetta con testo
[Link](b1); // aggiunge al pannello un bottone colorato con etichetta
[Link](b2); // aggiunge al pannello un bottone con testo
[Link](t1); // aggiunge al pannello un campo di testo con ampiezza specificata
[Link](t2); // aggiunge al pannello un campo di testo con inizializzazione
// ed ampiezza specificata
[Link](a1); // aggiunge al pannello un' area di testo con Righe e Colonne specificate
[Link](a2); // aggiunge al pannello un'area di testo con inizializzazione
// e Righe e Colonne specificate
[Link](c1); // aggiunge al pannello una casella di controllo vuota e disattivata
[Link](c2); // aggiunge al pannello una casella di controllo con stringa
[Link](c3); // aggiunge al pannello una casella di controllo con stringa ed attivata
[Link](rb1); // aggiunge al pannello i Radio Button
[Link](rb2);
[Link](p); // aggiunge il pannello
[Link](true); // mostra il frame (dimensioni 400x400)
[Link] (JFrame.EXIT_ON_CLOSE);
}
public static void main(String [] args) {
Gui2 o = new Gui2();
}
}
Altri metodi della classe JButton:
• String getText() per ottenere il valore dell’etichetta dell’oggetto, deprecato getLabel()
Abbiamo già fatto uso della classe GridLayout con costruttore GridLayout (numero righe,
numero colonne) per posizionare i componenti nelle celle di una tabella tutte caratterizzate dalla
stessa dimensione. Un altro costruttore permette di impostare anche la spaziatura verticale e quella
orizzontale: GridLayout (num_righe, num_colonne, spaziatura_verticale, spaziatura_orizzontale)
BorderLayout
BorderLayout divide lo schermo in cinque regioni: North, East, West,
South, Center. È, di default il gestore di layout per i contenitori ad alto
livello come i Content Pane.
BorderLayout assicura a North, South, East e West tanto spazio quanto
richiedono, lo spazio rimanente viene assegnato a Center.
BorderLayout può essere costruito con costruttore BorderLayout () oppure con BorderLayout
(spaziatura_orizzontale, spaziatura_verticale) specificano lo spazio orizzontale e verticale tra due
componenti.
nb: nel package swing tali regioni vengono definite dalle costanti BorderLayout.PAGE_START,
BorderLayout.LINE_START, BorderLayout.LINE_END, BorderLayout.PAGE_END e
[Link] rispettivamente per indicare in alto, a sinistra, a destra, in basso e
centro.
Oltre alle numerose classi che già awt introduceva per gestire il posizionamento, swing rende
disponibile anche la classe BoxLayout per una scelta general purpose nell’impilare i vari elementi.
3
Gestori di Layout [Link] (guida visuale)
/******************************************************************/
/* GESTIONE DI UN LAYOUT SEMPLICE MEDIANTE USO DI SWING ****/
/******************************************************************/
import [Link].*;
import [Link].*;
//Creiamo i componenti
[Link](true);
[Link](true);
[Link]('*');
[Link](ipLabel);
[Link](ipText);
[Link](passwordLabel);
[Link](passwordText);
[Link](fileDaInviareLabel);
[Link](fileDaInviareText);
[Link](pulsante);
setContentPane(pannello); // rendiamo il pannello parte del nostro frame
setResizable(false); // immodificabili dimensioni [*]
setVisible(true); // visualizziamo il tutto
}
new SempliceLayout();
}
}
/*****************************************************************************/
/* GESTIONE DI UN LAYOUT A GRIGLIA AVANZATA MEDIANTE USO DI SWING ****/
/*****************************************************************************/
import [Link].*;
import [Link].*;
public class Layout extends JFrame {
//Creiamo i componenti
JLabel ipLabel = new JLabel("IP host", [Link]); // per default a sinistra
JLabel passwordLabel = new JLabel("Password", [Link]);
JLabel fileDaInviareLabel = new JLabel("File da inviare", [Link]);
JTextField ipText = new JTextField(); // non ci preoccupiamo di impostare numero caratteri
JPasswordField passwordText = new JPasswordField();
JTextField fileDaInviareText = new JTextField();
JButton pulsante = new JButton("Inizia TX");
// Definiamo un metodo che ci servirà per definire i limiti di layout
void impostaLimite(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) {
[Link] = gx;
[Link] = gy;
[Link] = gw;
[Link] = gh;
[Link] = wx;
[Link] = wy;
}
public Layout() { // costruttore dell'applicazione
super("File transfer appz");
setSize(300, 120);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pannello = new JPanel();
// impostiamo le proprietà dei componenti
[Link](true);
[Link](true);
[Link]('*');
//definiamo il gestore di layout
GridBagLayout grigliaAvanzata = new GridBagLayout(); // griglia personalizzata
GridBagConstraints limite = new GridBagConstraints();
[Link](grigliaAvanzata);
//definiamo i limiti di ogni componente e lo aggiungiamo al pannello
impostaLimite(limite,0,0,1,1,35,0); //etichetta IP host
[Link] = [Link];
[Link] = [Link];
[Link](ipLabel,limite);
[Link](ipLabel);
impostaLimite(limite,1,0,1,1,65,100); //campo IP host
[Link] = [Link];
[Link](ipText,limite);
[Link](ipText);
impostaLimite(limite,0,1,1,1,0,0); //etichetta password
[Link] = [Link];
[Link] = [Link];
[Link](passwordLabel,limite);
[Link](passwordLabel);
impostaLimite(limite,1,1,1,1,0,100); //campo password
[Link] = [Link];
[Link](passwordText,limite);
[Link](passwordText);
[Link](pulsante);
setContentPane(pannello); // rendiamo il pannello parte del nostro frame
setVisible(true); // Visualizziamo il tutto!
}
import [Link].*;
import [Link];
public EtichetteEcampi() {
super("Etichette e campi");
setSize(350, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pannello = new JPanel();
[Link](true);
[Link](true);
[Link](true);
[Link](campoDiTesto);
[Link](areaDiTesto);
setContentPane(pannello);
setVisible(true); // Visualizziamo il tutto!
}
}
nb: public GridLayout (int rows, int cols) crea un layout a griglia dove tutti i componenti sono delle stesse
dimensioni. Uno tra numero rige e colonne - ma non entrtambi - può essere zero: significa che un qualsiasi
numero di oggetti può essere inserito o nell'unica riga o nell'unica colonna
// da [Link]
Etichette e bordi
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public EtichetteBordi(){
[Link]([Link]);
[Link]([Link]);
[Link]([Link]);
[Link]([Link]([Link]));
[Link]([Link]([Link]));
[Link]([Link]([Link]));
nb: public GridLayout (int rows, int cols, int hgap, int vgap) crea un layout a griglia dove tutti i
componenti sono delle stesse dimensioni e rende possibile impostare il numero di pixel tra le colonne come
per il margine destro e sinistro dai bordi (horizontal gap) ed il numero di pixel tra le righe come per i
margini in alto e basso dai bordi (vertical gap).
/**
* @(#)[Link]
* Gui application
* @author 3AI
* @version 1.00 2009/4/4
*/
import [Link].*;
import [Link].*;
class MioPanel extends JPanel{
public MioPanel(){
[Link](new Dimension(180, 150)); // per reimpostare dinamicamente
}
public void paintComponent(Graphics g){
[Link](g);
[Link]([Link]);
[Link](20,20, 100,80);
[Link]([Link]);
[Link](30,30, 80,60);
[Link]([Link]);
[Link]("ciao",50,60);
}
}
class Bottone extends JPanel{
private JButton b;
public Bottone(){
private JFrame f;
private Container c;
private MioPanel p; // pannelli personalizzati
private Bottone p2;
public Gui(){
f = new JFrame("Due pannelli"); // crea un nuovo JFrame Inizialmente invisibile con titolo
c = [Link](); // recupera il "muro grezzo"
p = new MioPanel(); // crea pannello personalizzato adattabile alle dimensioni della finestra
p2 = new Bottone(); // crea altro pannello personalizzato adattabile alle dimensioni di bottone e finestra
[Link]([Link]);
[Link](new BorderLayout()); // scelta di Layout che distingue tra alto, basso, destra, sinistra e centro
[Link](p,[Link]); // al centro il pannello con disegno
[Link](p2,BorderLayout.PAGE_END); // in basso il bottone (per retrocompatibiltà anche SOUTH)
}
public static void main(String[] v){
Gui gui = new Gui();
}
}
// Lo stesso esempio di Applicazione con uso GUI già usato per introdurre componenti GUI
// in un pannello. Posizionamento tramite gestori di layout: impilando in verticale
import [Link].*;
import [Link].*;
public class Gui2 {
private JFrame f ;
private Container c;
private JPanel p;
private JLabel l;
private JButton b1, b2;
private JTextField t1, t2;
private JTextArea a1, a2, a3;
private JScrollPane sp; // con barre a scorrimento inserendo JTextArea in JScrollPane
private JCheckBox c1, c2, c3:
private ButtonGroup g; // per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button
private JRadioButton rb1, rb2;
public Gui2 () { // costruttore
f = new JFrame("Finestra con componenti"); // crea frame invisibile
// per impostare le dimensioni e la posizione:
[Link](450,330); // misure in pixel
[Link](200,100); // (0,0) angolo sup. sin.
[Link](true); // per ridimensionare con mouse
c = [Link](); // recupera il "muro grezzo"
p = new JPanel();
[Link] ([Link]); // sfondo colorato
[Link] (new BoxLayout (p, BoxLayout.PAGE_AXIS)); // impila gli elementi in verticale nel pannello
c1 = new JCheckBox();
c2 = new JCheckBox("Testo");
c3 = new JCheckBox("Testo attivato", true);
[Link]("Senza testo"); // per visualizzare, al passaggio del mouse, testo esplicativo
// Per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button
g = new ButtonGroup(); // per gestire selezione
rb1 = new JRadioButton("Lingua Francese", false);
rb2 = new JRadioButton("Lingua Francese", true);
[Link](rb1);
[Link](rb2);
[Link](l); // aggiunge al pannello un'etichetta con testo
[Link](b1); // aggiunge al pannello un bottone colorato con etichetta
[Link](b2); // aggiunge al pannello un bottone con testo
[Link](t1); // aggiunge al pannello un campo di testo con ampiezza specificata
[Link](t2); // aggiunge al pannello un campo di testo con inizializzazione ed ampiezza specificata
[Link](a1); // aggiunge al pannello un' area di testo con Righe e Colonne specificate
[Link](a2); // aggiunge al pannello un'area di testo con inizializzazione e Righe e Colonne specificate
[Link](sp); // aggiunge al pannello un Pannello a scorrimento che contiene
// un'area di testo con inizializzazione e Righe e Colonne ridotte per visualizzare barre a scorrimento
[Link](c1); // aggiunge al pannello una casella di controllo vuota e disattivata
[Link](c2); // aggiunge al pannello una casella di controllo con stringa
[Link](c3); // aggiunge al pannello una casella di controllo con stringa ed attivata
[Link](rb1); // aggiunge al pannello i Radio Button
[Link](rb2);
import [Link].*;
import [Link].*;
import [Link].*;
le dimensioni obbligatorie pur se nulle, qui sono scelte in modo da permettere di leggere
completamente, eseguendo in ambiente JCreator, il titolo della cornice del visualizzatore della
Java Applet Window con messaggio di Applet avviato o non avviato.
NB: Un’ applet dunque può aprire un'altra finestra ma compare automaticamente un avviso anche
solo come piccola icona di allerta in alto a sinistra della nuova finestra che ricorda come la Java
Applet Window non sia mai completamente invisibile.
nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa
cartella del bytecode (classes). Si noti che,scegliendo come progetto Basic Java Applet
si crea nella sottocartella classes la seguente pagina
<html>
<head> </head>
<body bgcolor="000000">
<center><applet code = "[Link]"
width = "500"
height = "300" >
</applet>
</center>
</body>
</html>
con uso di tag obsoleto <applet></applet>
Esercizio:
• 4 bottoni con testo: Freccia Sx, Freccia Dx, Freno Manuale, Avvia Motore
• un’etichetta con testo Luci con associate 3 caselle opzione (esclusiva) con testo posizioni,
anabbaglianti, abbaglianti , tutte non attivate
• un’etichetta carburante
• ed un JTextField largo 30 pixel
150 pixel
570 pixel
Soluzione:
import [Link].*;
import [Link].*;
import [Link].*;
[Link](true);
}
}
Nel codice HTML: <object code ="[Link]" width= "0" height= "0"></object>
nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa
cartella del bytecode (classes).
I Canvas
Tra i vari contenitori Java il Canvas (area di disegno o tela) è una semplice superficie di disegno
particolarmente utile per visualizzare immagini o per effettuare altre operazioni grafiche.
Un oggetto di tipo Canvas è semplicemente una porzione rettangolare di schermo, una specie di
pannello che possiede un proprio metodo paint() che, pur diverso dall’omonimo metodo di un
Applet, usa anch’esso oggetti della classe Graphics ed è richiamato dal sistema in fase di creazione
e aggiornamento in modo che l’oggetto Graphics associato possa aggiornarsi .
Una istanza della classe Canvas non è molto utile: riceve eventi da tastiera e da mouse, ma non li
tratta, ed il metodo paint() non disegna alcunché.
Generalmente la classe Canvas è usata solo come base per subclassi, che possono generare
oggetti più utili: una subclasse di Canvas generalmente farà almeno un’override del metodo
paint() e possibilmente anche dei metodi di gestione degli eventi come quelli del mouse e della
tastiera.
Quando il contenuto del canvas dovrà essere modificato al di fuori del metodo paint(), sarà
possibile richiamare il contesto grafico con i metodi getGraphics(). Vedremo come questi
metodi possono essere usati per i canvas creando ad esempio un bottone di forma personalizzata e
colore modificato da eventi
public Graf () {
[Link] (d);
[Link](300,180); // per impostare le dimensioni e la posizione: misure in pixel
[Link](200,100); // (0,0) angolo sup. sin.
[Link](true); // per ridimensionare (per default non ridimensionabili) con mouse
[Link](true); // mostra il frame (dimensioni 300x150)
[Link] (JFrame.EXIT_ON_CLOSE);
}
public static void main(String [] args) {
Graf ogg = new Graf();
}
}// fine classe principale
// classe esterna eventualmente nello stesso file [Link]
[Link]("Font di dimensioni "+ size +" stile " + style + " e nome " + name);
}
}// fine classe che eredita da Canvas
Esercizio:
import [Link].*;
import [Link].*;
import [Link].*;
nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa
cartella del bytecode (classes).
Gli Eventi
Quando l’utente di una GUI digita caratteri o usa il mouse o un componente dell’interfaccia grafica,
il gestore delle finestre di Java invia una comunicazione al programma per segnalare che si è
verificato un evento.
Esistono classi d’ascolto di eventi (event listener) per permettere ad un programma di indicare
quali eventi gradisce ricevere.
Ogni programma dovrà creare un oggetto per ognuna delle classi cui è interessato; tali oggetti
prendono il nome di ascoltatori (oggetto di una classe di ascolto).
La classe di ascolto deve implementare almeno una interfaccia di ascolto (interfacce di tipo
listener).
Un ascoltatore di eventi è un oggetto di una classe di ascolto che implementa almeno una interfaccia
di ascolto. Tali interfacce sono contenute nel package [Link] che deve essere importato.
Per creare un ascoltatore bisogna conoscere l’origine dell’evento che può essere l’intera applet o
una sua parte. Per origine dell’evento si intende il contenitore o il componente che può generare
l’evento (ad esempio un pulsante è l’origine dell’evento tipo “clic su pulsante”).
Eventi del mouse
Esempio con gestione eventi del mouse:
// [Link]
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
// classe di ascolto
public class ClickMe extends JApplet implements MouseListener { // tipo di evento ad esempio
// pressione del mouse
private Spot spot = null;
private static final int RADIUS = 7;
public void init() {
addMouseListener(this); // per collegare ascoltatore all’origine dell’evento: tutta l’applet
}
// [Link]
public class Spot {
public int size;
public int x, y;
• con codice HTML che carica ed esegue Applet con "Java Plug in" per consentire al browser
di usare un interprete Java esterno (più aggiornato) e adatta anche a Mozilla – FireFox ed
altri browser che non supportano il tag <object>:
<html>
<head><title>Uso Eventi</title></head>
<body>
<p>Carica ed esegue Applet con uso di Java Plug-in (anche per NN versioni precedenti alla 6):
<p>appare uno spot rosso nel punto dove fai click col mouse
<p><object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
width="200" height="100">
<param name="code" value="[Link]">
<param name="type" value="application/x-java-applet;version=1.6">
<comment><embed type="application/x-java-applet" width="200" height="100"
code="[Link]">
</embed>
</comment>
</object>
</body>
</html>
NB: getWidth() e getHeight() per recupero dimensioni senza creare oggetto Dimension con
getSize()
Esempio con gestione eventi del mouse con adattatore (classe di raccordo Adapter) che evita di
dover scrivere tutte le segnature dei metodi dell'interfaccia di ascolto :
// [Link] versione Applet
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class Pallini extends JApplet{
private int xP,yP;
public void init() {
MiaClasseAscoltoMouse A1 = new MiaClasseAscoltoMouse ();
addMouseListener (A1); // lega la classe di ascolto all’origine dell’evento: cioè
// tutta l’applet (è sottinteso this : manca oggetto origine)
}
public void paint(Graphics g) {
[Link]([Link]);
[Link](xP,yP,20,20);
}
public void test() { // per test in ambiente JCreator
int x = getLocationOnScreen().x; // ritorna l’ascissa del punto
int y = getLocationOnScreen().y; // ritorna l’ordinata del punto
[Link]( "punto (" + xP + "," + yP +")" );
}
// classe interna cioè innestata non statica
private class MiaClasseAscoltoMouse extends MouseAdapter {
public void mousePressed (MouseEvent e) {
xP = [Link](); // accede alla variabili istanza xP e yP della classe esterna
yP = [Link](); // recupera gli attributi dell’oggetto di tipo Point “puntato” dal mouse
// cioè le coordinate x ed y
repaint();
test(); // per visualizzare coordinate
}
}
}// fine classe Pallini
Con codice HTML:
<html>
<head><title>Uso Classe Adapter</title></head>
<body>
Se premi con il mouse (all'interno di una zona) compare un pallino rosso <br>
<object code ="[Link]" width = "500" height = "400"></object>
</body>
</html>
NB: per estrarre coordinate sullo schermo getLocationOnScreen() della classe [Link] può
essere invocato per recuperare le coordinate del punto in alto a sinistra ad esempio dell’applet; il metodo
ritorna infatti un oggetto di tipo Point con attributi x ed y ed è applicabile al componente corrente
/**
* @(#)[Link]
*
* Pallini application
*
* @author classi
* @version 1.00 2011/4/14
*/
import [Link].*;
import [Link].*;
import [Link].*;
public class Pallini extends JPanel{
private int x,y;
private JFrame f ;
public Pallini() {
f= new JFrame();
[Link](this);
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 generati da componenti delle classi Button, TextField, List
e MenuItem
Molti controlli Swing oltre a JButton generano eventi che possono essere catturati da un
actionListener cioè sono sorgente di eventi ActionEvent
Esempio di struttura di applicazione con gestione eventi generati4 da interazione con interfaccia
grafica:
un pulsante (parte della GUI) è origine dell’evento (di azione)
tutta la classe è ascoltatore dell’evento (di azione)
esiste un solo metodo nell’interfaccia
import [Link].*;
import [Link].*;
import [Link].*;
public class NomeClasse implements ActionListener { // classe ascoltatore
// con interfaccia per eventi di azione
private JFrame f;
private Container c;
private JPanel p;
private JButton b;
MouseEvent:
• implementando il Listener
class MyXXXListener implements XXXListener {
// definizione dei metodi definiti da XXXListener
}
• estendendo l’adapter
Problema: scrivere un ascoltatore (listener) che alla pressione di bottoni diversi mostri il contenuto
della JTextField inserita nella finestra istanza dell'applicazione MyFrame
→ L’ascoltatore deve aver accesso al riferimento a quel JTextField di quella particolare istanza
Primo caso: uso classe Listener interna cioè innestata non statica
Quando si usano classi esterne, è possibile “capire” il componente che ha notificato l’evento
associando ai diversi componenti un diverso valore della proprietà actionCommand
Confronto soluzioni:
Le classi interne hanno il pregio di consentire una migliore gestione della struttura interna
dell'oggetto (comportamenti adatti in ambito OO), appesantendo il caricamento dell'applicazione di
quel (tanto o poco) necessario al ClassLoader per caricare e risolvere un certo numero di classi in
più, rispetto alla soluzione dell'implementazione diretta.
Quale che sia la scelta adottata, ciò che importa è la consapevolezza degli effetti.
Esercizi non risolti
Esercizio (non risolto): realizzare un'applicazione grafica con dimensione della finestra 200x200
pixel come da layout in Fig.1
Alla pressione di ogni pulsante si vuole che lo sfondo cambi colore come da Fig.2
Esercizio (non risolto): realizzare un'applet EuroConvertitore implementando sia TextListener sia
FocusListener
Esercizio: progettare un pannello che sia maschera di input che consenta all’utente di :
• inserire articoli (e relativo prezzo), sia in lire che in euro
• avere sempre sott’occhio il totale, sia in lire che in euro
• poter salvare su file, in qualunque momento, l’elenco degli ordini inseriti.
Di seguito realizzare l'applicazione di test che crea una finestra di dimensioni 300x300 pixel e permette di visualizzare
tale maschera col layout di figura
Reset
Riempimento con valori generati casualmente e visualizzazione nell’area di testo sulla destra
Riempimento con valori decrescenti
Ricerca del valore massimo scritto a fondo pagina
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
class GUI {
repaint(); repaint();
try{ try{
[Link](80); [Link](80);
}catch(InterruptedException ie) { return;} }catch(InterruptedException ie) {return;}
} }
} }
} }
nb: l'uso di una tela (oggetto di classe che estende Canvas) disegnando con metodo paint() causa maggior
effetto "flicker" o sfarfallio.
Confronto: scritta scorrevole che si modifica da campo di testo (unico thread associato al main)
import [Link].*;
import [Link].*;
import [Link].*;
// classe esterna
class MioPanel extends JPanel {
private String nome;
private JTextField testo;
private int Xpos;
}
}
nome = [Link]();
[Link]([Link]);
[Link](nome, Xpos,50);
if ([Link] ("produttore")){
[Link]([Link]);
[Link](Xpos,5,raggio/2,raggio/2); // x,y dell'angolo in alto a sinistra,
// larghezza, altezza
}
}
}
JTextField e documento: eventi swing
Associato ad ogni campo di testo c’è un documento che gestisce il testo presente e ad ogni modifica del
contenuto questo documento genera un DocumentEvent per segnalare l'avvenuto [Link] evento
dev'essere gestito da un opportuno DocumentListener
}
public void changedUpdate(DocumentEvent e){ }
}
public class DocumentP{
public static void main(String [] args){
JFrame f = new JFrame ("Testo");
Container c = [Link]();
Es12Panel guiP = new Es12Panel();
[Link](Color. lightGray); // sfondo del pannello colorato
[Link](guiP); // aggiunge il pannello
[Link](300,100);
[Link](true);
[Link] (JFrame.EXIT_ON_CLOSE);
}
}
ADT
JList (da Tutorial Sun)
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
[Link](fireButton);
[Link]([Link](5));
[Link](new JSeparator([Link]));
[Link]([Link](5));
[Link](employeeName);
[Link](hireButton);
[Link]([Link](5,5,5,5));
add(listScrollPane, [Link]);
add(buttonPane, BorderLayout.PAGE_END);
}
class FireListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//This method can be called only if there's a valid selection
//so go ahead and remove whatever's selected.
int index = [Link]();
[Link](index);
[Link](index);
[Link](index);
}
}
}
//This listener is shared by the text field and the hire button.
class HireListener implements ActionListener, DocumentListener {
private boolean alreadyEnabled = false;
private JButton button;
//Required by DocumentListener
public void insertUpdate(DocumentEvent e) {
enableButton();
}
//Required by DocumentListener.
public void removeUpdate(DocumentEvent e) {
handleEmptyTextField(e);
}
//Required by DocumentListener.
public void changedUpdate(DocumentEvent e) {
if (!handleEmptyTextField(e)) {
enableButton();
}
}
if ([Link]() == -1) {
//No selection, disable fire button.
[Link](false);
} else {
//Selection, enable the fire button.
[Link](true);
}
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("ListDemo");
[Link]( JFrame.EXIT_ON_CLOSE);
[Link](new Runnable() {
prima…
dopo ….
Esercizio: Disegno di un auto in altra finestra alla pressione di un pulsante (evento della GUI)
// Applet [Link]
// esempio di Applet con gestione eventi della GUI: creazione di eventi personalizzati
// Uso canvas
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
Auto A;
[Link](A);
[Link](true);
}
// definizione classe d'ascolto interna cioè innestata non statica
private class GestiscePulsante implements ActionListener{ // interfaccia per eventi di azione
Disegna();
}
} // fine classe d'ascolto
}
Una classe innestata non è altro che una classe che viene definita all’interno di un’altra classe.
N.B. : fino alla versione 1.3 di Java, il termine “classe innestata” non era stato ancora adottato. Si parlava
invece di “classe interna” (“inner class”).
Dalla versione 1.4 in poi, la Sun ha deciso di sostituire il termine “classe interna”, con il termine “classe
innestata” o classe annidata (“nested class”). Il termine “classe interna” deve ora essere utilizzato solo per
le classi innestate che non sono dichiarate statiche. In realtà la stragrande maggior parte delle volte si
utilizzano classi interne.
Leggere testo di input con applicazioni GUI e il package swing
import [Link].*;
import [Link].*;
import [Link].*;
String nome="";
nb: per eseguire la pagina html con programma appletviewer, inserito come tools in JCreator,
impostare come opzioni:
Per scoprire le potenzialità di swing5 eseguire la demo in file compresso seguendo percorso
C:\Programmi\Java\jdk1.6.0_21\demo\jfc\SwingSet2\[Link]
5
SWING [Link]
Esempio senza apparente gestione di eventi
import [Link].*;
import [Link].*;
import [Link].*;
public AppIcone () {
pack();
setVisible (true);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
nb: salvando in stessa cartella il sorgente e la sottocartella che contiene le immagini IMG
Uso componente JColorChooser per visualizzare in finestra modale palette di colori
import [Link].*;
import [Link].*; // per Color
Java si è diffuso storicamente, e trae forza, dal concetto di applet6 come piccola (almeno all’inizio
dei tempi) applicazione da eseguirsi dentro un browser Internet
Una applet ("applicazioncina") è una applicazione non autonoma, ma pensata per far parte di una
pagina Internet
· porta dinamicità alle pagine HTML "statiche"
· viene eseguita dal browser, che quindi deve incorporare un interprete Java
e questo può causare un tempo di visualizzazione più alto
· non ha un main, perché la sua vita è dipendente dalla pagina in cui è visualizzata, eredita dalla
superclasse ed è public.
· non deve creare un frame principale, perché usa la finestra del browser che la ospita (in effetti,
Applet deriva direttamente da Panel e quindi è essa stessa un pannello)
Se si usano componenti Swing, occorre necessariamente usare JApplet infatti una Applet con
componenti Swing non viene disegnata correttamente
6
Da [Link]
// [Link]
import [Link]; // importa solo la necessaria classe Graphics definita all’interno del package
// che implementa l’Interfaccia Utente detta Abstract Windowing Toolkit
Si ottiene il seguente effetto con uso di BROWSER (Internet Explorer recenti o FireFox Mozilla)
Ciao alla citta '! cioè una scritta nella finestra del browser
(5, 25)
Ciao Nome_proprio
import [Link].*;
public class Stati extends Applet { // Stati è sottoclasse di Applet con costruttore Applet()
public void start () { // richiamato ogni volta che si accede a pagina web
// invoca metodo paint(..)
[Link](); // metodo originale
[Link]("Eseguito start()");
}
public void stop () { // richiamato ogni volta che si esce da pagina web
// sia finestra iconizzata, sia non in primo piano
[Link](); // metodo originale
[Link]("Eseguito stop()");
}
7
Lanciando da browser aprire visualizzazione console (simbolo Plug-in Java che compare nella barra di sistema)
NB: da pannello di controllo (Java Plug-in) si deve scegliere l’opzione “Mostra Java nella barra di sistema” e
selezionare i browser in cui usare Java™ Plug-in come runtime Java predefinito
APPLET e SICUREZZA
Un'applet non può fare tutto quello che fa una applicazione. Poiché può essere scaricata dalla rete,
sarebbe troppo pericoloso permettere a un'applet di fare qualunque cosa ed è costretta a rispettare
un ben preciso modello di sicurezza ("sandbox")
In molte situazioni, questi vincoli sono troppo rigidi e rischierebbero di rendere impossibile la
costruzioni di applet utili.
APPLET FIRMATE
Attraverso tecnologie di cifratura, un'applet può essere firmata, ossia a essa può essere allegato un
certificato che ne garantisce l'origine. A tali applet firmate, cui si attribuisce maggiore fiducia,
l'utente può consentire di svolgere alcune o tutte le operazioni sottoposte a vincolo.
POLITICHE DI SICUREZZA
A partire da Java 2, l'utente può decidere caso per caso quali politiche di sicurezza applicare, con
una granularità molto fine
Esiste il concetto di policy file, che elenca le politiche locali e si può stabilire che una certa applet,
proveniente da un ben preciso sito, ha diritti particolari. Un tale file può essere fornito da chi
sviluppa l'applet, o modificato dall'utente con lo strumento PolicyTool.
8
Per questo motivo si preferisce lavorare con applicazioni quando ci si connette a Internet e se ne usano le risorse.
Graphics
Un oggetto di tipo Graphics rappresenta essenzialmente una porzione di schermo in cui è possibile mostrare
testi, immagini, forme, in modo indipendente dalla piattaforma
Per disegnare su un oggetto GUI (di tipo contenitore), dobbiamo chiamare opportuni metodi sull’oggetto
Graphics dello stesso.
Esistono due modi:
• ottenere l’oggetto Graphics con [Link]()
• modificare il metodo di disegno del contenitore cioè estendere la classe ereditando
da una classe Frame o Container o Panel (package awt) o JPanel (swing)
Non solo l'applet ha il metodo paint che può essere ridefinito, ma anche gli oggetti di tipo Component,
ovvero tutti i componenti GUI (del package awt)9, quindi per cambiare l'aspetto grafico di un qualsiasi
componente grafico basta ridefinirne10 il metodo paint.
Tra tutti i Component c'è la tela su cui è possibile disegnare, essa è un oggetto della classe Canvas.
Chi è abituato a programmare con altri linguaggi si aspetterà che nel metodo paint ci sia un’ inizializzazione
del device su cui si va a disegnare e poi una serie di istruzioni tipo drawLine, drawBox eccetera [ 1], ma
questo non è del tutto vero, ovvero nei Component e nelle applet non c'è nessun metodo grafico.
Il parametro g di tipo Graphics del metodo paint o paintComponent, infatti, contiene i metodi grafici usabili
da Java e rappresenta in qualche modo l'area (contesto grafico) in cui verranno disegnate le varie primitive.
Graphics è una classe che non può essere istanziata: nel metodo paint o paintComponent viene ricevuto
un’oggetto di tale classe come parametro e se ne possono usare i metodi oppure si può recuperare il
contesto grafico (di un contenitore: di tipo Frame o Container o Panel in awt o JPanel in swing) che possiede
tutti i metodi di disegno.
Per ottenere il contesto grafico ad esempio della finestra corrente usando il metodo getGraphics( ):
Graphics g = getGraphics();
nb: usando il metodo getGraphics() sarà necessario richiamare il metodo dispose() per deallocare l’oggetto
quando se ne termina l’uso.
[1] nel disegnare in ambiente Dev-Cpp:
9
Analogamente per gli oggetti di tipo JComponent (swing) esiste il metodo paintComponent
10
[Link]
GRAFICA BI-DIMENSIONALE IN JAVA
[Link]
Esempio
Pannello con grafica personalizzato: [Link].
La funzione paintComponent riempe un rettangolo
sfumato, vi disegna dentro un fumetto con scritto
grande "Ciao!", traccia con tratto spesso tre linee
alla base del fumetto.
Disegno diretto
Metodi per disegnare direttamente una figura. I
parametri sono interi esprimenti numero di pixel,
cioè le primitive vanno fornite direttamente in device space.
Dimension d = getSize();
[Link] (image, 0,0, [Link],[Link], this);
Tutorial Sun
[Link]
APPENDICE: Gestione semplificata delle immagini
Le immagini memorizzate in file locali o su Internet possono essere lette in un'applicazione Java e
visualizzate da oggetti Graphics. A partire dal JDK 1.4 la lettura di un'immagine è molto semplice e non
richiede il recupero del "toolkit di default" nè la creazione di un oggetto di tipo MediaTracker per tracciare
le immagini nel componente assegnato né l'attesa se più di un'immagine deve essere caricata prima di poterla
disegnare.
A questo punto la variabile image contiene un riferimento ad un oggetto che incapsula i dati dell'immagine.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
import [Link].*;
public ImmaginePannello() {
try {
image = [Link](new File("immagini/[Link]"));
// cartella immagini in sottocartella con bytecode
[Link](image, 0, 0, null);
}
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link].*;
public ImmagineURL() {
try {
image = [Link](new URL
("[Link]
[Link](image, 0, 0, null);
}
}
Una galleria di immagini con Java
[Link]
/**
* @(#)[Link]
*
* Immagini application
* una galleria di immagini con recupero di URL
*
* @author quarte
* @version 1.00 2011/4/9
*/
import [Link].*;
import [Link].*;
import [Link].*;
/*
* la mini gallery necessita di alcune immagini
* salvate nell'omonima cartella con lo stesso percorso dei file .class
* immagini/[Link]
* immagini/[Link]
* immagini/[Link]
* immagini/[Link]
* immagini/[Link]
* immagini/[Link]
* immagini/[Link]
*/
public class Immagini extends JPanel implements ActionListener {
//definiamone attributi e metodi
JLabel pic;
public Immagini() {
super(new BorderLayout()); // per rendere possibili allineamenti [*]
//definiamo i nomi da associare alle immagini
String[] coloPics = {
"Rosso", "Blu", "Verde", "Rosa", "Giallo", "Azzurro", "Viola" };
JComboBox coloList = new JcomboBox(coloPics); //creiamo la lista delle immagini
[Link](6); // si seleziona l'ultima voce
[Link](this);
//definiamo le informazioni relative alle immagini
pic = new JLabel();
[Link]([Link]().deriveFont([Link]));
[Link]([Link]); // allineamento [*]
updateLabel(coloPics[[Link]()]);
[Link]([Link](5,0,0,0));
//impostiamo la dimensione delle immagini
[Link](new Dimension(200, 110+10));
//settiamo i bordi e i colori.
add(coloList, BorderLayout.PAGE_START);
add(pic, BorderLayout.PAGE_END);
setBorder([Link](15,15,15,15));
}
// gestione eventi di azione
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox)[Link]();
String nomePic = (String)[Link]();
updateLabel(nomePic);
}
// recupero immagine con controllo esistenza file
// apertura e lettura del contenuto della cartella
protected void updateLabel(String name) {
ImageIcon icon = createImageIcon("immagini/" + name + ".gif");
[Link](icon);
[Link]("colore: " + [Link]());
if (icon != null) {
[Link](null);
}else{
[Link]("Impossibile trovare la pagina");
}
}
//notifica nel caso l'immagine non sia nel percorso specificato
protected static ImageIcon createImageIcon(String path) {
[Link] imgURL = [Link](path);
//nomeapplicazione..[Link](path)per recuperare l'URL cioè il percorso del file
if (imgURL != null) {
return new ImageIcon(imgURL);
}else{
[Link]("Impossibile trovare il file: " + path);
return null;
}
}
//creazione dell'interfaccia
private static void InterfacciaGrafica() {
//setaggio della finestra
JFrame frame = new JFrame("MiniGallery");
[Link](JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new Immagini();
[Link](true);
[Link](newContentPane);
//mostriamo la finestra che contiene la GUI
[Link]();
[Link](true);
}
public static void main(String[] args) {
// creaiamo il visualizzatore e mostriamo la GUI
[Link](new Runnable() { public void run() {
InterfacciaGrafica();}});
} // in realtà sarebbe sufficiente mostrare la GUI senza creare oggetto runnable
} // fine applicazione
Inserire immagini o disegnare con ImageIcon
La classe [Link]è usata per piccole immagini su bottoni o etichette e per disegnare su
qualunque componente di tipo JComponent.
Risulta molto semplice inserire un'immagine di tipo ImageIcon in un bottone o etichetta: ad esempio per
inserirla in un componente di tipo JLabel basta il seguente codice:
import [Link].*;
import [Link].*;
public ImageLabel() {
}
}
String url="[Link]
[Link] where = new URL(url);
ImageIcon anotherIcon = new ImageIcon(where);
Per disegnare su un componente di tipo JComponent si ricorre al metodo paintIcon con la seguente sintassi:
// Disegnare immagini di tipo ImageIcon in un componente di tipo JLabel (che è di tipo JComponent)
import [Link].*;
import [Link].*;
new ImageIconLabel();
}
} // fine applicazione
//classe esterna
class MyIcon extends JLabel{ //oppure, più generico, estendendo dalla classe JComponent
public MyIcon(){
x = 5 pixel
y = 5 pixel
APPENDICE: Introduzione agli eventi e loro gestione
Gli eventi vengono gestiti dal sistema, che effettua per prima cosa alcune operazioni predefinite, e
quindi passa il controllo a una procedura, detta procedura-evento, con la quale il programmatore
specifica il comportamento dell’applicazione in risposta all’evento. Si parla di modello a delega
quando il programmatore può decidere a quale ascoltatore “delegare” la gestione dell’evento.
Gli eventi più comuni sono quelli generati dal mouse o dalla tastiera.
Le procedure-evento
Gli oggetti predefiniti sono gli elementi di base di applicazioni visuali. Al contrario degli ambienti
OOP puri, nei quali il programmatore definisce gli oggetti come blocchi di codice e di dati correlati,
negli ambienti visuali gli oggetti sono entità preconfezionate, già pronte per l’uso. Queste entità
sono elementi reali, come caselle di testo o pulsanti di comando.
L’ambiente di sviluppo mette a disposizione apposite barre di pulsanti che servono per la creazione
degli oggetti. Ogni pulsante sulla barra rappresenta un tipo di oggetto predefinito disponibile.
Lo sviluppatore seleziona il pulsante corrispondente al tipo di oggetto che vuole creare e quindi lo
traccia su una finestra. Successivamente ne imposta le proprietà e infine scrive le procedure-evento
necessarie per far rispondere l’oggetto alle azioni dell’utente.
Schede di approfondimento
Nel linguaggio Java, quando l’utente di una interfaccia grafica (GUI) digita caratteri o usa il mouse
o un componente dell’interfaccia grafica, il gestore delle finestre di Java invia una comunicazione
al programma per segnalare che si è verificato un evento.
Oggetto Oggetto
Genera evento ascoltatore
GUI
Classe che
implementa
event
listener
Interfaccia:
metodi
Risposta a evento per
rispondere
a evento
Esistono classi d’ascolto di eventi (event listener) per permettere ad un programma di indicare quali
eventi gradisce ricevere.
Ogni programma dovrà creare un oggetto per ognuna delle classi cui è interessato; tali oggetti
prendono il nome di ascoltatori (oggetto di una classe di ascolto).
La classe di ascolto deve implementare almeno una interfaccia di ascolto (interfacce di tipo
listener). Un ascoltatore di eventi è un oggetto di una classe di ascolto che implementa almeno una
interfaccia di ascolto.
Tali interfacce11 sono segmenti software predefiniti per gestire l’evento.
Per creare un ascoltatore bisogna conoscere l’origine dell’evento che può essere ad esempio l’intera
Applicazione o Applet (programma Java eseguibile da browser) o una sua parte.
Per origine dell’evento si intende il contenitore o il componente che può generare l’evento (ad
esempio un pulsante è l’origine dell’evento di azione tipo “clic su pulsante”).
11
Contenute nel package [Link] libreria che deve essere importata.
I passi, dunque, per gestire gli eventi programmando in Java sono i seguenti:
1. Decidere quali eventi interessano l’applicazione o l’applet. Tale fase si traduce nella scelta
dell’interfaccia di ascolto da implementare
2. Decidere qual è l’origine dell’evento: il componente o contenitore che può generare (notificare)
l’evento e creare tale oggetto GUI (ogni componente ad eccezione di LABEL o un contenitore
ad esempio tutto l’Applet).
L’oggetto ascoltatore può essere ad esempio tutta l’Applet o tutta l’applicazione che
implementa (implements) la classe predefinita d’ascolto di quell’evento che ne definisce
l’interfaccia (metodi di risposta a quell’evento).
L’oggetto ascoltatore può essere creato come istanza di una classe di ascolto definita
dall’utente che implementa (implements) la classe predefinita d’ascolto di quell’evento
che ne definisce l’interfaccia (metodi di risposta a quell’evento)
La classe Scanner
Sfortunatamente, la classe InputStream non possiede metodi comodi per la ricezione di dati
numerici e stringhe
Per ovviare a questo inconveniente, Java 5.0 ha introdotto la classe Scanner nel package util.
Un oggetto di tipo Scanner consente di leggere da qualsiasi flusso di ingresso (ad es. un file) senza
rendere necessaria la gestione di ecccezioni.
Si può usare anche per leggere dati in ingresso da tastiera ricevuti tramite l'oggetto [Link] (di
tipo InputStream adatto per la lettura di flussi di byte)
Prima di tutto si deve importare la classe Scanner all'interno del file .java che ne fa uso.
import [Link];
All'interno del codice si deve creare un nuovo oggetto della classe Scanner
Cosa succede se l’utente non digita un numero intero sulla tastiera (ad esempio, se scrive 55KZ) ?
Effetto senza cattura delle eccezioni:
• Leggere una parola fino al primo carattere di spaziatura: spazio, fine riga, tabulazione
boolean b = [Link]();
Uso finestre di dialogo: di input, di allarme o di scelta multipla
La classe JOptionPane permette di creare facilmente una dialog box standard di tipo “pop
up” che consente all’utente di inserire dati o essere avvisato di qualcosa. Per informazioni sull’uso
di tale classe si consulti How to Make Dialogs, nella sezione del The Java Tutorial.
Una dialog box appare, di solito, come mostrato a lato, ma si possono message
icon
apportare modifiche al layout modificandone le proprietà con l’impostazione input value
di opportuni parametri dei metodi di tipo showXxxDialog option buttons
parentComponent: il Componente che contiene la dialog box; se tale primo parametro è null imposta il Frame di
default usato come parent: la finestra di dialogo sarà centrata nello schermo e risulterà indipendente dal resto
dell'applicazione.
title: il titolo della finestra di dialogo che appare nella cornice superiore; il valore di default dipende dal tipo di dialog
(la stringa “Input” per dialog in input, “Messaggio” per dialog in out, “Selezionare un’opzione” per dialog di conferma).
messageType : definisce lo stile del messaggio. Possibili valori, che prevedono relative icone di default, sono:
ERROR_MESSAGE
INFORMATION_MESSAGE
WARNING_MESSAGE
QUESTION_MESSAGE
PLAIN_MESSAGE
optionType: definisce il set dei bottoni di opzione (senza limiti) che appaiono in basso al dialog box:
DEFAULT_OPTION
YES_NO_OPTION
YES_NO_CANCEL_OPTION
OK_CANCEL_OPTION
options: una più dettagliata descrizione del set dei bottoni di opzione. Di solito un array di stringhe ma è previsto un
array di oggetti che possono essere di tipo:
Component cioè un componente aggiunto direttamente al bottone
Icon usata come label in un JButton
altro cioè un’oggetto convertito in una stringa mediante il metodo toString. Il risultato è usato come
label in un JButton
icon: una icona decorativa. Il valore di default è stabilito dal parametro messageType.
La classe JOptionPane mette a disposizione tre tipi di pannelli: Confirm Dialog, Input Dialog e Message
Dialog
• il primo tipo di pannello viene usato quando si deve chiedere all'utente di effettuare una scelta tra un
gruppo di possibilità;
• il secondo torna utile quando si debba richiedere l'inserimento di una stringa di testo
• mentre il terzo viene usato per informare l'utente.
JOptionPane fornisce un gruppo di metodi statici che permettono di creare facilmente questi pannelli
ricorrendo ad una sola riga di codice senza istanziare oggetti:
String nome;
nome = [Link] ("Come ti chiami?", "Mario");
// initialValue è “Mario”
Tra i metodi showConfirmDialog per finestra di dialogo che chiede di confermare una
domanda tipo yes/no/cancel, il più semplice :
[Link](null, "Conferma");
Alcuni metodi showMessageDialog per finestra di informazione:
[Link](null, nome);
Tutte le finestre di dialogo (dialogs) create sono modali cioè ogni metodo showXxxDialog blocca il
thread corrente fino a quando l’interazione con l’utente non è stata completata
Esempio di applicazione con test di alcuni metodi di tipo showXxxDialog tra cui:
• finestra di dialogo in lettura con modifica del titolo di default della dialog box
• finestra di dialogo in scrittura con modifica del titolo di default della dialog box
class Dialog {
// per stesso effetto .... ma con titolo "Lettura" ... invece di "Input"
// Mostra una finestra di dialogo che chiede all’utente di selezionare una stringa
return input;
}
public void visualizza(String testo){ // uso finestra di dialogo in scrittura
}
public static void main (String arg[]){
Dialog o = new Dialog();
String messaggio = "Inserita: " + [Link]();
[Link](messaggio);
}// fine main
[Link] (null,
"Icona personalizzata",
"Titolo del dialog",
JOptionPane.INFORMATION_MESSAGE,
new ImageIcon("[Link]")); // icona personalizzata
JButton b1 = new JButton("Bottone 1");
// Component come messaggio
[Link] (null, b1,
null, JOptionPane.INFORMATION_MESSAGE );
[Link](null,
"Conferma");
Per permettere opzioni di scelta in input, con metodo showInputDialog, volendo personalizzare l’icona ad esempio col
logo di Java (immagine [Link] di dimensioni 16x16, nella stessa cartella), il titolo:
try {
[Link]("[Link]");
} catch (Exception e) { } // stile CDE/Motif. Scelta disponibile su qualunque piattaforma
Look & Feel : insieme delle due proprietà che caratterizzano un ambiente a finestre:
• l'aspetto dei componenti (ovvero la loro sintassi) – specifiche di visualizzazione
• la maniera in cui essi reagiscono alle azioni degli utenti (la loro semantica) – specifiche di
interazione
La natura multipiattaforma di java ha spinto i progettisti di Swing a separare le problematiche di disegno
grafico dei componenti da quelle inerenti al loro contenuto informativo, con la sorprendente conseguenza di
permettere agli utenti di considerare il Look & Feel come una proprietà del componente da impostare a
piacere. La distribuzione standard del JDK comprende di base due alternative: Metal e Motif.
La prima definisce un Look & Feel multipiattaforma, progettato per risultare familiare agli utenti di ogni
piattaforma; la seconda implementa una vista familiare agli utenti Unix. Le distribuzioni di java per
Windows e Mac includono anche un L&F che richiama quello della piattaforma ospite.
Per impostare da programma un particolare look & feel è sufficiente chiamare il metodo
[Link](String className)
passando come parametro il nome di un l&f installato nel sistema.
Un’applicazione che crea una finestra in cui si apre una dialog box modale che risulta centrata rispetto a
quest’ultima:
import [Link].*;
import [Link].*; // per Container
class DialogF extends JFrame {
public void visualizza(){
// per aprire una finestra
// nel punto x,y con larghezza 400, altezza 200
setBounds(100,100,400,200);
Container cont=getContentPane();
[Link](null);
setVisible(true);
String nome;
nome = [Link] (cont,"Come ti chiami?", "Mario");
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
public static void main (String arg[]){
DialogF o = new DialogF();
[Link]();
}// fine main
}// fine applicazione
La stessa applicazione (che crea una finestra in cui si apre una dialog box modale che risulta
centrata rispetto a quest’ultima) con modifica del Look & Feel
import [Link].*;
import [Link].*; // per Container
Container cont=getContentPane();
[Link](null);
setVisible(true);
String nome;
nome = [Link] (cont,"Come ti chiami?", "Mario");
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
public static void main (String arg[]){
DialogF o = new DialogF();
[Link]();
}// fine main
}// fine applicazione
nb:
Due parole sui metodi per visualizzare o nascondere i frames :
setVisible(true) per rendere visibile il frame che non lo è per default - deprecato show()
setVisible(false) ovviamente per nasconderlo - deprecato hide()
Per scegliere la posizione iniziale si può utilizzare il metodo setBounds(int, int, int, int); con argomenti
nell'ordine di digitazione x ed y dell'angolo superiore sinistro e dimensioni larghezza ed altezza del frame
Progetto di un pannello che sia maschera di input
/**
* @(#)[Link]
*
* Maschera classe che crea il pannello consentendo di:
* inserire articoli (e relativo prezzo), sia in lire che in euro
* avere sempre sott’occhio il totale, sia in lire che in euro
* poter salvare su file, in qualunque momento, l’elenco degli ordini inseriti.
*
* @author classe quarta
* @version 1.00 2011/4/9
*/
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
// Costruzione del secondo Box orizzontale in cui collocare i due campi di testo
nome = new JTextField(15);
prezzo = new JTextField(7);
[Link]([Link]);
riga2 = new Box(BoxLayout.X_AXIS);
[Link](nome);
[Link](prezzo);
// Costruzione del quarto Box orizzontale per area di testo e Box verticale
riga4 = new Box(BoxLayout.X_AXIS);
[Link](elenco);
[Link]([Link](30));
[Link](boxRadio);
// Assemblaggio dei vari blocchi
add(riga1);
add(riga2);
inserisci = new JButton("Aggiungi articolo");
add(inserisci);
add(riga3);
add(riga4);
save = new JButton("Salva");
[Link](false); // inizialmente disabilitato
add(save);
// Creazione e registrazione dei listener
[Link] (new InsertListener(nome, prezzo, totale,elenco, lire, save)); // in modo anonimo
CurrencyListener c = new CurrencyListener(prezzo, totale);
[Link](c); // unico listener per i due radio-button
[Link](c); // unico listener per i due radio-button
[Link] (new SaveListener(elenco, totale,lire, save));
}
} // fine classe che estende JPanel
class InsertListener implements ActionListener {
JTextField nome, prezzo, totale;
JTextArea elenco;
JRadioButton lire;
JButton save;
public InsertListener (JTextField n, JTextField p, JTextField t, JTextArea e, JRadioButton l, JButton s){
nome=n;
prezzo=p;
totale=t;
elenco=e;
lire=l;
save=s;
}
public void actionPerformed(ActionEvent e){
[Link](true);
double tot = [Link]([Link]());
double prz = [Link]([Link]());
[Link]([Link](prz + tot));
[Link] ([Link]() + " " + [Link]() +([Link]() ? " ITL" : " EUR") + "\n");
[Link]("");
[Link]("");
[Link]();
}
} // fine classe ascoltatore per inserimento nuovi articoli
class CurrencyListener implements ActionListener {
JTextField prezzo, totale;
public final double CAMBIO = 1936.27;
public CurrencyListener(JTextField p,JTextField t){
prezzo=p; totale=t;
}
public void actionPerformed(ActionEvent e){
double tot = [Link]([Link]());
String p = [Link]();
if ([Link]("")) p="0";
double price = [Link](p);
if ([Link]().equals("Lire")) {
// erano Euro, vanno convertiti in lire
tot *= CAMBIO;
price *= CAMBIO;
// elimina la parte frazionaria di un numero reale,
tot = [Link](tot); // arrotondandolo
price = [Link](price);
}
else { // erano Lire, da convertire in Euro
tot /= CAMBIO;
price /= CAMBIO;
tot = [Link](tot*100)/100;
price = [Link](price*100)/100;
// Arrotondamento alla IIª cifra decimale: si sposta la virgola, si arrotonda e si rimette la virgola dov'era
}
[Link] ([Link](tot));
[Link](price==0.0 ? "" :
[Link](price)); // Estetica: un prezzo di 0.0 non viene indicato, si mette le stringa vuota.
}
} // fine classe ascoltatore per conversione valuta
import [Link].*;
import [Link].*;
class TestMaschera {
Container c = [Link]();
Maschera guiP = new Maschera();
[Link](300,300);
[Link](true);
[Link] (JFrame.EXIT_ON_CLOSE);
}
}
/**
* @(#)[Link]
*
* Menu application
*
* @author Sun
* @version 1.00 2011/5/4
*/
// [Link]
import [Link].*;
import [Link].*;
import [Link].*;
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
public Menu() {
//a submenu
[Link]();
submenu = new JMenu("Un sottomenu");
Container c= [Link]();
[Link](400,300);
[Link](menuBar);
[Link](true);
}
new Menu();