La classe Runnable

 

Creazione di una finesta:

 

Classe: FinestraDemo

 1 package finestrademo;
 2 
 3 import javax.swing.*;
 4 
 5 public class FinestraDemo {
 6     public static void main(String[] args) {
 7         // Crea una finestra JFrame
 8         JFrame finestra = new JFrame("La mia prima finestra");
 9 
10         // Imposta le dimensioni della finestra
11         finestra.setSize(400, 300);
12 
13         // Imposta l'operazione di chiusura predefinita
14         finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15 
16         // Mostra la finestra
17         finestra.setVisible(true);
18     }
19 }

 

In questo esempio:

  • Abbiamo creato una finestra utilizzando JFrame.
  • Abbiamo impostato il titolo della finestra con "La mia prima finestra".
  • Abbiamo specificato le dimensioni della finestra con setSize(400, 300).
  • Abbiamo impostato l’operazione di chiusura predefinita
    con setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE).
  • Infine, abbiamo reso la finestra visibile con setVisible(true).

Però questo approccio ha un difetto che se ci sono delle operazioni che potrebbero richiedere del tempo per essere eseguite come delle operazioni di I/O per scaricare dei file o delle interfacce grafiche molto complesse queste essendo eseguite in un unico thread, lo stesso, bloccherebbero il tutto fino a che le operazioni non sono terminate, l’interfaccia utente deve rimanere reattiva per rispondere agli input dell’utente.

Invece con il metodo che segue l'interfaccia grafica viene eseguita in un'altro thread e quindi non si blocca nulla

  1. Interfaccia Runnable:

    • L’interfaccia Runnable è parte del multithreading in Java.
    • Viene utilizzata per eseguire operazioni in un thread separato.
    • È particolarmente utile quando si lavora con operazioni che potrebbero bloccare il thread principale (come le operazioni di I/O o le interfacce grafiche).
  2. Interfaccia Grafica (Swing):

    • Quando crei interfacce grafiche (finestre, pulsanti, etichette, ecc.), è importante non bloccare il thread dell’interfaccia utente (UI thread).
    • L’interfaccia utente deve rimanere reattiva per rispondere agli input dell’utente.
    • Pertanto, è comune utilizzare l’interfaccia Runnable per eseguire operazioni di interfaccia grafica in un thread separato.

Qui abbiamo tutto in un unica classe:

 

Classe: FinestraConComponentiRunnable

 1 package finestraconcomponentirunnable;
 2 
 3 import javax.swing.*;
 4 
 5 public class FinestraConComponentiRunnable {
 6     public static void main(String[] args) {
 7         SwingUtilities.invokeLater(new Runnable() {
 8             @Override
 9             public void run() {
10                 JFrame finestra = new JFrame("Finestra con Componenti e Runnable");
11                 finestra.setSize(400, 300);
12                 finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
13 
14                 JButton pulsante = new JButton("Clicca qui!");
15                 finestra.add(pulsante);
16 
17                 finestra.setVisible(true);
18             }
19         });
20     }
21 }

 

Qui in due classi separate una princilale con metodo main e l'altra con le impostazioni da eseguire:

 

Classe: ImgControlDemo

 1 package imgcontroldemo;
 2 
 3 import javax.swing.*;
 4 
 5 public class ImgControlDemo {
 6     public static void main(String[] args) {
 7         SwingUtilities.invokeLater(new Runnable() {
 8             @Override
 9             public void run() {
10                 new ImgControl();
11             }
12         });
13     }
14 }
15 
16 class ImgControl {
17     public ImgControl() {
18         JFrame finestra = new JFrame("Finestra con Componenti e Runnable");
19         finestra.setSize(400, 300);
20         finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21 
22         JButton pulsante = new JButton("Clicca qui!");
23         finestra.add(pulsante);
24 
25         finestra.setVisible(true);
26     }
27 }

 

Le osservazioni da fare sono:

 

SwingUtilities.invokeLater

  • Utilizzo: Viene utilizzato per assicurare che un’azione venga eseguita sul thread di gestione eventi (EDT) di Swing.
  • Scopo: Serve a prevenire problemi di concorrenza e a garantire che l’interfaccia utente sia aggiornata in modo sicuro e coerente.
  • Esempio: Se vuoi aggiornare la GUI da un thread diverso, dovresti usare SwingUtilities.invokeLater per mettere il tuo codice di aggiornamento nella coda degli eventi di Swing.
  • Funzionamento: Il metodo accetta un oggetto Runnable che contiene il codice che deve essere eseguito dall’EDT. Quando viene invocato, il codice viene messo in coda e eseguito quando l’EDT è pronto.

Questo metodo è fondamentale per la programmazione di interfacce utente in Java Swing per mantenere l’applicazione reattiva e stabile.

 

L'oggetto Runnabile viene istanziato dalla classe Runnable che è una classe che implementa l'interfaccia Runnable. Questa interfaccia possiede un solo metodo run. Con "new Rannable()" noi creiamo un oggetto senza dargli un nome infatti stiamo utilizzando una classe anonima. Ora dobbiamo sovrascrivere il metodo run (osservare lo specificatore: @Override). nel corpo del quale andremo a metttere tutto ciò che vogliamo che debba essere eseguito.