Swing e la programmazione a eventi

Swing e la programmazione a eventi
Lo stile basato su eventi


I componenti interagiscono attraverso l’invio di messaggi broadcast
o multicast

“Attenzione! C’è un incendio”

“Si avvisano i signori passeggeri che …”
Ogni componente notifica un cambiamento nel proprio stato o in
quello dell’ambiente inviando un messaggio


Tutti i componenti interessati all’evento descritto da tale messaggio
ne ricevono copia


In tal caso agisce da “generatore dell’evento”
In tal caso agiscono da “ascoltatori dell’evento”
In generale, il generatore dell’evento non conosce né il numero né
l’identità degli ascoltatori
2
Caratteristiche generali

Con il paradigma a eventi

L’applicazione è puramente “reattiva”

Non è possibile identificare staticamente un flusso di controllo unitario

Il programma principale si limita a inizializzare l’applicazione, istanziando
gli osservatori e associandovi gli opportuni handler
Occorrenza
dell’evento A
Occorrenza
dell’evento B
Realtà
Applicazione
Osservatori
Notifica
dell’evento A
Ascoltatore
evento A
Notifica dell’evento B
Ascoltatore
evento A
Ascoltatore
evento B
listeners
3
Vantaggi

Utili per sistemi altamente dinamici ed evolutivi, in cui nuovi moduli
si possono aggiungere o possono essere eliminati

Per comunicare tra di loro, i moduli non devono conoscere le
rispettive identità

come invece accade in Java


nomeModulo.nomeServizio (parametri)
Si parla più in generale di paradigma di progettazione "publish and
subscribe"

moduli che generano eventi ("publish")

moduli che sottoscrivono l'interesse ad essere notificati dell'occorrenza
di certi eventi ("subscribe")
4
In pratica
subscribe y
x
Gestore degli eventi
y
subscribe z
subscribe x
5
Modello a eventi in Java

Un’applicazione può essere costruita come componenti che
interagiscono attraverso eventi

Utilizzando le convenzioni dei JavaBean

Qui noi vediamo il package javax.swing

libreria che fornisce le classi che consentono la progettazione delle
interfacce utente secondo lo stile ad eventi
6
Swing
GUI

GUI: Graphical User Interface

L'interfaccia utente costituisce il mezzo con il quale l'utente
interagisce con l'applicazione

costituisce il "look&feel"

Fondamentale per l'usabilità del software

Come si progetta?
8
Progettazione

Separare GUI e parte funzionale

La GUI si preoccupa di interagire con l'utente

visualizzare

accettare input

La parte funzionale contiene la logica applicativa

Vantaggi

GUI modificabile senza toccare la parte funzionale e viceversa

Diverse strategie "look&feel" per la stessa applicazione

Spesso le modifiche si incentrano sulla GUI al fine di migliorare l'usabilità
9
Model-View-Controller


Swing si basa su un “paradigma” di progettazione che si incontra
anche in altri campi:

Un componente ha un suo “modello logico”

Un componente ha un suo “aspetto visuale”

Un componente ha “comportamenti” che consentono la sua interazione
con il resto dell’applicazione
Esempio -> JButton

Model: Premuto/Rilasciato (variabile booleana)

View: dipende dal look&feel

Controller: ActionPerformed della classe ActionListner collegata al
JButton (ci torneremo)
10
AWT e Swing

Abstract Windowing Toolkit (AWT)


Sono un residuo di precedenti versioni di JAVA fornisce ancora alcune importanti
componenti al funzionamento e creazione di elementi di interfaccia
Swing



Consentono di realizzare applicazioni con un “look and feel” più aggiornato e
elegante
Si basano su un modello di interazione introdotto da JAVA2
Hanno superato alcuni dei difetti di AWT



Chiedono servizi al sistema operativo, ma (normalmente) ad un livello più basso e
riescono così ad avere un maggiore controllo del “look&feel”
Sono una “estensione” del core di JAVA e possono risultare più complesse da
programmare
Consentono un maggior controllo del look&feel di un’applicazione e garantiscono il
medesimo look&feel su tutte le piattaforme
11
AWT e Swing

Il nome di tutti i componenti Swing inizia con J


I componenti Swing sono lightweight


