Worin bestehen die Hauptunterschiede der drei in Swing definierten Fenstertypen?

Die Swing-Bibliothek stellt drei von java.awt.Container und ihrer Unterklasse java.awt.Window abgeleitete Fenstertypen zur Verfügung, deren wichtigste Gemeinsamkeiten und Unterschiede hier dargestellt werden.

Das Beispiel zeigt eine einfache Einstiegsklasse mit ihrer main()-Methode, in der jeweils ein Objekt von einer Klasse erstellt wird:

JFrame
Ein nicht-modales1 Fenster, das in der Standardeinstellung eine Fensterleiste mit der betriebssystem-typischen Funktionalität besitzt. Mit diesem Typ werden üblicherweise Hauptfenster eines Desktop-Programmes erstellt.
JWindow
Ein ebenfalls nicht-modales1 Fenster, das jedoch keine Fensterleiste besitzt. Es ist gut geeignet für Fenster (z.B. Splash-Screens), die durch andere Programmteile geschlossen werden.
JDialog
Ein ebenfalls in der Standard-Einstellung nicht-modales1 Fenster, das eine Fensterleiste besitzt. Es ist der Hauptfenstertyp zur Erstellung von Dialogen.

Alle drei Fenster werden unmittelbar nacheinander geöffnet und ihre Größe auf 300 x 300 Pixel gesetzt. Sie enthalten alle ein einfaches JLabel mit dem Text des jeweiligen Fenstertypus, das standardmäßig linksbündig in die Fenstermitte gesetzt wird. Die Fenster müssen durch die Methode setVisible() explizit sichbar gemacht werden.

Zwei Gemeinsamkeiten seien hier erwähnt, die dem Beispiel nicht direkt entnommen werden können:

JFrame

Die ursprünglich gesetzte Größe des Fensters von 300 x 300 Pixel wird im Beispiel überschrieben, indem das Fenster durch die Methode setExtendedState() vertikal und horizontal maximiert, also auf Bildschirmgröße gesetzt wird. Die Methode ist in java.awt.Frame deklariert, von dem JFrame direkt abgeleitet ist. Sie steht somit den beiden anderen Klassen nicht zur Verfügung.

Dem gegenüber kann allen drei Fenstertypen jedoch eine Referenz auf ein weiteres Fenster übergeben werden, in dessen Mitte es erscheinen soll. Dies geschieht durch die Methode setLocationRelativeTo(). Wird, wie hier demonstriert, statt dessen null als Parameter gesetzt, so wird das jeweilige Fenster mittig auf dem Bildschirm dargestellt. Für die Übergabe einer Referenz muss der Entwickler allerdings ggfs. selber sorgen, z.B. mit SwingUtilities.getWindowAncestor(), o.ä. JFrame selbst stellt hierzu keinen entsprechenden Konstruktor bereit.

Die Fensterleiste des JFrame kann durch Übergabe von true an die Methode setUndecorated() entfernt werden. Doch Vorsicht! Ein Schließen des Fensters ist dann über die Leiste natürlich nicht mehr möglich.

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;

public class FensterTypen {

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

class FrameFenster {
    public FrameFenster() {
        JFrame frame = new JFrame("JFrame-Fenster");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLocationRelativeTo(null);
        frame.add(new JLabel("JFrame-Fenster"));
        frame.setVisible(true);
    }
}

class WindowFenster {
    public WindowFenster() {
        JWindow window = new JWindow();
        window.setSize(300, 300);
        window.setLocation(100, 100);
        window.add(new JLabel("JWindow-Fenster"));
        window.setVisible(true);
    }
}

class DialogFenster {
    public DialogFenster() {
        JDialog dialog = new JDialog();
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setSize(300, 300);
        dialog.setLocation(300, 200);
        dialog.setTitle("JDialog-Fenster");
        dialog.add(new JLabel("JDialog-Fenster"));
        dialog.setVisible(true);
    }
}

JWindow

JWindow verhält sich ähnlich wie JFrame, besitzt jedoch keine Fensterleiste vergleichbar einem undecorated gesetzten JFrame und kann somit natürlich auch keinen Titel anzeigen, über einen Button an der Leiste minimiert oder geschlossen werden, etc. Die Manövrierung des Fensters (Verschieben, Schließen, etc.) muss somit auch vom Entwickler selbst implementiert werden.

JDialog

Wie der Name bereits nahelegt dient die Klasse im Wesentlichen zur Erzeugung von Dialogen. Sie ist einem JFrame auf den ersten Blick in ihrer Erscheinung recht ähnlich, stellt jedoch ein gutes Dutzend überladener Konstruktoren bereit, denen ein owner übergeben werden kann. Dies ist eine Komponente, die den Dialog aussendet, dessen Dialogergebnis empfangen kann oder zu der der Dialog relativ positioniert werden kann. Der Modalitätsstatus1 des Dialoges kann durch setModal() explizit gesetzt werden.

1) Ein modales Fenster ist ein Fenster, das den Zugriff auf andere geöffneten Fenster des gleichen Programms verhindert, solange es selbst geöffnet ist. Modale Fenster sind dann von Bedeutung, wenn durch sie der Programmlauf zwingend gesteuert werden muss (z.B. Sicherheitsabfragen, Warnmeldungen, o.ä.).

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.