Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Utilizzo delle Actions in Swing

Vediamo come utilizzare le Actions, che permettono di definire un comportamento al verificarsi di un evento
Vediamo come utilizzare le Actions, che permettono di definire un comportamento al verificarsi di un evento
Link copiato negli appunti

Le Actions rappresentano un utile strumento che consente di definire un determinato comportamento in relazione a eventi scatenati da più sorgenti.

Per chiarire meglio il concetto potremmo pensare, per esempio, a un Action che esegua l'apertura di un file dal disco e a una applicazione che utilizzi tale Action sia da una voce specifica del menù che da un pulsante definito sulla toolbar.

Il fatto di condividere lo stesso oggetto di tipo Action (detto action object) permette a tutti i componenti che ne fanno uso di essere avvisati in modo automatico ogni volta che una proprietà dell'oggetto Action stesso viene modificata.

Nell'esempio precedente, se la proprietà enabled dell'action object che esegue l'apertura del file viene posta a false, sia la voce di menù che il pulsante della toolbar risulteranno automaticamente disabilitati.

L'interfaccia Action

Ogni Action deve implementare l'interfaccia javax.swing.Action, che deriva, a sua volta, dall'interfaccia ActionListener definita nell'Abstract Window Toolkit (AWT). Ne consegue che ogni classe che implementi l'interfaccia Action dovrà fornire un'implementazione del metodo actionPerformed(). È proprio all'interno di tale metodo che andrà scritto il codice che si occuperà di definire il comportamento desiderato per l'action object.

L'interazione con i Container di Swing

Le Swing consentono una grande flessibilità nell'uso delle Action. Infatti, ogni oggetto di tipo Action può essere aggiunto direttamente a un qualunque Swing container, sebbene questo tipo di utilizzo sia stato deprecato a partire dalla versione 1.3 del JDK. In altre parole, definito un action object sarà sempre possibile scrivere istruzioni del tipo:

JToolBar toolBar = new JToolBar();
toolBar.add(myAction);

dove myAction sarà un oggetto di tipo Action.

Quando si aggiunge un'Action a un container, quest'ultimo crea automaticamente un componente grafico opportuno in grado di interagire con l'action object fornito in input al metodo add().

Attraverso l'uso delle due righe precedenti, per esempio, verrà creato un JButton che sarà aggiunto al container di tipo JToolBar. Il riferimento al JButton da utilizzare per eventuali personalizzazioni, sarà restituito dal metodo add() stesso.

Il modo più idoneo per ottenere il medesimo risultato, a partire dalla release 1.3, prevede, però, l'utilizzo del metodo setAction() invocato direttamente dal componente grafico che si desidera aggiungere al container. Ovvero:

JToolBar toolBar = new JToolBar();
JButton button = new JButton();
button.setAction(myAction);
toolbar.add(button);

Esiste una doppia interazione tra l'oggetto di tipo Action e ogni componente grafico inserito su un container a cui sia stata assegnata un'azione definita dall'oggetto stesso:

  • Il componente grafico si registra come PropertyChangeListener, in ascolto per ogni eventuale modifica che dovesse verificarsi nell'action object
  • L'action object registra se stesso come ActionListener sul componente grafico.
Figura 1. Schema della doppia interazione
schema della doppia interazione

Dalla figura si evince che: alla pressione del bottone da parte dell'utente viene invocata la funzionalità implementata dall'Action object (attraverso un ActionEvent) e, parallelamente, per ogni modifica di una proprietà dell'Action corrisponde lo scatenarsi di un PropertyChangeEvent verso il componente grafico.

La Classe AbstractAction

La libreria Java Swing mette a disposizione una classe di utilità che fornisce un'implementazione astratta dell'interfaccia Action. La classe AbstractAction, infatti, fornisce la funzionalità di default per quasi tutti i metodi definiti nell'interfaccia Action.

È possibile estendere tali implementazioni creando delle classi che ereditino da AbstractAction ed effettuando l'overriding dei metodi. Quasi sempre, però, l'unico metodo per il quale è necessario fornire un'implementazione è actionPerformed(). Al suo interno sarà necessario scrivere il codice per gestire la funzionalità che l'azione dovrà svolgere. Vediamo un semplice esempio:

Listato 1. Crea un interfaccia e gestisce la funzionalità che l'azione svolge (vedi il codice completo)

..//
        //Crea una JMenuBar
        menuBar = new JMenuBar();
        menuBar.setBorder(new BevelBorder(BevelBorder.RAISED));
        
        // Crea un JMenu e lo aggiunge alla JMenuBar precedente
        JMenu menu = new JMenu("Menu");
        menuBar.add(menu);
..//
    class OpenAction extends AbstractAction{
        public OpenAction (String text, Icon icon){
            super(text,icon);      
        }
      
        // Implementazione del metodo actionPerformed() che gestisce
        // la funzionalità propria dell'action object
        public void actionPerformed(ActionEvent e){
            System.out.println("Eseguita una Action di
       tipo "" + e.getActionCommand() + """);
        }
    }
..//

Se si esegue il codice visto nella pagina precedente, verrà visualizzata la finestra seguente:

Figura 2. Interfaccia creata nell'esempio precedente
Interfaccia creata nell'esempio precedente

Se si preme il bottone Apri sulla Toolbar o si seleziona la voce di menù Apri, verrà stampata sulla console la seguente stringa:

Eseguita una Action di tipo "Apri"

Che è esattamente ciò che è stato definito all'interno del metodo actionPerformed() dell'action object referenziato dalla variabile openAction.

Si noti come sia il bottone della toolbar che l'elemento del menù contengano la dicitura "Apri", la quale corrisponde esattamente alla descrizione fornita in fase di costruzione dell'action object.

Se si aggiunge adesso la riga di codice evidenziata in rosso, nel costruttore della classe ActionSample:

OpenAction openAction = new OpenAction("Apri",
                new ImageIcon("open.gif"));
openAction.setEnabled(false);
    
// Crea un JButton da aggiungere alla toolbar
JButton openButton = new JButton();

Rieseguendo l'applicazione si potrà osservare che sia il bottone della toolbar, sia la voce di menu sono disabilitate:

Figura 3. Interfaccia con il bottone e la voce del menù disabilitati
Interfaccia con il bottone e la voce del menù disabilitati

Dimostrando, in tal modo, che una variazione di una proprietà dell'oggetto di tipo Action ha effetto su tutti i componenti grafici che interagiscono con esso.

Dimostrando, in tal modo, che una variazione di una proprietà dell'oggetto di tipo Action ha effetto su tutti i componenti grafici che interagiscono con esso.

Ti consigliamo anche