La convenzione è JXxxx
Vengono creati disegnandoli nella finestra sottostante
È bene non includere componenti Swing ed AWT in una stessa
interfaccia:

I componenti AWT (heavyweight) vengono sempre mostrati “sopra” i
componenti Swing (ad esempio con i Menu)

Problema dovuto alla mancanza di compatibilità fra i due framework
12
Un’interfaccia Swing

Tre elementi fondamentali

Contenitori

Elementi grafici

Eventi
13
Frame

Un frame

Definisce l’intelaiatura dell’interfaccia

Fornisce un rettangolo, “decorato” alla maniera delle finestre cui siamo
abituati

E’ un oggetto COMPLESSO!
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
14
JFrame


Come in tutta la programmazione ad
oggetti occorre conoscere la “gerarchia”
entro la quale si colloca JFrame
Per conoscere la “derivazione” di ogni
oggetto delle librerie GUI di Swing si deve
fare ricorso alla documentazione in linea
di Java

java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
http://java.sun.com/j2se/1.5/docs/api/
java.awt.Frame
javax.swing.JFrame
15
JFrame
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
16
Scorrendo la gerarchia


Component

“A component is an object having a graphical representation that can be
displayed on the screen and that can interact with the user. Examples of
components are the buttons, checkboxes, and scrollbars of a typical
graphical user interface”

Component è quindi una classe molto generale e definisce un sacco di
metodi
Container

Un Component con la proprietà di essere abilitato a contenere altri
Component


Prevede metodi di tipo “add” per aggiungere componenti
Prevede anche metodi per rappresentare il contenitore e i suoi contenuti
e per aggiornarne l’immagine
17
Scorrendo la gerarchia


Window

È un particolare contenitore che può apparire sullo schermo come entità propria,
ma non ha bordi, barre e controlli

Possiede metodi per mostrare la finestra, nascondere la finestra, posizionare la
finestra e aggiustare l’ordine di comparizione relativamente ad altre finestre
Frame


Si tratta di Window con bordi e barra del titolo, oltre alle caratteristiche solite di
un’interfaccia (minimizzazione, iconizzazione, chiusura, resizing)
JFrame

È un Frame AWT a cui SWING aggiunge una serie di metodi per ridefinire i
dettagli grafici. Ad esempio

l metodo setSize(int l, int h) permette di determinare le dimensioni del Frame

Il metodo setLocation(int x, int y) consente di definire le coordinate del pixel in alto
a sinistra del frame nel riferimento dello schermo
18
Cosa possiamo fare con un JFrame?

Non possiamo disegnare, scrivere o aggiungere elementi
direttamente al Frame

Gli elementi diversi dal Menu debbono essere “aggiunti” ad un
Container opportuno

Ad esempio

Per scrivere del testo dentro un Frame, il testo dovrà essere scritto
(aggiunto) al pannello contentPane del JFrame

