Tutorial JFileChooser in Java Swing

di  Antonio Coschignano, venerd́ 25 giugno 2010
Nell'implementazione di interfaccie grafiche definite tramite Java Swing spesso ci troviamo di fronte alla necessità di selezionare file o directory dal file system per leggere o scrivere dei dati su di esso. Nel package javax.swing viene fornito un supporto nativo per questa operazione tramite la classe javax.swing.JFileChooser che implementa un'interfaccia grafica per la navigazione del file system.

In base a ciò che vogliamo fare abbiamo a disposizione diverse modalità di accesso al file system tramite il JFileChooser. Possiamo implementare dei filtri per visualizzare solo alcuni tipi di file, oppure possiamo optare per la sola creazione di un file per scrivere flussi di dati al suo interno. Ma andiamo per gradi, vediamo una semplice selezione di un file e come ottenere un riferimento ad esso:
import javax.swing.JFileChooser;
...
public MyClass extends JPanel {
  ...
  JFileChooser fileChooser = new JFileChooser();
  int n = fileChooser.showOpenDialog(MyClass.this);
  ...
}
Questo, non fa altro che aprire la finestra di dialogo per selezionare un file:

Esempio JFileChooser

Il metodo showOpenDialog() è bloccante, nel senso che il flusso del programma si interrompe fino a quanto non viene selezionato il file. Il metodo ritorna un'intero che può assumere uno dei seguenti valori:
  • JFileChooser.CANCEL_OPTION: abbiamo selezionato il tasto Annulla
  • JFileChooser.APPROVE_OPTION: abbiamo selezionato il tasto Apri
  • JFileCHooser.ERROR_OPTION: si è verificato un errore
Inoltre sono definiti altri metodi per personalizzare alcuni parametri della finestra di dialogo come setApproveButtonText(String str) che imposta la stringa da visualizzare nel pulsante di approvazione e setDialogTitle(String dialogTitle) che invece imposta il titolo della finestra di dialogo.

Leggere e scrivere sul file selezionato

Una volta che abbiamo selezionato un file, per ottenere un riferimento ad esso utilizziamo il metodo getSelectedFile():
import java.io.File;
...
File f = fileChooser.getSelectedFile();
oppure se abbiamo selezionato più file, possiamo utilizzare getSelectedFiles(), che ritorna un array di File:
File [] files = fileChooser.getSelectedFiles();
Quindi ottenuto un oggetto di tipo java.io.File, abbiamo tutto quello che ci serve, siamo liberi di leggere e scrivere dati attraverso i normali stream di java. Ad esempio per scrivere possiamo utilizzare un DataOutputStream/FileOutputStream:
File f = fileChooser.getSelectedFile();
DataOutputStream outStream = new DataOutputStream(new FileOutputStream(f));
...
oppure per leggere utilizziamo DataInputStream/FileInputStream:
File f = fileChooser.getSelectedFile();
DataInputStream inStream = new DataInputStream(new FileInputStream(f));
...
Un'altro caso importante riguarda il tentativo si salvare dei dati su un file che non esiste nel file system e che quindi digitiamo nella casella accanto a Nome file. In questo caso si usa il metodo showSaveDialog() che invece del pulsante Apri visualizza il pulsaante Salva.

Definizione di un filtro (FileFilter)

Definire un filtro significa specificare al JFileChooser il tipo (o tipi) di file che vogliamo vengano visualizzati nella finestra di dialogo. Ad esempio se desideriamo visualizzare solo file di tipo testo quindi con estensione .txt oppure solo directory, o ancora possiamo specificare un insieme di estensioni che riguardano file multimediali .mp3, wav etc.

Per questa operazione si usa un'implementazione della classe astratta javax.swing.filechooser.FileFilter. Questa classe definisce il metodo accept() che riceve come argomento un oggetto di tipo File e ritorna un valore boolean e il metodo getDescription() che ritorna una stringa che viene visualizzata nel campo 'Tipo File' del file chooser. Una volta implementata l'interfaccia si usa il metodo setFileFilter() della classe JFileChooser per impostare il tipo di filtro che abbiamo definito. Per essere più chiari definiamo un nostro filtro per soli file di testo quindi con estensione .txt:
import javax.swing.filechooser.FileFilter;

