Bottoni
I
pulsanti, grazie alla loro modalita' di utilizzo estremamente intuitiva,
sono sicuramenti i controlli grafici piu' usati. Swing offre quattro tipi
di pulsanti, legati tra loro dalla gerarchia illustrata in Figura 1.
|
Figura
1 - Gerarchia dei bottoni Swing
JButton
e' l'implementazione del comune bottone "Push"; JToggleButton e' un pulsante
On-Off; JCheckBox e' un controllo grafico creato sul modello delle caselle
di spunta dei questionari; JRadioButton e' un controllo che permette di
scegliere una tra molte possibilita' in modo mututamente esclusivo.
|
Figura
2 - Pulsanti disponibili su Swing
La
classe AbstractButton definisce l'interfaccia di programmazione comune
a tutti i pulsanti: per questa ragione cominceremo il nostro studio da
questa classe; dopo aver appreso il funzionamento di una delle sottoclassi
concrete di AbstractButton, sara' abbastanza facile capire gli altri.
AbstractButton
- Gestione dell'aspetto
L'API
di AbstractButton definisce un insieme di metodi per gestire l'aspetto
del componente; in particolare viene fornita la possibilita' di associare
ad ogni controllo grafico un'ettichetta di testo, un'icona o entrambi.
E' possibile impostare l'etichetta in formato HTML: basta aggiungere il
prefisso "<html>" nel parametro di setText(String). Le seguenti righe
di codice creeranno un JButton con un'ettichetta HTML:
JButton
b =new JButton();
b.setText("<html><font
size=-1><b><u>Esempio</u></b> di pulsante <b>HTML</b></font></html>"));
|
Figura
3 - E' possibile decorare un pulsante con HTML
I pulsanti
Swing permettono di impostare un'icona diversa per ognuno degli stati in
cui si possono trovare: normale, premuto, selezionato (valido per i controlli
che mantengono lo stato come i CheckBox), disabilitato e rollover (lo stato
in cui si trova un controllo quando viene sorvolato dal puntatore del mouse).
-
void
setText(String text):
Imposta l'eticchetta di testo.
-
void
setEnabled(boolean b):
Abilita o disabilita il controllo.
-
void
setRolloverEnabled(boolean b):
Attiva o disattiva l'effetto rollover.
-
void
setSelected(boolean b):
Regola lo stato del controllo.
-
void
setIcon(Icon defaultIcon):
Imposta l'icona di default.
-
void
setPressedIcon(Icon pressedIcon):
Imposta l'icona per lo stato "premuto".
-
void
setSelectedIcon(Icon selectedIcon):
Imposta l'icona "selezionato".
-
void
setDisabledIcon(Icon disabledIcon):
Imposta l'icona "disabilitato".
-
void
setRolloverIcon(Icon rolloverIcon):
Imposta l'icona "rollover".
-
void
setDisabledSelectedIcon(Icon disabledSelectedIcon):
Imposta l'icona per la combinazione "disabilitato - selezionato"
-
void
setRolloverSelectedIcon(Icon rolloverSelectedIcon):
Imposta l'icona per la combinazione "rollover selezionato"
Come icona
possiamo usare un oggetto di tipo ImageIcon, ricorrendo al costruttore
ImageIcon(String filename) che crea un'icona a partire da un'immagine di
tipo GIF o JPEG il cui percorso viene specificato nella stringa del parametro.
Il
piu' delle volte e' sufficiente specificare l'icona di default, dal momento
che le immagini per gli stati "premuto", "selezionato" e "disabilitato"
vengono create in modo automatico a partire da quella principale. Le seguenti
righe creano un pulsante decorato con l'immagine "img.gif" (puo' andar
bene una qualunque immagine): ovviamente il file deve essere presente nella
directory di lavoro, altrimenti verra' creato un pulsante vuoto.
// crea un pulsante
JButton b = new JButton();
// crea un'icona
ImageIcon icon = new ImageIcon("img.gif");
// imposta icon come icona per b
b.setIcon(icon);
AbstractButton
- Gestione degli eventi
I
controlli derivati da AbstractButton prevedono due tipi di ascoltatore:
ActionListener ed ItemListener. Il primo ascolta il tipo piu' semplice
di evento, come la pressione di un pulsante; il secondo permette di conoscere
i cambiamenti da "selezionato" a "non selezionato" o viceversa nei pulsanti
tipo JToggleButton. Nei paragrafi seguenti vedremo alcuni esempi di utilizzo;
qui di seguito possiamo vedere i metodi necessari ad aggiungere o rimuovere
i gli ascoltatori da un pulsante.
|
Figura
4 - Ascoltatori ed eventi per i pulsanti
-
void
addActionListener(ActionListener l):
aggiunge un ActionListener al pulsante
-
void
removeActionListener(ActionListener l):
rimuove un ActionListener dal pulsante
-
void
addItemListener(ItemListener l):
aggiunge un ItemListener al pulsante.
-
void
removeItemListener(ItemListener l):
rimuove un ItemListener dal pulsante.
E'
da segnalare la possibilita' di attivare le azioni associate ad un pulsante
in maniera equivalente a quella che si otterrebbe con un click del mouse.
-
void
doClick()
Esegue un click sul pulsante
JButton
Vediamo
ora la prima sottoclasse concreta di AbstractButton: JButton, il comune
pulsante push. I seguenti costruttori permettono di creare pulsanti
e di definirne le principali proprieta'.
-
JButton(String
text):
Crea un pulsante con l'etichetta specificata dal parametro.
-
Button(Icon
icon):
Crea
un pulsante con l'icona specificata dal parametro.
-
Button(String
text, Icon icon):
Crea un pulsante con l'etichetta e l'icona specificate dai parametri
Ogni
Top Level container puo' segnalare un pulsante come DefaultButton. Esso
verra' evidenziato in maniera particolare e verra' richiamato con la semplice
pressione del tasto "Invio". Le righe seguenti creano un pulsante, un JFrame
e impostano il pulsante come DefaultButton :
JFrame f = new JFrame();
JButton b = new JButton("DefaultButton");
f.getContentPane().add(b);
f.getRootPane().setDefaultButton(b);
L'ascoltatore
piu' utile per un JButton e' ActionListener, che riceve eventi di tipo
ActionEvent quando il pulsante viene premuto e rilasciato. Di seguito ecco
i metodi piu' importanti di ActionEvent
-
String
getActionCommand():
restituisce una stringa che identifica il comando (se non viene specificata
altrimenti, e' uguale all'etichetta del pulsante).
-
String
paramString():
restituisce un parametro che identifica l'evento.
|
Figura
5 - Relazione tra JButton e ActionEvent
Vediamo
ora un programma di esempio che illustra l'uso di due JButton, uno dei
quali viene registrato come DefaultButton, e dei relativi ascoltatori.
|
Figura
6 - Esempio di uso di JButton
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
public
class JButtonExample extends JFrame {
private JDialog dialog;
private JButton okButton;
private JButton jDialogButton;
public JButtonExample() {
// Imposta le proprieta' del Top Level Container
super("JButtonExample");
setBounds(10,35,200,70);
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
// Crea una finestra di dialogo modale, inizialmente invisibile
dialog = new JDialog(this,"JDialog",true);
dialog.setBounds(250,20,300,100);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(BorderLayout.CENTER,new JLabel("Chiudi questa
finestra per continuare",JLabel.CENTER));
dialog.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
// Crea due pulsanti
okButton = new JButton("OK");
jDialogButton = new JButton("Open Frame");
// Crea gli ascoltatori
ActionListener okListener = new OKButtonListener();
ActionListener openActionListener = new JDialogButtonListener();
// Registra gli ascoltatori presso i pulsanti
okButton.addActionListener(okListener);
jDialogButton.addActionListener(openActionListener);
//imposta okButton come DefaultButton
getRootPane().setDefaultButton(okButton);
// Aggiunge i pulsanti al Top Level Container
getContentPane().add(okButton);
getContentPane().add(jDialogButton);
setVisible(true);
}
// Ascoltatore del pulsante OK
class OKButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
System.exit(0);
}
catch (Exception ex) {}
}
}
// Ascoltatore del pulsante jDialog
class JDialogButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
}
public
static void main(String argv[])
{
JButtonExample b = new JButtonExample();
}
}
JToggleButton
E
un pulsante che puo' avere due stati: premuto e rilasciato. Clickando con
il mouse si provoca il passaggio tra uno stato e l'altro. Alcuni costruttori
permettono di creare JToggleButton e di impostarne le proprieta'.
-
JToggleButton(String
text, Icon icon, boolean selected):
Crea un pulsante con l'etichetta, l'icona e lo stato specificate dai parametri
-
JToggleButton(String
text, boolean selected):
Crea un pulsante con l'etichetta e lo stato specificate dai parametri
-
JToggleButton(Icon
icon, boolean selected):
Crea un pulsante conl'icona e lo stato specificate dai parametri, senza
etichetta.
Un JToggleButton,
quando viene premuto, genera un ActionEvent e un ItemEvent. L'evento piu'
interessante per questo tipo di pulsanti e' il secondo, che segnala
il cambiamento di stato, cioe' il passaggio da premuto a rilasciato e viceversa.
-
Object
getItem():
restituisce l'oggetto che ha generato l'evento.
-
int
getStateChange():
restituisce un intero che puo' assumere i valori ItemEvent.SELECTED o ItemEvent.DESELECTED
-
String
paramString():
restituisce un parametro che identifica l'evento.
|
Figura
7 - Relazione tra ItemEvent e JToggleButton
E'
possibile comunque utilizzare ActionListener alla stessa maniera dell'esempio
precedente: in questo caso verra' inviato un ActionEvent ad ogni click,
indipendentemente dallo stato del pulsante. Il seguente esempio crea una
finestra con un JToggleButton che permette di aprire e di chiudere una
finestra di dialogo non modale.
|
Figura
8 - Esempio di JToggleButton
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
public
class JToggleButtonExample extends JFrame {
private JDialog dialog;
private JToggleButton jDialogButton;
public JToggleButtonExample() {
// Imposta le proprieta' del Top Level Container
super("JToggleButtonExample");
setBounds(10,35,250,70);
FlowLayout fl=new FlowLayout(FlowLayout.CENTER)
getContentPane().setLayout(fl);
// Crea una finestra di dialogo non modale,
//inizialmente invisibile
dialog = new JDialog(this,"JDialog",false);
dialog.setBounds(250,20,300,100);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(BorderLayout.CENTER,new
JLabel("Finestra Aperta",JLabel.CENTER));
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
// Crea il pulsante e lo registra presso il suo ascoltatore
jDialogButton = new JToggleButton("Open / Close Frame",false);
jDialogButton.addItemListener(new
JDialogButtonItemListener());
// Aggiunge il pulsante al Top Level Container
getContentPane().add(jDialogButton);
setVisible(true);
}
// Ascoltatore di JDialogButton
class JDialogButtonItemListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
int status = e.getStateChange();
if(status == ItemEvent.SELECTED)
dialog.setVisible(true);
else
dialog.setVisible(false);
}
}
public
static void main(String argv[]) {
JToggleButtonExample b = new JToggleButtonExample();
}
}
Il
codice dell'ascoltatore JDialogButtonItemListener e' un po' piu' complesso
di quello degli ActionListener dell'esempio precedente: il codice di questo
tipo di ascoltatori deve normalmente prevedere una verifica dello stato
in cui si trova trova il pulsante, al fine di scatenare la giusta reazione.
La verifica dello stato viene effettuata interrogando l'oggetto ItemEvent
con il metodo getStateChange().
JCheckBox
JCheckBox
e' una sottoclasse di JToggleButton che ha una forma simile alle caselle
di spunta dei questionari. Il suo funzionamento e' analogo a quello della
superclasse, ma di fatto tende ad essere utilizzato in contesti in cui
si offre all'utente la possibilita' di scegliere una o piu' opzioni tra
un insieme, come avviene ad esempio nei pannelli di controllo. I costruttori
disponibili sono gli stessi di JToggleButton, e cosi' pure la gestione
degli eventi, pertanto non sara' necessario ripeterli. Un esempio mostrera'
un uso tipico di questo componente.
|
Figura
9 - Con i due JCheckBox e' possibile due finestre di dialogo
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
public
class JCheckBoxExample extends JFrame {
private JDialog dialog1;
private JDialog dialog2;
private JCheckBox checkBox1;
private JCheckBox checkBox2;
public JCheckBoxExample() {
// Imposta le proprieta' del Top Level Container
super("JCheckBoxExample");
setBounds(10,35,200,70);
FlowLayout fl=new FlowLayout(FlowLayout.CENTER)
getContentPane().setLayout(fl);
// Crea due finestre di dialogo non modali,
// inizialmente invisibili
dialog1 = new JDialog(this,"JDialog 1",false);
dialog1.setBounds(250,20,300,100);
dialog1.getContentPane().setLayout(new BorderLayout());
dialog1.getContentPane().add(BorderLayout.CENTER,new
JLabel("Finestra 1 Aperta",JLabel.CENTER));
dialog1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
dialog2 = new JDialog(this,"JDialog 2",false);
dialog2.setBounds(250,150,300,100);
dialog2.getContentPane().setLayout(new BorderLayout());
dialog2.getContentPane().add(BorderLayout.CENTER,
new JLabel("Finestra 2 Aperta",JLabel.CENTER));
dialog2.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
// Crea i checkBox e li registra presso il loro ascoltatore
ItemListener listener = new JCheckBoxItemListener();
checkBox1 = new JCheckBox("Finestra 1");
checkBox1.addItemListener(listener);
checkBox2 = new JCheckBox("Finestra 2");
checkBox2.addItemListener(listener);
// Aggiunge i checkBox al Top Level Container
getContentPane().add(checkBox1);
getContentPane().add(checkBox2);
setVisible(true);
}
// ascoltatore JCheckBox
class JCheckBoxItemListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
Object target = e.getItem();
int status = e.getStateChange();
if(target.equals(checkBox1)
&& status == ItemEvent.SELECTED)
dialog1.setVisible(true);
else if(target.equals(checkBox1)
&& status == ItemEvent.DESELECTED)
dialog1.setVisible(false);
else if(target.equals(checkBox2)
&& status == ItemEvent.SELECTED)
dialog2.setVisible(true);
else if(target.equals(checkBox2)
&& status == ItemEvent.DESELECTED)
dialog2.setVisible(false);
}
}
public
static void main(String argv[]) {
JCheckBoxExample b = new JCheckBoxExample();
}
}
L'ascoltatore
JCheckBoxItemListener presenta un grado di complessita' maggiore del precedente:
esso ascolta entrambi i controlli, e ad ogni chiamata verifica quale dei
due abbia generato l'evento (chiamando il metodo getItem() di ItemEvent)
e quale stato ha assunto, e quindi predispone la reazione opportuna.
JRadioButton
JRadioButton
e' una sottoclasse di JToggleButton, dotata dei medesimi costruttori. Questo
tipo di controlli viene usato tipicamente per fornire all'utente la possibilita'
di operare una scelta tra un insieme di possibilita', laddove una scelta
esclude l'altra. Per implementare questo comportamento di mutua esclusione
e' necessario registrare i JRadioButton che costituiscono l'insieme presso
un'istanza della classe ButtonGroup, come viene mostrato nelle righe seguenti
ButtonGroup
group = new ButtonGroup();
group.add(radioButton1);
group.add(radioButton2);
group.add(radioButton3);
Ogni
volta che l'utente attiva uno dei pulsanti registrati presso il ButtonGroup,
gli altri vengono automaticamente messi a riposo. Questo comportamento
ha una conseguenza importante nella gestione degli eventi: un gruppo di
JRadioButton registrati presso un ButtonGroup genera due ItemEvent consecutivi
per ogni click del mouse, uno per la casella che viene selezionata ed uno
per quella deselezionata. Di norma si e' interessati unicamente al fatto
che un particolare JRadioButton sia stato premuto, poiche' la politica
di mutua esclusione rende superfluo verificarne lo stato: in questi casi
e' consigliabile utilizzare un ActionListener come nell'esempio seguente,
nel quale un gruppo di JRadioButton permette di modificare la scritta
su un'etichetta di testo.
|
Figura
10 - Attivando un JRadioButton l'etichetta viene modificata
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
public
class JRadiobuttonExample extends JFrame {
private JRadioButton radioButton1;
private JRadioButton radioButton2;
private JRadioButton radioButton3;
private JLabel label;
public JRadiobuttonExample() {
// Imposta le proprieta' del Top Level Container
super("JRadiobuttonExample");
setBounds(10,35,150,150);
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
// Crea i radiobutton e la label
radioButton1 = new JRadioButton("RadioButton 1");
radioButton2 = new JRadioButton("RadioButton 2");
radioButton3 = new JRadioButton("RadioButton 3");
label = new JLabel();
// Crea l'ascoltatore e registra i JRadioButton
ActionListener listener = new JRadioButtonListener();
radioButton1.addActionListener(listener);
radioButton2.addActionListener(listener);
radioButton3.addActionListener(listener);
// Crea il ButtonGroup e registra i RadioButton
ButtonGroup group = new ButtonGroup();
group.add(radioButton1);
group.add(radioButton2);
group.add(radioButton3);
// Aggiunge i componenti al Top Level Container
getContentPane().add(radioButton1);
getContentPane().add(radioButton2);
getContentPane().add(radioButton3);
getContentPane().add(label);
radioButton1.doClick();
setVisible(true);
}
// Ascoltatore JRadioButton
class JRadioButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String target = e.getActionCommand();
label.setText(target);
}
}
public
static void main(String argv[]) {
JRadiobuttonExample b = new JRadiobuttonExample();
}
}
Conclusioni
In
questo articolo abbiamo imparato l'uso dei pulsanti, grazie ad alcuni esempi
che potete trovare in allegato nel file esempi.zip
Nel
prossimo articolo impareremo dapprima a disporre i pulsanti all'interno
di Tool Bar, quindi a realizzare menu a tendina.
|