Per convenienza il metodo add() di JFrame si occupa di tutto il lavoro
frame.getContentPane().add(label) = frame.add(label)
19
HelloWorldSwing
import javax.swing.*;
public class HelloWorldSwing {
private static void createAndShowGUI() {
JFrame frame = new JFrame("HelloWorldSwing");
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
createAndShowGUI();
}
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
20
HelloWorldSwing (seconda versione)
import javax.swing.*;
public class HelloWorldSwing {
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("HelloWorldSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
createAndShowGUI();
}
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
21
Look&feel
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
22
Look&feel nativo
public class WindowUtilities {
public static void setNativeLookAndFeel() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
System.out.println(“Problema Look and feel nativo” + e);
}
}
23
Aggiungiamo componenti

Dobbiamo sapere:

Da dove prendere i componenti?


Come costruirli e personalizzarli?


Costruttori e modificatori
Come usarli?


Una lista/descrizione delle librerie disponibili
Quali eventi sono in grado di raccogliere e quali i listener necessari
Come disporli sui frame che costituiscono la nostra applicazione?

Layout manager
24
Container

Top-level container
JApplet

JDialog
General-purpose containerJScrollPane
JPanel
JFrame
JSplitPane
JTabbedPane
25
Container

Special-purpose container
JInternalFrame
JLayeredPane
JToolBar
Permette di semplificare
l’attivazione di determinate
funzioni per mezzo di semplici
pulsanti
Permette di inserire frame dentro
altri frame
Permette di inserire
componenti a vari
livelli di profondità
26
Controlli di base
JButtons
Include buttons,
radioButtons, checkbox,
MenuItem, ToggleButton
JComboBox
JSlider
JList
JMenu
JTextField
Include
JPasswordField,
JTextArea
27
Visualizzatori di informazioni non editabili
JLabel
JProgressBar
Jcomponent.setToolTipText(String)
Può includere
immagini e/o testo
28
Visualizzatori di informazioni formattate editabili
JColorChooser
JFileChooser
JTable
JTextComponent
JTree
JTextField,
JPasswordField,
JTextArea, JEditorPane,
JTextPane
29
Altri componenti grafici

Label

Button

CheckBoxButton

ScrollBar

PullDownMenu

PopupMenu

…
30
Layout

Java gestisce la disposizione dei componenti dentro i Container
mediante oggetti che si chiamano LayoutManager




È un’interfaccia che descrive come un componente deve
comunicare con il suo LayoutManager
Esiste un’ampia collezione di LayoutManager, ma se si vuole si può
creare il proprio


Incapsulano gli algoritmi per il posizionamento delle componenti di una
GUI
Il LayoutManager mantiene l’algoritmo separato in una classe a parte
Noi vediamo solo i LayoutManager più comuni: FlowLayout,
BorderLayout, GridLayout, CardLayout e GridBagLayout
L’associazione avviene tramite il metodo setLayout() di cui è
provvista la classe Container (e quindi tutte le sue sottoclassi)

p.setLayout(new BorderLayout());
31
FlowLayout

E’ il più semplice. La sua strategia
è:



Rispettare la dimensione di tutti i
componenti
private static void createAndShowGUI() {
JFrame frame = new JFrame("Flow");
Disporre i componenti in
orizzontale finché non viene
riempita tutta una riga, altrimenti
iniziare su una nuova riga
frame.setLayout(new FlowLayout());
Se non c’è spazio i componenti
non vengono visualizzati
frame.add(new JButton("Button3"));
frame.add(new JButton("Button1"));
frame.add(new JButton("Button2"));
frame.add(new JButton("Button4"));
frame.add(new JButton("Button5"));
frame.pack();
frame.setVisible(true);
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
32
BorderLayout






Definisce 5 aree logiche: NORTH, SOUTH, CENTER, EAST e WEST
Richiede la dimensione preferita del componente (altezza e larghezza)
Se il componente è NORTH o SOUTH setta l’altezza al valore preferito e la
larghezza in modo da occupare tutto lo spazio orizzontale
Se il componente è EAST o WEST setta la larghezza al valore preferito e
l’altezza in modo da occupare tutto lo spazio verticale restante
Se il componente è CENTER setta l’altezza e la larghezza in modo da
occupare tutto lo spazio centrale restante
Quindi



Le posizioni NORTH e SOUTH servono quando vogliare fissare l’altezza di un
componente al valore preferito
Le posizioni EAST e WEST servono quando vogliamo fissare la larghezza di un
componente al valore preferito
La parte CENTER è quella che si espande
33
Esempio
private static void createAndShowGUI() {
JFrame frame = new JFrame("Border");
frame.setLayout(new BorderLayout());
frame.add(new JButton("North"), BorderLayout.NORTH);
frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("Center"), BorderLayout.CENTER);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
34
GridLayout

Dispone i componenti su una griglia
private static void createAndShowGUI() {
JFrame frame = new JFrame("Grid");
frame.setLayout(new GridLayout(3,4));
for (int x=1; x<13; x++)
frame.add(new JButton(""+x));
frame.pack();
frame.setVisible(true);
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
}
35
Stratificazione
private static void createAndShowGUI() {
JFrame f = new JFrame(”Example");
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JPanel p4 = new JPanel();
f.setLayout(new BorderLayout());
p2.setLayout(new FlowLayout());
p4.setLayout(new BorderLayout());
p4.add(new JButton("Button1"), BorderLayout.EAST);
p4.add(new JButton("Button2"), BorderLayout.WEST);
p2.add(p3);
p2.add(p4);
f.add(p1, BorderLayout.NORTH);
f.add(p2, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
36
Eventi

L’interazione tra gli elementi dell’interfaccia e la logica applicativa è
gestita tramite eventi

Gli EventListener sono interfacce definite per catturare e processare
tipi di eventi particolari

Un listener deve

Essere associato al componente

Essere informato quando il componente genera un evento del tipo
richiesto

Rispondere facendo qualcosa di appropriato
37
EventHandler

Devono avere tre pezzi di codice


Dichiarazione

Estendono o implementano listener esistenti

public class MyClass implements ActionListener {
Associazione tra handler (ovvero listener) e istanza


someComponent.addActionListener(instanceOfMyClass);
Definizione del codice che implementa i metodi dell’interfaccia listener

public void actionPerformed(ActionEvent e) { ...
38
Un primo esempio
public class Demo extends JFrame implements ActionListener {
JButton b = new JButton("Click me!");
public Demo() {
b.addActionListener(this);
getContentPane().add(b);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
}
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
b.setBackground(Color.RED);
39
Eventi e Listener
Categoria
Evento
handler
Mouse
MouseEvent
MouseListener,
MouseMotionListener
Keyboard
KeyEvent
KeyListener
Selezione elem
ItemEvent
ItemListener
input di testo
TextEvent
TextListener
scrollbar
AdjustmentEvent
AdjustmentListener
bottoni, menu,...
ActionEvent
ActionListener
cambiamenti nella finestra
WindowEvent
WindowListener
focus
FocusEvent
FocusListener
40
Esempio completo (parte I)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CheckDemo {
static JFrame jframe = new JFrame("Example");
public static void setupjframe() {
jframe.setSize(400,100);
jframe.setVisible(true);
jframe.getContentPane().setLayout( new FlowLayout() );
WindowListener l = new MyWindowAdapter();
jframe.addWindowListener(l);
}
41
Esempio completo (parte II)
public static void main(String[] args) {
setupjframe();
JCheckBox jck1 = new JCheckBox("Pepperoni");
JCheckBox jck2 = new JCheckBox("Mushroom");
JCheckBox jck3 = new JCheckBox("Black olives");
JCheckBox jck4 = new JCheckBox("Tomato");
jck1.addActionListener(new MyActionListener());
jck2.addItemListener(new MyItemListener());
Container c = jframe.getContentPane();
c.add(jck1);
c.add(jck2);
c.add(jck3);
c.add(jck4);
jframe.pack();
}
}
42
Esempio completo (parte III)

ActionEvent
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e)
{ System.out.println("event = " + e); }
}

ItemEvent
public class MyItemListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange()==e.SELECTED)
System.out.print("selected ");
else System.out.print("de-selected ");
System.out.print("Mushroom\n");
}
}
43
Esempio completo (parte IV)

WindowEvent
public class MyWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {System.exit(0);}
}
44
Altro esempio
public class SwingApplication implements ActionListener {
private static String labelPrefix = "Number of button clicks: ";
private int numClicks = 0;
final JLabel label = new JLabel(labelPrefix + "0 ");
public Component createComponents() {
JButton button = new JButton("I'm a Swing button!");
button.setMnemonic(KeyEvent.VK_I);
button.addActionListener(this);
label.setLabelFor(button);
JPanel pane = new JPanel(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
10, //bottom
30) //right
);
return pane;
QuickTimeᆰ and a
TIFF (LZW) decompressor
are needed to see this picture.
45
Altro esempio
public void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("SwingApplication");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingApplication app = new SwingApplication();
Component contents = app.createComponents();
frame.getContentPane().add(contents, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
createAndShowGUI();
}
}
46
Link utili








http://java.sun.com/products/jfc/
http://java.sun.com/docs/books/tutorial/uiswing/
http://www.javaolympus.com/freebooks/FreeJavaSwingBooks.jsp
www.cs.uno.edu/~fred/nhText/ Resources/Slides/Chapter17.ppt
Building Graphical User Interfaces with Java
www.sce.carleton.ca/courses/ sysc-2004/w04/lectures/SYSC-200416a-Gui.ppt
Graphical User Interfaces with Java
www.csd.uwo.ca/courses/CS212a/notes/javagui.ppt
47