class TxtFileFilter extends FileFilter {

  public boolean accept(File file) {
    if (file.isDirectory()) return true;
    String fname = file.getName().toLowerCase();
    return fname.endsWith("txt");
  }

  public String getDescription() {
    return "File di testo";
  }
}
Nel metodo accept() estrapoliamo semplicemnte l'estensione del file e verifichiamo che sia .txt. Quindi ritorniamo true anche nel caso esso sia una directory. Questo metodo da come si può intuire viene richiamato internamente dal JFileChooser quando visualizza i file di un determinato percorso del file system, e quindi visualizza solo gli elementi per cui il metodo accept() ritorna true. Per installarlo nel file chooser basta utilizzare il metodo setFileFilter() in questo modo:
...
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new TxtFileFilter());
...

Esempio JFileChooser

Per concludere con questo tutorial propongo un esempio completo sull'utilizzo del JFileChooser. L'esempio mostra un semplice editor di testo dove è possibile visualizzare, modificare o creare file txt. Naturalmente la selezione del file avviene tramite il file chooser dove viene applicato il FileFilter che abbiamo definito sopra. L'interfaccia grafica dell'editor è costruita facendo uso di una JTextArea e altri componenti Swing come JButton, JFrame e JPanel. Il codice sottostante è completo, quindi - per testarlo - potete copiarlo ed incollarlo direttamente nel vostro editor java :
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.filechooser.FileFilter;

public class JFileChooserDemo extends JPanel {

  private JTextArea textArea;

  public JFileChooserDemo() {
    super(new BorderLayout());
    createPanel();
  }

  private void createPanel() {
    JButton openFileChooser = new JButton("Apri File");
    JButton saveFileChooser = new JButton("Salva File");
    openFileChooser.addActionListener(new OpenFileChooser());
    saveFileChooser.addActionListener(new SaveFileChooser());
    textArea = new JTextArea(10, 20);
    add(new JScrollPane(textArea), BorderLayout.CENTER);
    JPanel panelButton = new JPanel();
    panelButton.add(openFileChooser);
    panelButton.add(saveFileChooser);
    add(panelButton, BorderLayout.SOUTH);
  }

  private class OpenFileChooser implements ActionListener {

    public void actionPerformed(ActionEvent e) {
      try {
        textArea.setText("");
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new TxtFileFilter());
        int n = fileChooser.showOpenDialog(JFileChooserDemo.this);
        if (n == JFileChooser.APPROVE_OPTION) {
          File f = fileChooser.getSelectedFile();
          BufferedReader read = new BufferedReader(new FileReader(f));
          String line = read.readLine();
          while(line != null) {
            textArea.append(line);
            line = read.readLine();
          }
          read.close();
        }
      } catch (Exception ex) {}
    }
  }

  private class SaveFileChooser implements ActionListener {

    public void actionPerformed(ActionEvent e) {
      try {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new TxtFileFilter());
        int n = fileChooser.showSaveDialog(JFileChooserDemo.this);
        if (n == JFileChooser.APPROVE_OPTION) {
          File f = fileChooser.getSelectedFile();
          BufferedWriter write = new BufferedWriter(new FileWriter(f));
          write.append(textArea.getText());
          write.flush();
          write.close();
        }
      } catch (Exception ex) {}
    }
  }

  private class TxtFileFilter extends FileFilter {

    public boolean accept(File file) {
      if (file.isDirectory()) return true;
        String fname = file.getName().toLowerCase();
        return fname.endsWith("txt");
    }

    public String getDescription() {
      return "File di testo";
    }
  }

  public static void main(String[] argv) {
    JFrame frame = new JFrame("JFileChooserDemo");
    JFileChooserDemo demo = new JFileChooserDemo();
    frame.getContentPane().add(demo);
    frame.pack();
    frame.setVisible(true);
  }
}
Altri link che potrebbero interessarti
  • » Una lista concatenata in java
  • » La gestione delle Stringhe in java
  • » La gestione degli eventi in java Swing
  • » La classe Collections
  • » Java Generics
  • » Gestire la System Tray in Java
  • » Gestire la clipboard in Java Swing
  • » Connessioni HTTP in Java