Breve introduzione all`uso di SWING in JAVA File - e

Università degli Studi di Pisa
Dipartimento di Informatica
Lezione 12
Laboratorio Programmazione Rete
GUI JAVA:
nozioni di base per il progetto
13/12/2016
Laura Ricci
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
PERCHE' UNA INTERFACCI GRAFICA?
●
consideriamo il Client del progetto Text Twist. Il Client deve:
●
visualizzare i messaggi che provengono dal server (callback)
corrispondenti agli inviti da parte degli altri giocatori
●
gestire i messaggi provenienti da gruppo di multicast
●
accettare le richieste provenienti dall'utente di aperture di nuove
partite e di proposte di parole
●
in una interfaccia a linea di testo, le righe introdotte dall'utente
potrebbero essere visualizzate in interleaving con messaggi provenienti
dal server
●
una semplice interfaccia grafica può risolvere questo problema
●
●
diverse aree per l'immissione dei dati, visualizzazione messaggi
importante: il progetto dell'interfaccia non è una priorità del progetto,
deve essere solo un mezzo per rendere più semplice l'implementazione!
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA GUI: INTRODUZIONE
Struttura generale di un programma JAVA che utilizza una GUI:
●
main() routine sempre presente:
●
in generale crea una o più componenti GUI e le rende visibili sullo
schermo
●
●
dopo che le componenti sono state create, esse sono autonome
il comportamento di ogni componente è programmato all'interno della
componente stessa, e la componente gestisce gli eventi generati dall'utente
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE: JFRAME
Componente fondamentale: La classe JFrame che rappresenta una window:
(inclusa nel package javax.swing)
●
apertura e chiusura
●
resizing
e diversi attributi:
●
titlebar, dimensioni,....
import javax.swing.*;
public class GUIClass {
public static void main (String args[])
{ JFrame window = new JFrame("GUI Test");
window.setSize(800,600);
window.setLocation(100,100);
window.setVisible(true);
} }
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE: CONTENTPANE
●
il contenuto visualizzato in un JFrame viene indicato come content pane
(pane = vetro).
●
un JFrame possiede per default un content pane: si possono aggiungere
oggetti direttamente a questo content pane oppure crearne uno nuovo
●
gli oggetti possono essere, a loro volta, contenitori oppure oggetti semplici
import javax.swing.*;
public class GUIClass {
public static void main (String args[])
{ JFrame window = new JFrame("GUI Test");
window.setSize(800,600);
window.setLocation(100,100);
window.setVisible(true);
}}
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA CONTAINERS
●
componenti: elementi base visibili che possono formare una GUI
●
containers: componenti che possono contenere altri componenti: oggetto
che appartiene ad una sottoclasse di java.awt.Container
●
esempi di contenitori
●
●
●
il content pane di default di un oggetto Jframe
Jpanel: può contenere un altro Jpanel in modo da organizzare
l'interfaccia in modo gerarchico.
all'interno di un Jpanel possono essere posizionati componenti
elementari (bottoni, text areas,...)
JPanel annidati
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA LAYOUTS
●
i componenti aggiunti ad un contenitore (ad esempio un JPanel) devono essere
posizionati all'interno di esso:
●
●
●
diversi layout definiti per default (FlowLayout, BorderLayout,,
GridLayout)
possibile anche creare nuovi layout
Layout manager: oggetto associato ad un contenitore che implementa qualche
strategia per il posizionamento dei componenti.
●
per associare un layout ad un contenitore Cont :
Cont.setLayout(....), parametro un oggetto di tipo LayoutManager
●
per aggiungere un componente ad un contenitore Cont:
Cont.add(....), parametri: coomponente da aggiungere + indicazioni
(dipendenti dal Layout) su come posizionare quella componente
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
BASIC LAYOUT MANAGER: FLOWLAYOUT
Allinea i componenti in righe successive:
●
la dimensione di ogni componente è stabilita dal sistema
●
quando una riga è riempita, passa ad inserire componenti nella riga successiva
●
layout di default per un oggetto JPanel
●
può essere impostato mediante il metodo setLayout().
●
costruttore
public FlowLayout(int align, int hgap, int vgap)
align: allineamento al centro, a sinistra o a destra
hgap, vgap: spazio orizzontale e verticale tra le componenti
●
Esempio di inserimento di 5 buttons in un FlowLayout
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
BASIC LAYOUT MANAGER: BORDERLAYOUT
●
una grande componente centrale e 4 componenti più piccole ai lati della
componente centrale
●
per aggiungere una componente comp in questo layout associato ad un container
comp
cntr.add(comp, borderLayoutPosition);
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
BASIC LAYOUT MANAGER: GRIDLAYOUT
●
un GridLayout organizza le componenti in una gliglia composta con righe e
colonne tutte della stessa dimensione
●
una griglia con 4 righe e 3 colonne
●
costruttori:
new GridLayout(R,C)
new GridLayout(R,C,H,V)
●
R,C: numero righe e colonne
●
H,V: numero di pixel tra righe e colonne
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE
●
componenti standard definiti come sottoclassi della classe JComponent,
sottoclasse della classe Component.
●
per utilizzare una componente:
●
creare la componente
●
aggiungere la componente ad un contenitore
●
registrare un listener per quella componente che consenta di
intercettare gli eventi da essa generati
●
componenti standard:
●
JButton
●
JLabel
●
JCheckBox
●
JTextField, JTextArea
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE: JBUTTON
●
rappresenta un oggetto selezionabile identificato da una label
stopGoButton = new Jbutton("Go")
●
diversi metodi per disabilitare il bottone, stabilirne le caratteristiche,...
●
quando l'utente clicca sul bottone, il bottone stesso genera un evento
di tipo Action-Event.
●
Listener: per gestire eventi che vengono generati dai buttons, occorre
implementare l'interfaccia ActionListener che contiene un unico metodo:
public void actionPerformed(ActionEvent evt)
che viene invocato quando viene generato un evento dal bottone
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE: JLABEL
●
Jlabel: un semplice componente utilizzata per visualizzare una linea di testo,
impostata nel costruttore
●
non cliccabile (a differenza di Jbutton)
●
il testo non può essere editato dall'utente, solo impostato da programma
JLabel message = new JLabel("Hello World!", JLabel.CENTER);
message.setForeground(Color.RED); // Display red text...
message.setBackground(Color.BLACK); // on a black background...
message.setFont(new Font("Serif",Font.BOLD,18)); // in a big bold font.
message.setOpaque(true); // Make sure background is filled in.
JPanel jp = new JPanel();
jp.add(message);
JFrame window = new JFrame("GUI Test");
window.setContentPane(jp);
window.setVisible(true); }}
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
COMPONENTI BASE: JTEXTFIELD E JTEXTAREA
●
JTextField e JTextArea: rappresentano componenti che possono contenere
testo editabile
●
JTextField può contenere una singola linea di testo
●
JtextArea può contenere più di una linea di testo
JPanel jp1 = new JPanel();
JTextField inputArea = new JTextField("0",10);
inputArea.setEditable(true);
jp1.add(inputArea);
JFrame window = new JFrame("GUI Test");
window.setContentPane(jp1);
window.setSize(800,600);
window.setLocation(100,100);
window.setVisible(true);
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
import java.awt.*;
import javax.swing.*;
public class GossipInterface extends JFrame {
public GossipInterface(
)
{ setTitle("GOSSIP");
setSize(1000,800);
JPanel panel1= new JPanel();
panel1.setLayout(null); }
public static void main (String args[
])
{ GossipInterface gi = new GossipInterface(
);
gi.setVisible(true);
}
}
con setLayout(null) il posizionamento delle componenti è a carico dell'utente.
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JLabel statusLabel = new JLabel("Stato");
statusLabel.setBounds(100,20,30,30);
panel1.add(statusLabel);
public void setBounds(int x,int y,int width,int height)
•
ereditato dalla classe awt.component
•
stabilisce la locazione del componente all'interno del pannello e la dimensione
del componente
x
0,0
y
Parametri
•
x,y - individuano la posizione del vertice superiore sinistro in un sistema di
assi cartesiani orientati nel modo seguente
•
width, height - individuano ampiezza ed altezza del componente
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JTextArea statusArea = new JTextArea( );
statusArea.setEditable(true);
JScrollPane scrollPaneStatus = new JScrollPane(statusArea);
scrollPaneStatus.setBounds(30,50,200,400);
panel1.add(scrollPaneStatus);
statusArea.append("jack online\n");
statusArea.append("john offline\n");
statusArea.append("laura online\n");
statusArea.append("paolo offline\n");
•
SetEditable – proprietà che consente di specificare se l'area di testo
può essere editata o meno dall'utente
•
JScrollPane – aggiunge barre di scorrimento all'area
●
metodo append: consente di aggiungere linee di caratteri ad una text area.
Le linee sono separate da un carattere di new line \n
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JLabel statusMsg = new JLabel("Messaggi");
statusMsg.setBounds(380,20,80,30);
panel1.add(statusMsg);
JTextArea printArea= new JTextArea();
printArea.setEditable(true);
JScrollPane scrollPane = new JScrollPane(printArea);
scrollPane.setBounds(320,50,200,400);
panel1.add(scrollPane);
printArea.append("ciao, ciao sono jack, come stai?");
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JLabel inputLabel = new JLabel("Scrivi");
inputLabel.setBounds(30,480,100,100);
panel1.add(inputLabel);
JTextField InputArea = new JTextField();
InputArea.setBounds(30,550,600,30);
InputArea.setEditable(true);
panel1.add(InputArea);
•
JTextField = campo di testo, si può leggere il valore inserito in questo
campo dall'utente
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JButton invia = new JButton("invia");
invia.setEnabled(true);
invia.setBounds(690,550,80,30);
panel1.add(invia);
•
JButton E' un pulsante che l'utente preme per lanciare una specifica
azione
•
nel nostro caso l'azione corrisponde all'invio del testo editato
nell'area JtextField
•
al costruttore viene passata la stringa che rappresenta il testo
visualizzto sul pulsante
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GOSSIP (PROGETTO 2014): L'INTERFACCIA
JButton chiudi = new JButton("chiudi");
chiudi.setEnabled(true);
chiudi.setBounds(30,600,80,30);
panel1.add(chiudi);
getContentPane().add(panel1);
•
questo pulsante è utilizzato per chiudere l'applicazione
•
infine il pannello creato viene aggiunto al JFrame (la finestra) mediante la
funzione getContentPane().
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA GUI: GESTIONE DEGLI EVENTI
•
Quando un utente esegue qualche operazione sulle componenti inserite in
una finestra viene generato un evento asincrono.
•
Alcuni esempi di eventi:
•
●
digitazione di un tasto
●
spostamento del mouse
●
click di un pulsante del mouse
●
selezione di un elemento dell'intefaccia grafica (es: un bottone)
●
chiusura della finestra
Il gestore delle finestre invia una segnalazione al programma identificando
l'evento mediante un codice
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA GUI: GESTIONE DEGLI EVENTI
•
l'applicazione deve definire un gestore di eventi, un Listener, per ogni
evento che interessa gestire
•
JAVA definisce interfacce diverse per ogni
essere generato dall'interfaccia
•
●
KeyListener
●
MouseListener
●
WindowListener
●
ActionListener,
●
....
tipo di evento che può
il gestore degli eventi viene definito mediante una implementazione di
questa interfaccia
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
JAVA GUI: GESTIONE DEGLI EVENTI
•
consideriamo GOSSIP, l'applicazione descritta nel progetto 2014, che
implementava una chat con consegna di messaggi a proxy nel caso gli
utenti non siano online
•
è necessario definire un insieme di pulsanti per interagire con
l'applicazione, ad esempio il tasto invia, che consente di inviare un
messaggio, o quello che consente di chiudere una finestra
•
gli eventi interessanti per l'applicazione sono quelli legati alla selezione
di questi bottoni
•
deve essere utilizzata l'interfaccia:
public interface ActionListener {
void actionPerformed (actionEvent event);
•
}
compito
del
programmatore
è
implementare
il
metodo
actionPerformed, in modo che esegua il codice da eseguire quando
viene selezionato il pulsante
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GESTIONE DEGLI EVENTI: UN ESEMPIO
consideriamo la seguente interfaccia:
quando viene selezionato il bottone, l'applicazione stampa a linea di
comando il messaggio “I was clicked”
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GESTIONE DEGLI EVENTI: UN ESEMPIO
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ClickListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("I was clicked");
}
il parametro event contiene ulteriori dettagli sull'evento, ad esempio
l'istante in cui esso è avvenuto
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GESTIONE DEGLI EVENTI: UN ESEMPIO
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class interfaceevents{
private static final int FRAME_WIDTH = 700;
private static final int FRAME_HEIGHT = 500;
public static void main(String args[])
{ JFrame frame = new JFrame();
JButton button = new JButton("click me!!!");
frame.add(button);
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
GESTIONE DEGLI EVENTI: UN ESEMPIO
ActionListener listener = new ClickListener();
button.addActionListener(listener);
frame.setSize(FRAME_WIDTH,FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
UN CONTATORE DI 'CLICKS'
modifichiamo il programma precedente in modo che, ogni volta che viene
selezionato il bottone, venga visualizzato il numero di volte che il pulsante è
stato selezionato fino a quel momento
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
UN CONTATORE DI 'CLICKS'
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class swingexample extends JFrame
{
private static String labelPrefix = "Number of clicks: ";
private int numClicks = 0;
JLabel label = null;
JButton button = null;
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
UN CONTATORE DI CLICKS
public swingexample()
{
label =
new JLabel(labelPrefix + "0
");
button = new JButton("Click me!");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
numClicks++;
label.setText(labelPrefix + numClicks);
}
};
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
UN CONTATORE DI CLICKS
Container panel = getContentPane ();
panel.setLayout(new GridLayout(2, 1));
panel.add(button);
panel.add(label);
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{ System.exit(0);} } );
setVisible(true);
}
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
●
2 JTextFields dove l'utente può immettere i numeri
●
4 JButtons che l'utente può cliccare per selezionare
l'operazione di somma, sottrazione, moltiplicazione o divisione
●
1 Jlabel per visualizzare il risultato della operazione
●
2 event handlers
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleCalculator extends JPanel implements
ActionListener {
private JTextField xInput, yInput;
private JLabel answer;
public static void main(String[] args) {
JFrame window = new JFrame("Simple Calculator");
SimpleCalculator content = new SimpleCalculator();
window.setContentPane(content);
window.pack();
window.setLocation(100,100);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
window.setVisible(true);
Dipartimento di Informatica
Università degli Studi di Pisa
}
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
●
window.pack(): effettua il resizing della finestra, in modo che le sue
dimensioni siano adatte alla dimensione ottimale delle componenti in essa
contenute
●
funziona correttamente se e solo se la dimensione ottimale dei
componenti è determinata automaticamente dal sistema
●
●
questo non avviene se si utilizza un container con un null LayoutManager
●
se
si utilizza null Layout Manager l'utente
autonomamente la dimensione dei componenti
deve
determinare
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE): specifica
l'azione da fare al momento della chiusura della finestra
●
Jframe.EXIT_ON_CLOSE: quit dell'applicazione
●
Jframe.HIDE_ON_CLOSE: nasconde il frame ma l'applicazione rimane attiva
●
Jframe.DISPOSE_ON_CLOSE: dispose del frame, applicazione attiva
●
Jframe.DO_NOTHING_ON_CLOSE: ignora il click
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
public SimpleCalculator() {
setBackground(Color.GRAY);
setBorder(BorderFactory.createEmptyBorder(5,5,5,5))
xInput = new JTextField("0", 10);
xInput.setBackground(Color.WHITE);
yInput = new JTextField("0", 10);
yInput.setBackground(Color.WHITE);
JPanel xPanel = new JPanel();
xPanel.add( new JLabel(" x = "));
xPanel.add(xInput);
JPanel yPanel = new JPanel();
yPanel.add( new JLabel(" y = "));
yPanel.add(yInput);
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
●
setBorder: impostazioni dei bordi del pannello principale
●
BorderFactory.createEmptyBorder(5,5,5,5)
●
●
i quattro valori definiscono l'ampiezza dei quattro bordi del pannello
uso di pannelli annidati:
●
un pannello per ogni componente
●
i sottopannelli utilizzano il default layout manager, FlowLayout layout
manager: in questo modo la Label ed il TextField vengono semplicemente
posti uno di fianco all'altro
●
i singoli pannelli verrano quindi aggiunti al pannello principale (vedi lucidi
successivi) con un opportuno LayoutManager
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1,4));
JButton plus = new JButton("+");
plus.addActionListener(this);
buttonPanel.add(plus);
JButton minus = new JButton("-");
minus.addActionListener(this);
buttonPanel.add(minus);
JButton times = new JButton("*");
times.addActionListener(this);
buttonPanel.add(times);
JButton divide = new JButton("/");
divide.addActionListener(this);
buttonPanel.add(divide);
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
answer = new JLabel("x + y = 0", JLabel.CENTER);
answer.setForeground(Color.red);
answer.setBackground(Color.white);
answer.setOpaque(true);
setLayout(new GridLayout(4,1,3,3));
add(xPanel);
add(yPanel);
add(buttonPanel);
add(answer);
riferimento implicito a this, cioè al pannello principale
●
setLayout:
●
utilizzato un GridLayout con quattro righe
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
public void actionPerformed(ActionEvent evt) {
double x, y;
// The numbers from the input boxes.
try { String xStr = xInput.getText();
x = Double.parseDouble(xStr); }
catch (NumberFormatException e) {
answer.setText("Illegal data for x.");
xInput.requestFocusInWindow();
return; }
try { String yStr = yInput.getText();
y = Double.parseDouble(yStr); }
catch (NumberFormatException e) {
answer.setText("Illegal data for y.");
yInput.requestFocusInWindow();
return; }
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
String op = evt.getActionCommand();
if (op.equals("+"))
answer.setText( "x + y = " + (x+y) );
else if (op.equals("-"))
answer.setText( "x - y = " + (x-y) );
else if (op.equals("*"))
answer.setText( "x * y = " + (x*y) );
else if (op.equals("/")) {
if (y == 0)
answer.setText("Can't divide by zero!");
else
answer.setText( "x / y = " + (x/y) );
} } }
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci
MINI CALCOLATRICE
●
poichè abbiamo associato lo stesso Listener ai quattro bottoni (per le
quattro operazioni aritmetiche), occorre distinguere quale bottone è stato
premuto
●
evt.getActionCommand():
●
restituisce la stringa associata al bottone che è stato premuto
●
la stringa identifica l'operazione che deve essere eseguita
Dipartimento di Informatica
Università degli Studi di Pisa
GUI: Nozioni di Base
Laura Ricci