Wie lässt sich ein einfacher Speichern unter...-Dialog realisieren? v.1.61

Java stellt mit seiner Klasse JFileChooser einen einfach zu handhabenden Dialog bereit, mit dem auf die bekannte Art und Weise Dateien gespeichert werden können.

Das Beispiel deklariert in init() einen JFrame mit einem Button, der auf Klick einen Speichern-Dialog öffnet. Nach Auswahl des gewünschten Verzeichnisses und Eingabe des Dateinamens wird dieser mit einer Nachricht auf die Konsole ausgegeben. Die Nachricht gibt an, ob der (fiktive) Dateityp zulässig ist oder nicht.

Im ActionListener des Buttons wird die Methode saveAs() aufgerufen. Als Parameter wird als Pfad zum Speicherverzeichnis null übergeben, was bewirkt, dass das Heimatverzeichnis des Users beim Öffnen des Dialoges angezeigt wird. Selbstverständlich kann hier jeder bliebige Pfad eingesetzt werden. Ist der übergebene Pfad ungültig, so wird ebenfalls der Heimatpfad des Users verwendet.
In der Methodendeklaration wird als erstes ein Objekt eines JFileChooser erzeugt, dem der o.a. Pfad übergeben wird. Als nächstes wird der Typ des gewünschen Datei-Auswahl-Dialogs festgelegt. Hier kann zwischen den statischen int-Werten OPEN_DIALOG und SAVE_DIALOG gewählt werden. Die folgenden Zeilen demonstrieren die Anwendung von zwei FileNameExtensionFilter . Die Klasse wurde erst in der Java-Version 1.6 eingeführt. Soll das Beispiel mit einer älteren Java-Version kompatibel sein, muss diese Passage einschließlich der if-Verzweigung zur Ausgabe weiter unten entfernt oder auskommentiert werden.
Der Konstruktor des Filters demonstriert die Syntax einer variablen Parameterzahl: Er erwartet eine beliebige Reihe von String-Werten, von denen der erste den Text der Dateityp-Auswahl des Dialoges darstellt. Die folgenden müssen Datei-Extensionen entsprechen, die die erlaubten Ziel-Dateitypen kennzeichnen. Nachdem wahlweise durch den Aufruf von removeChoosableFileFilter(chooser.getAcceptAllFileFilter()) der Eintrag Alle Dateien entfernt wurde, werden die neu erzeugten Filter mit dem Dialog verknüpft. Mit dem Setzen eines Titels und der Sichtbarschaltung ist die Konstruktion des Dialogs abgeschlossen.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

public class SpeichernUnterClass {

    public SpeichernUnterClass() {
        init();
    }
    
    private void init() {
        JFrame frame = new JFrame("Speichern unter Demo");
        JButton butt = new JButton("Speichern unter...");
        butt.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                saveAs(frame, null);
            }
        });
        frame.add(butt, BorderLayout.SOUTH);
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    boolean saveAs(Component c, String pfad) {

        JFileChooser chooser;
        if (pfad == null)
            pfad = System.getProperty("user.home");
        File file = new File(pfad.trim());

        chooser = new JFileChooser(pfad);
        chooser.setDialogType(JFileChooser.SAVE_DIALOG);
        FileNameExtensionFilter plainFilter = new FileNameExtensionFilter(
                "Plaintext: txt, csv", "txt", "csv");
        FileNameExtensionFilter markUpFilter = new FileNameExtensionFilter(
                "Markup: xml, htm, html", "xml", "html", "htm");
        chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());
        chooser.setFileFilter(plainFilter);
        chooser.setFileFilter(markUpFilter);
        chooser.setDialogTitle("Speichern unter...");
        chooser.setVisible(true);

        // Speichern-Dialog anzeigen
        int result = chooser.showSaveDialog(c);

        // wenn 'speichern' nicht 'abbrechen' gewählt wurde
        if (result == JFileChooser.APPROVE_OPTION) {

            pfad = chooser.getSelectedFile().toString();
            file = new File(pfad);
            if (plainFilter.accept(file) || markUpFilter.accept(file))
                System.out.println(pfad + " kann gespeichert werden.");
            else
                System.out.println(pfad + " ist der falsche Dateityp.");

            chooser.setVisible(false);
            return true;
        }
        chooser.setVisible(false);
        return false;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new SpeichernUnterClass());
    }
}

Die im Quelltext folgenden Zeilen regeln das Verhalten des Dialogs: Bei Betätigen eines Buttons liefert der Dialog einen int-Wert. Je nach betätigtem Button werden unterschiedliche Werte zurück gegeben, für die eigene Reaktionen definiert werden können.
Der in JFileChooser.APPROVE_OPTION gespeicherte Wert repräsentiert die Rückgabe des betätigten OK-Buttons. Hier muss das Abspeichern einer Datei implementiert werden. Zur Demonstration werden an dieser Stelle nur die oben bereits erwähnten Texte ausgegeben. Bevor dies geschehen kann, wird der in den Dialog eingegebene Dateiname nach Bilden von entsprechenden File-Objekten gegen die Filefilter geprüft.
Schließlich wird der Dialog unsichtbar gesetzt und - je nach betätigtem Button - true bei Erfolg oder false zurück gegeben.

1) Die Verwendung der Klasse javax.swing.filechooser.FileNameExtensionFilter verlangt Java 1.6.