Tecniche di programmazione: eventi e componenti
Download
Report
Transcript Tecniche di programmazione: eventi e componenti
Swing e la programmazione a eventi
Prova Finale – Ingegneria del Software
Davide Mazza
[email protected]
http://home.dei.polimi.it/mazza
Lo stile basato su eventi
I componenti interagiscono attraverso l’invio di messaggi broadcast
o multicast
Ogni componente notifica un cambiamento nel proprio stato o in
quello dell’ambiente inviando un messaggio
In tal caso agisce da “generatore dell’evento”
Tutti i componenti interessati all’evento descritto da tale messaggio
ne ricevono copia
“Attenzione! C’è una nuova notizia di Politica”
“Sono interessato alle notizie di Sport”
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
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
UI e GUI
UI: User Interface
L'interfaccia utente costituisce il mezzo con il quale l'utente interagisce
con l'applicazione
GUI: Graphical User Interface
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
La parte funzionale può essere testata automaticamente senza
interagire con l’interfaccia grafica
Diverse strategie "look&feel" per la stessa applicazione
Spesso le modifiche si incentrano sulla GUI al fine di migliorare l'usabilità
9
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
Costruite sopra AWT
Consentono di realizzare applicazioni con un “look and feel” più aggiornato e
elegante
Più semplici da usare rispetto alle librerie AWT
Il nome di tutti le classi Swing inizia con J (Es. JButton, Jframe, ecc)
Per motivi di compatibilità è bene non includere componenti Swing ed AWT in
una stessa interfaccia
10
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: azioni associate agli eventi del pulsante
11
Un’interfaccia Swing
Tre elementi fondamentali
Contenitori
Elementi Interattivi e visuali
Finestre, Panelli
Pulsanti, Menù, Caselle di teso
Eventi
Pulsante premuto, Focus, resize
12
Components e Container
Tutti gli elementi che hanno una rappresentazioni grafica sono dei
Component
Sono sotto classi di java.awt.Component
Esempi: JLabel, JTextArea, JButton
Sia i contenitori che gli elementi interattivi sono Component
I contenitori sono implementati dalla classe java.awt.Container
Sotto classe di java.awt.Component
Esempi: JFrame, JPanel
13
Container
I Container possono contenere un insieme di Component
Dato che tutti i Container sono dei Component posso avere un
meccanismo a scatole cinesi
Un container può contenere altri Container
Esempio: una finestra contiene diversi pannelli, e i pannelli
contengono vari pulsanti
Non tutti i Component sono Container!
Container.add(Component c)
Container.add(Component c, parametri …)
I parametri specificano come il componente verrà posizionato nel
contenitore
14
Frame
Un frame
Definisce l’intelaiatura dell’interfaccia
Fornisce un rettangolo, “decorato” alla maniera delle finestre
cui siamo abituati
E’ un oggetto COMPLESSO!
Riceve Eventi come close, resize,
riduzione ad icona, ecc
15
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
http://java.sun.com/j2se/1.5/docs/api/
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
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
Frame
È 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
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?
Aggiungere un titolo usando il costruttore ereditato
Possiamo aggiungere componenti nel suo pannello principale:
frame.getContentPane().add(label)
frame.add(label)
Settare le dimensioni delle finestra
Associare un azione all’evento di chiusura della finestra
Mostrare la finestra all’utente
19
HelloWorldSwing
import javax.swing.*;
public class HelloWorld extends JFrame{
public HelloWorld (){
super("HelloWorld!");
setSize(200, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new JLabel("Hello World!"));
setVisible(true);
}
public static void main(String[] args) {
new HelloWorld();
}
}
20
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
21
Container
Top-level container
JApplet
JDialog
JFrame
General-purpose container
JPanel
JScrollPane
JSplitPane
JTabbedPane
22
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à
23
Controlli di base
JButtons
Include buttons,
radioButtons, checkbox,
MenuItem, ToggleButton
JComboBox
JSlider
JList
JMenu
JTextField
Include
JPasswordField,
JTextArea
24
Visualizzatori di informazioni non editabili
JLabel
JProgressBar
Jcomponent.setToolTipText(String)
Può includere
immagini e/o testo
25
Visualizzatori di informazioni formattate editabili
JColorChooser
JFileChooser
JTable
JTextComponent
JTree
JTextField,
JPasswordField,
JTextArea, JEditorPane,
JTextPane
26
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());
27
FlowLayout
E’ il più semplice. La sua strategia è:
Rispettare la dimensione di tutti i
componenti
Disporre i componenti in orizzontale
finché non viene riempita tutta una
riga, altrimenti iniziare su una nuova
riga
Se non c’è spazio i componenti non
vengono visualizzati
E’ possibile allineare i componenti a
sinistra, destra o al centro
E’ possibile specificare la distanza
verticale e orizzontale
public static void main(String[] args) {
JFrame frame = new JFrame("Flow");
frame.setLayout(new FlowLayout());
frame.add(new JButton("Button1"));
frame.add(new JButton("Button2"));
frame.add(new JButton("Button3"));
frame.add(new JButton("Button4"));
frame.add(new JButton("Button5"));
frame.pack();
frame.setVisible(true);
}
28
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
29
Esempio
public static void main(String[] args) {
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("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
}
30
GridLayout
Dispone i componenti su una griglia
public static void main(String[] args) {
JFrame frame = new JFrame("Grid");
frame.setLayout(new GridLayout(3,4));
for (int x=0; x<12; x++)
frame.add(new JButton(""+x));
frame.pack();
frame.setVisible(true);
}
31
Stratificazione
public static void main(String[] args) {
JPanel panel_flow=new JPanel(new FlowLayout(FlowLayout.CENTER,20,20));
panel_flow.setBorder(BorderFactory.createTitledBorder("Flow Layout"));
panel_flow.add(new JLabel("JLabel"));
panel_flow.add(new JTextField("JTextField"));
panel_flow.add(new JButton("JButton"));
JPanel panel_grid=new JPanel(new GridLayout(3,1));
panel_grid.setBorder(BorderFactory.createTitledBorder("Grid Layout"));
panel_grid.add(new JButton("JButton_1"));
panel_grid.add(new JButton("JButton_2"));
panel_grid.add(panel_flow);
JFrame f = new JFrame("Example");
f.add(panel_grid);
f.pack();
f.setVisible(true);
}
32
Layout di Default
Nel JPanel il layout di default è: FlowLayout
Nel JFrame il layout di default è: BorderLayout
33
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
34
EventHandler
Devono avere tre pezzi di codice
Dichiarazione
Associazione tra handler (ovvero listener) e istanza
Estendono o implementano listener esistenti
public class MyClass implements ActionListener {
someComponent.addActionListener(instanceOfMyClass);
Definizione del codice che implementa i metodi dell’interfaccia listener
public void actionPerformed(ActionEvent e) { ...
35
Un primo esempio
public class Demo extends JFrame implements ActionListener {
JButton button = new JButton("Click me!");
public Demo() {
button.addActionListener(this);
getContentPane().add(button);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
button.setBackground(Color.RED);
}
public static void main(String[] args) {
new Demo();
}
}
36
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
37
Swing e Thread
Nelle Swing, la gestione degli eventi e il ridisegno delle finestre e dei
componenti grafici è affidata ad un unico thread
Dispatching Thread
Perché un unico thread? Perché le Swing non sono thread safe!
L’accesso ad un oggetto da parte di più thread può causare
problemi!
Dispatching Thread:
Viene eseguito in background
Processa gli elementi presenti nella coda degli eventi grafici
Anche il ri-disegno dei componenti è un evento (paint)
38
Esempio Completo
public class Calcolatrice extends JFrame {
private JButton somma;
private JTextField num1;
private JTextField num2;
private JTextField tot;
public Calcolatrice(){
[…]
}
//Gestione Evento
[…]
public static void main(String[] args) {
new Calcolatrice();
}
}
39
Esempio Completo - Costruttore
public Calcolatrice(){
super("Semplice Calcolatrice");
setDefaultCloseOperation(EXIT_ON_CLOSE);
somma = new JButton("somma");
num1 = new JTextField("1",5);
num2 = new JTextField("1",5);
tot = new JTextField("0",5);
somma.addActionListener(new AzioneSomma());
setLayout(new FlowLayout());
add(num1);
add(num2);
add(somma);
add(tot);
pack();
setVisible(true);
}
40
Esempio Completo – Gestore dell’Evento
public class Calcolatrice extends JFrame {
private JButton somma;
private JTextField num1;
private JTextField num2;
private JTextField tot;
public Calcolatrice(){
}
//Gestione Evento
private class AzioneSomma implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
int n1= Integer.parseInt(num1.getText());
int n2= Integer.parseInt(num2.getText());
tot.setText("" + (n1+n2));
}
}
41
Link utili
Swing Tutorial:
http://download.oracle.com/javase/tutorial/uiswing/index.html
Java Api:
http://java.sun.com/javase/6/docs/api/
42