16. Java: Swing - UNISA · 2002. 6. 11. · 16. Java: Swing Vittorio Scarano Algoritmi e Strutture...
Transcript of 16. Java: Swing - UNISA · 2002. 6. 11. · 16. Java: Swing Vittorio Scarano Algoritmi e Strutture...
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
1
Corso di Laurea in Informatica
Università degli Studi di Salerno
16. Java: Swing
Vittorio Scarano
Algoritmi e Strutture Dati: Sistemi Distribuiti
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
2
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
2
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
3
Programmazione grafica
• Una necessità:– interfaccia intuitiva e gradevole
– tutti gli applicativi oggigiorno sono grafici
• In Java 1.0 viene introdotto Abstract Windows Toolkit (AWT)
• Principi di AWT:– indipendenza dalla reale rappresentazione grafica attraverso
i “ peer” • componenti dipendenti dall’ambiente che gestivano il vero
input/output grafico
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
4
Alcuni problemi di AWT
• Il minimo comune denominatore”– per piattaforme come X/Motif, Macintosh, Windows
• Alcuni bug su varie piattaforme
• Il passo successivo– Netscape progetta la Internet Foundation Classes
– che rappresentano finestre in maniera uguale su tutte le piattaforme
• La Sun decide di partire da IFC per presentare Swing– che fa parte delle Java Foundation Classes
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
3
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
5
Caratteristiche di Swing
• Ricca dotazione di interfacce
• Piattaforma più robusta e testata
• Minore dipendenza dalla piattaforma di base
• Risultato coerente su tutte le piattaforme– ma possibile programmare l’aspetto (es. alla Windows)
• Alcuni (piccoli) problemi:– essendo soluzioni implementate senza i peersaranno più
lenti del corrispondente in AWT
• Di AWT si usano comunque alcune componenti:– gestione eventi, etc.
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
6
Swing e AWT
Swing+
AWTAWT
• Di AWT si usano comunque alcune componenti:– gestione eventi, etc.
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
4
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
7
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
8
Un primo passo: creazione di un frame
• Una finestra di massimo livello cioè direttamente visualizzata dal Sistema Operativo è detta frame
• La classe di AWT si chiama Frame, quella di Swing si chiama JFrame (notare la doppia maiuscola)
• Fondamentale la ereditarietà:– tutti i nostri componenti grafici devono ereditare da una
complessa (ma non necessariamente conosciuta) gerarchia
• I frame sono contenitori:– possono contenere altre componenti grafiche
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
5
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
9
La classe SimpleFrame
import javax.swing.*;
public class SimpleFrame extends JFrame {public SimpleFrame () {
setSize (WIDTH,HEIGHT);}
public static final int WIDTH = 300;public static final int HEIGHT= 200;
}
• Import – per la extends
• Sottoclasse di JFrame • Costruttore
– uso del metodo della classe JFrame per settare la dimensione
• Variabili di istanza– solo costanti utilizzate
SimpleFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
10
La classe SimpleFrameTest
import javax.swing.*;
public class SimpleFrameTest {public static void main (String[] args) {
SimpleFrame f = new SimpleFrame();f.setDefaultCloseOperation (
JFrame.EXIT_ON_CLOSE);f.show();
}}
• Semplice programma di test
• Crea un frame• Setta alcune
caratteristiche– termina il programma
quando il frame viene chiuso
• Mostra il frame
SimpleFrameTest.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
6
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
11
Alcune caratteristiche di un frame
• Tra le tante caratteristiche ereditate da JFrame – la posizione
– il titolo
– la icona (in alto a sinistra a sulla barra)
• Nel prossimo esempio:– vogliamo creare un frame al centro dello schermo
• abbiamo bisogno di Toolkit per prelevare la dimensione corrente dello schermo
– scegliendo il titolo e la icona
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
12
La classe CenteredFrame
import java.awt.*;import java.awt.event.*;import javax.swing.*;public class CenteredFrame extends JFrame {
public CenteredFrame () {Toolkit kit = Toolkit.getDefaultToolkit();Dimension screenSize=
kit.getScreenSize();int screenHeight=screenSize.height;int screenWidth=screenSize.width;
setSize (screenWidth/2,screenHeight/2);setLocation (screenWidth/4,
screenHeight/4);Image img = kit.getImage("icon.gif");setIconImage(img);setTitle("Centered Frame");
}}
• Import – per extends e Toolkit
• Uso di Toolkit – prelevare le dimensioni
dello schermo
• Set dimensione• Set locazione• Set immagine della
icona del frame• Set titolo
CenteredFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
7
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
13
La classe CenteredFrameTest
import javax.swing.*;
public class CenteredFrameTest {public static void main (String[] args) {
CenteredFrame f = new CenteredFrame();
f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
f.show();}
• Semplice programma di test
• Crea un frame• Setta alcune
caratteristiche– termina il programma
quando il frame viene chiuso
• Mostra il frame
CenteredFrameTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
14
Usiamo i Frame come contenitori
• Possiamo aggiungere dei componenti ai Frame
• Ricca disponibilità:– tra gli altri JPanel
• che è un contenitore ma che può anche essere soggetto all’inserimento di testo, disegni etc.
• La idea di JPanel:– offre un metodo paintComponent() dalla superclasse
• che si occupa di ridisegnare la finestra ad ogni spostamento, ridimensionamento, etc
– basta fare override del metodo senza dimenticare di richiamare il metodo della superclasse
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
8
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
15
La classe HelloWorldFrame (1)
import javax.swing.*;import java.awt.*;
public class HelloWorldFrame extends JFrame{public HelloWorldFrame () {
setTitle ("Ciao Mondo!");setSize (300,200);HelloWorldPanel p = new
HelloWorldPanel();Container c = getContentPane();c.add(p);
}}class HelloWorldPanel extends JPanel{
public void paintComponent (Graphics g) {super.paintComponent(g);g.drawString ("Ciao a tutti!", 75,100);
}}
• Import – per extends
• Costruttore:– setta il titolo e la size– crea un Panel
• uso classe interna allo stesso file (privata)
– preleva il ContentPane del JFrame
– aggiunge il pannello p
HelloWorldFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
16
La classe HelloWorldFrame (2)
import javax.swing.*;import java.awt.*;
public class HelloWorldFrame extends JFrame{public HelloWorldFrame () {
setTitle ("Ciao Mondo!");setSize (300,200);HelloWorldPanel p = new
HelloWorldPanel();Container c = getContentPane();c.add(p);
}}class HelloWorldPanel extends JPanel{
public void paintComponent (Graphics g) {super.paintComponent(g);g.drawString ("Ciao a tutti!", 75,100);
}}
• Classe interna:– di uso privato di
HelloWorldFrame
• Override del metodo– con chiamata al metodo
della superclasse– e aggiunta di una
stampa di una stringa
HelloWorldFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
9
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
17
La classe HelloWorldTest
import javax.swing.*;import java.awt.*;public class HelloWorldTest {
public static void main ( String[] args) {HelloWorldFrame f = new
HelloWorldFrame();f.setDefaultCloseOperation (
JFrame.EXIT_ON_CLOSE);f.show();
}}
• Semplice programma di test
• Crea un frame• Setta alcune
caratteristiche– termina il programma
quando il frame viene chiuso
• Mostra il frame
HelloWorldTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
18
La visualizzazione di immagini
• Si usano metodi per caricare una immagine e per visualizzarla su un pannello
• Alcuni commenti:– le immagini possono essere caricate da URL (e quindi da
Internet) con estrema facilità
– lentezza nel caricamento• nel primo esempio lo ignoriamo e poi vediamo come può essere
risolto
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
10
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
19
La classe ImageFrame (1)
import javax.swing.*;import java.awt.*;import java.awt.event.*;public class ImageFrame extends JFrame{
public ImageFrame () {setTitle ("Eccomi...");setSize (800,700);ImagePanel p = new ImagePanel();Container c = getContentPane();c.add(p);
}}class ImagePanel extends JPanel{
//…. continua
• Import – per extends
• Costruttore:– setta il titolo e la size– crea un Panel
• uso classe interna allo stesso file (privata)
– preleva il ContentPane del JFrame
– aggiunge il pannello p
ImageFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
20
La classe ImageFrame (2)
// … continuaclass ImagePanel extends JPanel{
public ImagePanel () {image = Toolkit.getDefaultToolkit().
getImage("foto.gif");}public void paintComponent (Graphics g) {
super.paintComponent(g);g.drawImage ( image, 75,100, null);
}private Image image;}
• Variabile istanza di ImagePanel– per la immagine
• Costruttore:– carica la foto.gif
• L’override di paintComponent– traccia la immagine
ImageFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
11
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
21
La classe ImageTest
import javax.swing.*;import java.awt.*;public class ImageTest {
public static void main ( String[] args) {ImageFrame f = new ImageFrame();f.setDefaultCloseOperation (
JFrame.EXIT_ON_CLOSE);f.show();
}}
• Semplice programma di test
• Crea un frame• Setta alcune
caratteristiche– termina il programma
quando il frame viene chiuso
• Mostra il frame
ImageTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
22
Il problema del caricamento
• Il caricamento della immagine viene effettuato mediante un thread– eseguito in maniera asincrona:
• il programma continua mentre viene caricata l’immagine
– questo per immagini grandi oppure immagini che vanno caricate da rete non è corretto
• Si deve fare in modo di fare “aspettare” nel costruttore di ImagePanel l’effettivo caricamento
• Ecco come si fa:
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
12
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
23
La classe (modificata) ImagePanel
// …resto del file (classe ImageFrame) identicoclass ImagePanel extends JPanel{
public ImagePanel () {image = Toolkit.getDefaultToolkit().
getImage("foto.gif");MediaTracker t = new
MediaTracker(this);t.addImage(image,1); // id immaginetry {t.waitForID(1); }catch (InterruptedException e) {}
}public void paintComponent (Graphics g) {
super.paintComponent(g);g.drawImage ( image, 75,100, null);
}private Image image;}
• Si definisce un oggetto che traccia il caricamento della immagine
• Si aggiunge l’immagine• Si aspetta il caricamento
effettuato della immagine con ID 1
ImageFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
24
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
13
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
25
La interazione in un ambiente grafico
• Un ambiente grafico deve garantire la interazione con gli utenti– rispondere ai click dell’utente in maniera “sensata”
• un click può:– essere ignorato
– selezionare una voce da un menù
– attivare un bottone
– iniziare una azione di drag and drop
– rispondere alla pressione di tasti della tastiera• scrivere testo “da qualche parte” sullo schermo
• Il sistema operativo monitora l’ambiente e segnala gli eventi ricevuti al programma in esecuzione
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
26
Due approcci estremi
• L’approccio alla VisualBasic– ogni elemento della interfaccia grafica ha una lista di eventi
fissati• un pulsante HelpButton ha la azione HelpButton_Click
• basta scrivere una procedura con questo nome per farne eseguire il codice in risposta ad una azione dell’utente
• L’approccio alla C– necessario scrivere il codice che costantemente controlla una
“coda di eventi” per trattarla (mega-switch)
– possibile creare nuovi eventi
– estremamente complessa
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
14
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
27
L’approccio di Java: un compromesso
• Il programmatore ha il controllo:– delle modalità di trasmissione degli eventi
• dalle sorgenti (bottoni, barre di scorrimento, etc.)
• ai rilevatori (listener)
• Il Modello di delega degli eventi– permette di mantenere il pieno controllo e la estendibilità del
codice
– al prezzo di scrivere (e debuggare) un pochino in più di codice (rispetto, ad esempio, al Visual Basic)
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
28
Gli oggetti evento
• In un linguaggio OO come Java, è ovvio che gli eventi siano incapsulati in un oggetto java.util.EventObject
– con le sue sottoclassi ActionEvent e WindowEvent
• Il funzionamento:– (1) un listener è una istanza di una classe che implementi la
interface Listener
– (2) una sorgente di eventi può registrare oggetti listener
– (3) quando si verificano eventi allora la sorgente invia ai listener registrati gli oggetti Event
– (4) i listener usano le informazioni nell’oggetto Event per determinare la loro reazione
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
15
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
29
Uno schema di funzionamento
• (1) Il Listener
• (2) La registrazione del listener sulla sorgente:
• (3) Ogni volta si verifica un evento, allora l’oggetto butt avvisa il listener lis inviando come parametro l’Event
• (4) l’oggetto lis allora esegue il metodo actionPerformed()
class MyListener implements ActionListener {….public void actionPerformed (ActionEvent ev) {
// la reazione all’evento}
}
ActionListener lis = new MyListener( );JButton butt = new JButton (“Ok”);butt.addActionListener(lis);
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
30
Un programma di esempio
• Un frame con 3 bottoni:– alla pressione di uno di questi bottoni, il colore di sfondo
cambia a seconda del bottone premuto
• La struttura delle classi:– nello stesso file: Buttonframe.java
• una classe ButtonPanel che contiene i bottoni
• una classe ButtonFrame che contiene ButtonPanel
• una classe ColorAction che fa il Listener dei bottoni
– una classe ButtonTest per il semplice uso di ButtonFrame
• Attenzione: esempio lievemente diverso da quello sul libro:• classe ButtonTest in un file separato
• non si usano le classi “interne” (classi definite all’interno di altre classi)
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
16
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
31
La classe ButtonTest
import java.awt.*;import javax.swing.*;
public class ButtonTest{
public static void main(String[] args){
ButtonFrame frame = new ButtonFrame();frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);frame.show();
}}
• Import – per usare JFrame
• Metodo main– crea un frame
ButtonFrame– ne setta alcune
caratteristiche• termina il programma
quando il frame viene chiuso
– mostra il frame
ButtonTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
32
La classe ButtonFrame (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;class ButtonFrame extends JFrame{
public ButtonFrame(){
setTitle("ButtonTest");setSize(300, 200);
ButtonPanel panel = new ButtonPanel();Container contentPane = getContentPane();contentPane.add(panel);
}
} // fine della classe ButtonFrame// … continua con le classi ButtonPanel // … e ColorAction
• Import • Costruttore:
– set del titolo – set della dimensione
• Creazione di un ButtonPanel …
• … e aggiunta del ButtonPanel al Frame
ButtonFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
17
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
33
La classe ButtonFrame (2)
//… continuaclass ButtonPanel extends JPanel {
public ButtonPanel() {JButton yButton = new JButton(“Giallo");JButton bButton = new JButton("Blu");JButton rButton = new JButton("Rosso");add(yButton); add(bButton);add(rButton);ColorAction yAction = new ColorAction(
Color.yellow,this);ColorAction bAction = new ColorAction(
Color.blue, this);ColorAction rAction = new ColorAction(
Color.red, this);yButton.addActionListener(yAction);bButton.addActionListener(bAction);rButton.addActionListener(rAction);
}} // fine ButtonPanel… continua
• Crea 3 bottoni con etichetta
• Aggiungi (add di JPanel) i tre bottoni al pannello
• Crea 3 listener – ad ognuno passa il
colore e una reference al Panel
• Aggiungi un Listener a ciascun bottone
ButtonFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
34
La classe ButtonFrame (3)
class ColorAction implements ActionListener{
public ColorAction(Color c, JPanel p){
backgroundColor = c;pann = p;
}
public void actionPerformed(ActionEvent event)
{pann.setBackground(backgroundColor);pann.repaint();
}
private Color backgroundColor;private JPanel pann;
}
• Implementa la interface ActionListener
• Costruttore– 2 parametri
• il colore da settare• il pannello di cui
cambiare il colore
• Il metodo per la esecuzione della azione– set background– forza il repaint del
pannello• Variabili di istanza
ButtonFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
18
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
35
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
36
Modifica del look-and-feel
• La ambientazione grafica (look-and-feel) permette di offrire un ambiente grafico familiare all’utente
• Sono disponibili:– Metal (specifico di Swing)
– Windows (disponibile solo su Windows)
– Mac (disponibile solo su Mac)
– Motif (X)
• Interessante:– è possibile far cambiare a run-time la ambientazione
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
19
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
37
La classe PlafTest
import java.awt.*;import java.awt.event.*;import javax.swing.*;
public class PlafTest{
public static void main(String[] args){
PlafFrame frame = new PlafFrame();frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);frame.show();
}}
• Standard applicazione di esempio…
PlafTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
38
La classe PlafFrame (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;
class PlafFrame extends JFrame{
public PlafFrame() {setTitle("PlafTest");setSize(300, 200);PlafPanel panel = new PlafPanel();Container contentPane = getContentPane();contentPane.add(panel);
}}// fine della classe PlafFrame// … continua con le classi PlafPanel // … e LookAction
• Import • Costruttore:
– set del titolo – set della dimensione
• Creazione di un PlafPanel …
• … e aggiunta del PlafPanel al Frame
PlafFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
20
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
39
La classe PlafFrame (2)
class PlafPanel extends JPanel {public PlafPanel() {makeButton("Metal",
"javax.swing.plaf.metal.MetalLookAndFeel");makeButton("Motif",
"com.sun.java.swing.plaf.motif.MotifLookAndFeel");makeButton("Windows","com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
void makeButton(String name, String plafName) {JButton button = new JButton(name);add(button);LookAction l = new LookAction(this, plafName);button.addActionListener(l);}
}// fine della classe PlafPanel .. continua …
• Usa un metodo per creare un bottone e registrare un listener
• Argomenti– label bottone– stringa della classe da usare
per cambiare look
• makeButton()– crea bottone e aggiunge al
pannello– crea listener e lo aggiunge
PlafFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
40
La classe PlafFrame (3)
class LookAction implements ActionListener {
public LookAction(JPanel p, String s) {pann = p;look = s;
}public void actionPerformed(ActionEvent event) {
try {UIManager.setLookAndFeel(look);SwingUtilities.updateComponentTreeUI
(pann);}catch(Exception e) { e.printStackTrace(); }
}JPanel pann;String look;
}
• Costruttore– setta le variabili di istanza:
• pannello su cui cambiare look-and-feel
• nome del Look da cambiare
• Metodo per la azione– usa metodi statici
• per cambiare il Look-and-feel• per aggiornare tutte le
componenti correnti del pannello
– necessario un try..catch
• Variabili di istanza
PlafFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
21
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
41
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
42
Eventi della finestra
• Quando la finestra è soggetta a qualche operazione da parte dell’utente, diventa sorgente di un WindowEvent
• La interfaccia messa a disposizione per implementare dei listener è WindowListener:
public interface WindowListener() {void windowOpened(WindowEvent e);void windowClosing(WindowEvent e);void windowClosed(WindowEvent e);void windowIconified(WindowEvent e);void windowDeiconified(WindowEvent e);void windowActivated(WindowEvent e);void windowDeactivated(WindowEvent e);
}
• Un problema:
• implementare tutti i metodi anche se sono vuoti
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
22
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
43
Un semplice “trucchetto”: l’ adapter
• Per evitare la implementazione di metodi vuoti:
– esiste una classe di nome WindowAdapter che implementa tutti i metodi vuoti
– e basta estendere questa classe (extends non implements)• facendo override dei soli metodi da definire non vuoti!
..void windowOpened(WindowEvent e) { }
..
class Terminator extends WindowAdapter {void windowClosed(WindowEvent e) {
System.exit(0);}
}
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
44
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
23
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
45
Elementi di una componente di interfaccia
• Componenti di interfaccia utente:– bottoni, campo di testo, menù etc.
• Tre elementi costitutivi:– il contenuto
• lo stato di un pulsante, il testo di un campo di testo, etc.
– l’aspetto visivo• colori, dimensioni, font, etc.
– il comportamento• reazione agli eventi utente e di altri oggetti
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
46
Schema model-view-controller
• Lo schema modello-vista-controllerè usato da Swing
• Principio guida (della programmazione OO):– ogni oggetto deve avere un numero limitato di responsabilità
(compiti da assolvere)
• Questo schema permette, in generale, di separare all’interno della componente grafica – gli aspetti dei dati contenuti,
– la rappresentazione grafica
– e la loro interazione con l’ambiente circostante
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
24
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
47
Lo schema model-view-controller
• Ogni componente grafica viene implementata da tre classi:– un modello
• che serve a memorizzare il contenuto– per una casella di testo, memorizza la stringa
– una vista• che serve a visualizzare il contenuto
– per un casella di testo, contiene font, dimensioni, posizione etc.
– un controller• che permette la interazione con l’utente
– per una casella di testo, permette la modifica, cancellazione del contenuto, etc.
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
48
Alcuni vantaggi dello schema
• Memorizzazione dei dati (modello) diversa dalla presentazione (vista)– lo stesso file HTML può essere presentato come “preview”
(come appare sul browser) oppure come file di testo ASCII (con tutti i tag)
• Il controller controlla l’input– e decide se informare il modello (cambia il contenuto)
oppure la vista (è cambiata la presentazione)
– l’altra componente ignora le informazioni inviate alla componente che deve essere informata
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
25
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
49
Swing e lo schema progettuale
• Normalmente i programmatori ignorano questo schema:– interagiscono con una classewrapper(tipo JButton)
– le modifiche a JButton vengono da questa inoltrata alla componente modello, vistaoppure controller
• Si può comunque recuperare il modello da una classewrapper
• Permette di creare ambienti innestabili– riutilizzare componenti cambiandone solamente la vista
– a volte possibile arun-time!
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
50
Un esempio: la classeJButton (1)
• Di norma, per ogni componente grafica esiste – una classe modello che implementa una interfaccia
– perJButton esiste una interfacciaButtonModel che viene implementata da una classeDefaultButtonModel
• I metodi diButtonModel – getActionCommand()
• stringa di comando della azione associate al bottone
– getMnemonic()• scorciatoia da tastiera
– isArmed(),is Enabled(), is Pressed(), is Rollover(), isSelected()• se il bottone è stato premuto/abilitato/premuto (mouse è ancora lì)/ mouse è sul
pulsante/selezionato (pulsante di scelta)
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
26
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
51
Un esempio: la classeJButton (2)
• E’ possibile recuperare l’oggetto modello della componente:
• Ogni componente usa un oggetto vista la cui classe ha un nome che termina con UI (User Interface)– perJButton esiste una classeBasicButtonUI
• Alcune componenti usano un oggetto controllerdedicato, la cui classe ha nome che termina conUIListener– perJButton esiste una classeButtonUIListener
JButton butt = new JButton (“Giallo”);ButtonModel model = button.getModel();
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
52
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
27
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
53
Gestori del layout
• Si occupano di implementare una politica di gestione del posizionamento dei componenti sulla finestra
• Disponibili una varia gamma di classi – disponibili da Sun
– ma anche da altri produttori di software
• Nell’esempio di ButtonFrame:– i pulsanti si trovavano al centro della finestra
– e mantenevano la posizione centrale al ridimensionamento della finestra
– usa il BorderLayout (di default posiziona al centro)
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
54
La classe ButtonFrameBorder (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;class ButtonFrame extends JFrame{
public ButtonFrame(){
setTitle("ButtonTest");setSize(300, 200);
ButtonPanel panel = new ButtonPanel();Container contentPane = getContentPane();contentPane.add(panel);
}
} // fine della classe ButtonFrame// … continua con le classi ButtonPanel// … e ColorAction
• Import • Costruttore:
– set del titolo – set della dimensione
• Creazione di unButtonPanel …
• … e aggiunta delButtonPanel al Frame
ButtonFrameBorder.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
28
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
55
La classe ButtonFrame (2) con il FlowLayout
//… continuaclass ButtonPanel extends JPanel {
public ButtonPanel() {setLayout (new
FlowLayout(FlowLayout.RIGHT));JButton yButton = new JButton(“Giallo");JButton bButton = new JButton("Blu");JButton rButton = new JButton("Rosso");add(yButton);add(bButton);add(rButton);ColorAction yAction = new ColorAction(
Color.yellow,this);ColorAction bAction = new ColorAction(
Color.blue, this);ColorAction rAction = new ColorAction(
Color.red, this);……
• Seleziona come gestore del Layout un oggetto FlowLayout– che viene creato
passando una costante definita nella classe
– che posizione a destra i pulsanti
– altra scelta LEFT e CENTER
ButtonFrameBorder.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
56
Un altro Layout Manager : BorderLayout
• Permette di definire con più precisione la posizione
• Divide la finestra in:
• Ridimensiona i componenti in modo che riempiano tutto lo spazio disponibile– di default su JFrame (inserimento al centro)
North
West Center East
South
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
29
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
57
Cosa accade se usiamo BorderLayout()?
• Si usa BorderLayout()
• Posizioniamo:– il Giallo a nord
– il blu a est
– il rosso a sud
• Cosa accade?
//… continuaclass ButtonPanel extends JPanel {
public ButtonPanel() {setLayout (new BorderLayout());JButton yButton = new JButton(“Giallo");JButton bButton = new JButton("Blu");JButton rButton = new JButton("Rosso");add(yButton, BorderLayout.NORTH); add(bButton, BorderLayout.EAST);add(rButton, BorderLayout.SOUTH);
……
ButtonFrameBorder.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
58
E se mettiamo tutti e tre i pulsanti a Sud?
• Si usa BorderLayout()
• Posizioniamo:– tutti i pulsanti a sud
• Cosa accade?
//… continuaclass ButtonPanel extends JPanel {
public ButtonPanel() {setLayout (new BorderLayout());JButton yButton = new JButton(“Giallo");JButton bButton = new JButton("Blu");JButton rButton = new JButton("Rosso");add(yButton, BorderLayout.SOUTH); add(bButton, BorderLayout.SOUTH);add(rButton, BorderLayout.SOUTH);
……
• Solo un componente può essere inserito a sud:
• l’ultimo sostituisce il precedente
• Come si fa?
ButtonFrameBorder.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
30
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
59
La soluzione: un Panel che contiene i pulsanti
//… continuaclass ButtonPanel extends JPanel{
public ButtonPanel(){
setLayout (new BorderLayout());JButton yellowButton = new JButton("Giallo");JButton blueButton = new JButton("Blu");JButton redButton = new JButton("Rosso");
JPanel cont = new JPanel();cont.add(yellowButton);cont.add(blueButton);cont.add(redButton);
add(cont, BorderLayout.SOUTH);….
• Seleziona come gestore del Layout un oggetto BorderLayout
• Crea 3 bottoni• Crea un Pannello
– al quale aggiunge i tre pulsanti
– con il gestore di layout standard (BorderLayout)
• Poi aggiunge il pannello a sud
ButtonFrameBorder.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
60
Organizzazione della lezione
• La programmazione grafica con Swing e AWT
• Un primo approccio con Swing: frame e pannelli
• Gli eventi dell’ambiente grafico– i listener (rilevatori di evento)
– modifica del Look-and-feel
– adapter a interfacce
• Lo schema di progettazione di Swing
• I gestori di layout
• Campi di testo
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
31
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
61
Componenti per input di testo
• Due componenti:– JTextField per l’input di un rigo di testo
– JTextArea per l’input di una area di testo (più righi)
• Entrambe derivano dalla classe astratta JTextComponent
– che contiene la maggior parte dei metodi tra cui:• void setText (String t)
– modifica il testo della componente
• String getText()– restituisce il testo della componente
• void setEditable (boolean b)– può essere modificata oppure no
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
62
Listener per campi di testo
• Implementa la interfaccia DocumentListener con i metodi:– void insertUpdate (DocumentEvent e) { }– void removeUpdate (DocumentEvent e) { }– void changedUpdate (DocumentEvent e) { }
• Sfortunamente nessuna classe adapter è disponibile:– si devono esplicitamente implementare i 3 metodi anche se
servono vuoti
• Per aggiungere un listener ad un campo si usa:JTextField nome = new JTextField(30);TextListener lis = new TextListener();nome.getDocument().addDocumentListener(lis);
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
32
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
63
Un esempio di uso
• Una finestra che contenga due campi di testo:– in uno scriviamo il nome– nell’altro (non editabile) compare “Ciao…”
• Necessario (a parte la classe TextTest)– una classe TextFrame che
• crea due oggetti JTextField
• setta il listener di uno dei due (quello di input) a TextListener a cui passa le reference dei due campi
• setta l’altro JTextField a non editabile
– una classe TextListener• nel costruttore prende due variabili di reference JTextField
• quando il testo sul primo campo cambia, scrive la stringa sul secondo
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
64
La classe TextTest
import java.awt.*;import javax.swing.*;
public class TextTest{
public static void main(String[] args){
TextFrame frame = new TextFrame();frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);frame.show();
}}
• Import – per usare JFrame
• Metodo main– crea un frame
TextFrame– ne setta alcune
caratteristiche• termina il programma
quando il frame viene chiuso
– mostra il frame
TextTest.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
33
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
65
La classe TextFrame (1)
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;class TextFrame extends JFrame {
public TextFrame() {setTitle("Test sul Testo");setSize(300, 200);Container contentPane = getContentPane();JPanel pan = new JPanel ();JTextField nome = new JTextField(30);JTextField saluto = new JTextField(40);saluto.setEditable (false);TextListener lis = new TextListener(
nome,saluto);nome.getDocument().addDocumentListener(
lis);// … continua la classe TextFrame
• Import • Costruttore: (continua)• Creazione di unJPanel
• Creazione di due JTextField– il secondo non editabile
• Aggiunta del listener a nome
– passando nome esaluto
TextFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
66
La classe TextFrame (2)
//…// continua il costruttore di TextFrame
contentPane.add(nome, BorderLayout.NORTH);
contentPane.add(saluto, BorderLayout.SOUTH);
}}
// fine classe TextFrame// continua con la classe TextListener
• Aggiunge i due campi di testo al Container– uno a nord– l’altro a sud
• Attenzione:– il layout manager di
default di JFrame è BorderLayout
TextFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
34
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
67
La classe TextFrame (3)
class TextListener implements DocumentListener {
public TextListener (JTextField n,JTextField s) {nome = n;saluto = s;
}public void insertUpdate(DocumentEvent e) {saluto.setText("Ciao " + nome.getText());}
public void removeUpdate(DocumentEvent e) {saluto.setText("Ciao " + nome.getText());}
public void changedUpdate(DocumentEvent e) {saluto.setText("Ciao " + nome.getText());}JTextField nome;JTextField saluto;
}
• Implementa DocumentListener
• Costruttore– assegna i due campi di
testo passati
• Tre metodi per gli eventi di cui è “in ascolto”– settano il testo di saluto
a seconda del contenuto di nome
TextFrame.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
68
Un esempio “reale”: conversione lire/euro
• Due campi di testo:– uno (editabile) in cui si inseriscono il valore in lire
– uno (non editabile) in cui viene scritto il corrispettivo in euro
• Struttura simile al programma precedente:– Calculator (che istanzia CalculatorFrame)
– CalculatorFrame (che istanzia i campi di testo ed usa TextListener per le modifiche al campo)
– TextListener (che implementa i metodi per le modifiche al valore in lire e il calcolo del valore in euro)
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
35
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
69
La classe Calculator
import java.awt.*;import javax.swing.*;
public class Calculator{
public static void main(String[] args){
CalculatorFrame frame = new CalculatorFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();}
}
• Import – per usare JFrame
• Metodo main– crea un frame
CalculatorFrame– ne setta alcune
caratteristiche• termina il programma
quando il frame viene chiuso
– mostra il frame
Calculator.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
70
La classe CalculatorFrame
// soliti import!! :-)class CalculatorFrame extends JFrame {
public CalculatorFrame() {setTitle("Euroconvertitore");setSize(100, 100);
Container contentPane = getContentPane();JPanel pan = new JPanel ();JTextField v = new JTextField(10);JTextField r=new JTextField(10);r.setEditable (false);TextListener lis = new TextListener(v,r);v.getDocument().addDocumentListener(lis);
contentPane.add(v, BorderLayout.NORTH);contentPane.add(r, BorderLayout.SOUTH);
}}
• Import • Costruttore: • Creazione di unJPanel
• Creazione di due JTextField– il secondo non editabile
• Aggiunta del listener a v
– passando v e r
CalculatorFrame.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
36
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
71
La classe TextListener (1)
import java.util.*;import java.text.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;
class TextListener implements DocumentListener {
public TextListener (JTextField v, JTextField r) {
valuta = v;risultato = r;}
// continua
• Import• Implementa
DocumentListener• Costruttore
– assegna i due campi passati alle due variabili di istanza (definite nel seguito)
TextListener.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
72
La classe TextListener (2)
// continua…public void insertUpdate(DocumentEvent e) {
int lire;try {
lire = Integer.parseInt(valuta.getText());} catch (NumberFormatException g)
{lire = -1;} double euro = lire / 1936.27;if (lire >= 0) {
NumberFormat fmt = NumberFormat.getNumberInstance();
fmt.setMaximumFractionDigits(2);risultato.setText(fmt.format(euro));
} elserisultato.setText(ERRORE);
}// identici removeUpdate e changedUpdate// continua
• Prova a convertire la stringa in un intero
• altrimenti lire è negativo
• Converte in euro• Se il valore in lire era
valido:– converte arrotondando alla
seconda cifra decimale
• altrimenti stampa una stringa di errore
TextListener.java
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
37
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
73
La classe TextListener (3)
// continua…JTextField valuta;JTextField risultato;final String ERRORE = "Valore errato";
}// fine classe TextListener
• Variabili di istanza per contenere i riferimenti per i due campi di testo
• La stringa di errore (costante)
TextListener.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
74
Cosa altro può fare Swing per me? (1)
Dialog Frame Panel ScrollPane
SplitPane TabbedPane Toolbar
InternalFrame
LayeredPane Buttons
ASD: Sistemi Distribuiti (Prof. Scarano) 11/06/2002
38
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
75
Cosa altro può fare Swing per me? (2)
Combo BoxList Menu Slider
Text Fields
Label
Progress BarTool tip
Color Chooser
Text
Table
File Chooser
Tree