13.02.01 JFrame und JDialog

Im Einführungskapitel zu Oberflächen in Java haben Sie bereits ein Fenster mit der Swing-Bibliothek erstellt. In diesem Kapitel lernen Sie weitere Funktionen des JFrames kennen und werden auch etwas über seinen Bruder, den JDialog erfahren. Da Fenster von Java-Programmierern gerne Frames genannt werden, werde ich sie im folgenden auch so nennen.

Einen JFrame erzeugen

Der JFrame verfügt über vier Konstruktoren, zwei von ihnen werden wir ein diesem Kapitel behandeln. Zum einen den parameterlosen Konstruktor, der einfach einen Frame erzeugt, und den Konstruktor JFrame(String title), welcher dem Frame auch gleich einen Titel zuweist.
Beide Konstruktoren geben dem Frame aber unter anderem keine Größe und keine Position auf dem Bilschirm mit auf den Weg. Das heißt, wir müssen, nachdem wir den Frame erzeugt haben, erst diese Attribute ergänzen, sonst wird der Frame in der oberen, linken Bildschirmecke mit der theoretischen Größe von 0 x 0 Pixel erscheinen. Theoretisch deswegen, weil, je nach dem auf welchem Betriebsystem man arbeitet, dem Frame noch Ränder hinzugefügt werden, weswegen man ihn doch sehen kann. Die Framegröße wird mit der Funktion setSize(int width, int height) oder setSize(Dimension d)festgelegt, die Position wird mit der Funktion setLocation(int x, int y) oder setLocation(Point p) zugewiesen. Diese zwei wichtigen Attribute kann man aber auch auf einmal setzen, mit der Methode setBounds(int x, int y, int width, int height) oder setBounds(Rectangle r).
Außerdem müssen wir meist noch selbst Hand anlegen, wenn es um das Schließen eines Fensters geht. Standardmäßig macht sich ein Frame beim Klicken auf das Kreuz in der oberen rechten Fensterecke nur unsichtbar, die Anwendung läuft im Hintergrund aber weiter und kann nur durch einen Taskmamager beendet werden. Wir haben folgende, vorgefertigte Optionen beim Schließen eines Fensters:

  • JFrame.HIDE_ON_CLOSE: Macht den Frame unsichtbar sobald auf das Kreuz geklickt wurde, er läuft aber im Hintergrund weiter. Voreingestellt.
  • JFrame.DO_NOTHING_ON_CLOSE: Beim Klicken auf das Kreuz eines Frames passiert nichts.
  • JFrame.EXIT_ON_CLOSE: Beendet die gesamte Anwendung.
  • JFrame.DISPOSE_ON_CLOSE: Zerstört den Frame. Wenn die der letzte Frame der Anwendung war, und auch sonst kein anderer Thread läuft, dann wird auch die Virtual Machine beendet.

Diese Optionen werden schließlich mit der Funktion setDefaultCloseOperation(int operation) gesetzt.

Nun aber genug Theorie, wollen wir mal einen Frame mit der Größe 300*400 an der Position 400, 400 erzeugen:

package de.jbb.jframes;

import javax.swing.JFrame;

public class Main{

  public static void main(String args[]){

    JFrame myFrame = new JFrame("Mein Frame"); //Erzeugen eines Frames mit Titel
    myFrame.setBounds(400,400,300,400); //Position des Frames: 400, 400, Größe 300*400
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Beim Schließen des Fensters wird die Anwendung beendet.
    myFrame.setVisible(true); //Frame sichtbar machen.
  }
}

Mit setVisible(false) lässt sich der Frame wieder unsichtbar machen. Seine Einstellungen bleiben aber gespeichert, er wird nicht den Garbage Collector übergeben. Wenn Sie ihn zu einem spätern Zeitpunkt wieder sichtbar machen, hat er immer noch die gleichen Maße und Inhalte, wenn Sie dazwischen nichts an den Maßen oder dem Inhalt geändert haben.

Einen Frame zentriert anzeigen

Oft ist es schöner, wenn ein Fenster zentriert auf dem Bildschirm erscheint. Dazu kann man sich die Formel xKoordinate = Bildschirmbreite / 2 - Fensterbreite/2 ermitteln. Sie sollten hier aber nicht statisch ihre Bildschirmmaße verwenden, da der Frame dann auf anderen Bildschirmen alles andere als in der Mitte erscheint. Der User wird es Ihnen danken. Eine andere Möglichkeit ist, den User einmalig nach seiner Auflösung zu fragen. Aber haben Sie das jemals in einem Programm gesehen?
Auch hier macht es mal wieder die Kombination: Wir verwenden obige Formel, setzen die Auflösung des Users ein, aber ohne ihn danach zu fragen, denn die Auflösung lässt sich einfach mit dem Toolkit ermitteln (Vergessen sie nicht, das Toolkit aus java.awt.Toolkit zu importieren):

public static void main(String args[]){

  JFrame centeredFrame = new JFrame("Zentrierter Frame");
  centeredFrame.setSize(300,210);
  int xKoordinate = Toolkit.getDefaultToolkit().getScreenSize.getWidth() / 2 - centeredFrame.getWidth() / 2;
  int yKoordinate = Toolkit.getDefaultToolkit().getScreenSize.getHeight() / 2 - centeredFrame.getHeight() / 2;
  centeredFrame.setLocation(xKoordinate, yKoordinate);

  centeredFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  centeredFrame.setVisible(true);
}

Oder noch ein bisschen einfacher:

public static void main(String args[]){

  JFrame centeredFrame = new JFrame("Zentrierter Frame");
  centeredFrame.setSize(300,210);
  centeredFrame.setLocationRelativeTo(null);

  centeredFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  centeredFrame.setVisible(true);
}

Die Methode setLocationRelativeTo(Component c) richtet das Frame an einer bestimmten Java Componente aus (wie bspw. einem anderen Fenster, einem Button oder eben dem Bildschirm, wenn null übergeben wird). Achtung! Es kommt hier auf die Reihenfolge der Anweisungen im Code an. Zuerst muss immer die Größe des JFrames oder des JDialogs gesetzt werden, erst danach darf dann die Methode setLocationRelativeTo(Component c) aufgerufen werden. Vertauscht man die Reihenfolge der Anweisungen, wird die Fenster-Komponente nicht richtig ausgerichtet.

Setzen eines Icons

Wenn Sie in die Menüleiste Ihres Browsers schauen, dann sehen Sie wahrscheinlich, dass links in der Ecke das Icon des Browsers zu finden ist. So ein Icon lässt sich natürlich auch in einem JFrame setzen. Wenn Sie kein Icon setzen, wird das Java-Icon verwendet, doch es bietet sich an, zur Verbesserung der Wiedererkennung Ihres Programmes ein Icon zu entwerfen und zu setzen. Auf die Gestaltung werden wir hier nicht eingehen, sondern nur auf das Setzen eines schon vorhandenen Icons.

Icons, die im JFrame gesetzt wurden, werden auch in der Taskleiste angezeigt.

Um das Icon zu setzen, müssen wir einfach die Methode setIconImage(Image image) aufrufen:

JFrame frame = new JFrame("Frame mit Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100,100,500,500);
ImageIcon icon = new ImageIcon("/pfad/zu/meinem/Icon.png"); // ImageIcon liegt im Packet javax.swing.
frame.setIconImage(icon.getImage());
frame.setVisible(true);

Java nimmt alle Standard-Bildformate an. Die Icons sollten aber in der Größe 16×16 oder 32×32 sein.

Den JFrame mit Hintergrundfarben versehen

Natürlich kann man auch die Hintergrundfarbe eines Frames ändern. Dies sollte allerdings mit vorsicht genossen werden, da viele Benutzer möchten, dass alles in Ihrem Betriebssystem zusammen passt. Um die Hintergrundfarbe zu ändern, müssen wir die Methodenreihe JFrame.getContentPane().setBackground(Color c) aufrufen. Die Klasse Colorkommt aus dem Paket java.awt:

JFrame myFrame = new JFrame("Frame mit blauer Hintergrundfarbe");
myFrame.getContentPane().setBackground(Color.BLUE);

Die zusätzliche Methode getContentPane() kommt daher, dass der eigentlich sichbare Bereich des Frames aus dem Rahmen und dem Komponentenbereich besteht. Dieser Komponentenbereich wird als contentPane bezeichnet.

Dialoge mit JDialog

Dialoge unterscheiden sich von normalen Frames im Grunde nur dadurch, dass das Hauptfenster eines Programmes deaktiviert ist, solange der Dialog offen ist. Ein Beispiel hierfür ist der „Speichern unter“-Dialog in fast jedem Programm. Wenn sich der Dialog so verhält, dann verhält er sich modal. Konkret heißt das, dass der Code nach der Zeile setVisible(true) nicht weiter ausgeführt wird, bis der JDialog geschlossen wird. Außerdem werden Dialoge nicht in der Taskleiste angezeigt. Ein Dialog wird in Java durch die Klasse JDialog im Paket jawax.swing repräsentiert.
Der Standardkonstruktor von JDialog lautet JDialog(). Dann verhält er sich wie ein JFrame, nur das er nicht in der Taskleiste gezeigt wird.

Die weiteren Konstruktoren sind.

  • JDialog(JFrame owner): Owner bezeichnet den Frame, aus dem der Dialog aufgerufen wird. Unter anderem bewirkt das, dass das der Dialog genau über dem übergebenen Fenster erscheint.
  • JDialog(JFrame owner, String title): Setzt zusätzlich den Titel des Dialoges.
  • JDialog(JFrame owner, String titel, boolean modal): Setzt auch noch die Modalität des Dialoges

Es gibt noch mehr von diesen Konstruktoren, die sich allerdings nur dadurch von den hier aufgelisteten unterscheiden, indem sie keinen JFrame als Besitzer anehmen, sondern entweder einen anderen JDialog, oder ein Window. Dies ist die Mutterklasse aller Fensterklassen von Swing und AWT.
Es lassen sich natürlich auch Eigenschaften über Setter-Methoden ändern (z. B. setModal(boolean modal) und über Getter-Methoden ermitteln (z. B. isModal()).
Wenn Sie kein Besitzer-Fenster angeben wollen, die anderen beiden Eigenschaften aber über den Konstruktor setzen wollen, müssen Sie sich mit einem Trick behelfen. Naheliegend wäre in diesem Fall, einfach den Konstruktor mit JDialog(null, "Dialog", true) aufzurufen. Dies wird aber einen Fehler liefern, weil der Compiler in diesem Fall nicht weiß, welchen Konstruktor Sie meinen. Es kommen ja immerhin drei infrage. Deshalb müssen Sie dem Compiler sagen welchen er aufrufen soll. Dazu casten (wandeln) wir dieses null einfach in ein JFrame, JDialog oder JWindow um. Hier noch ein Codebeispiel für das darstellen eines Dialoges ohne Besitzer-Fenster:

package de.jbb.jdialogs;

import javax.swing.JDialog;

public class main{
  
  public static void main(String[] args){
    
    JDialog dialog = new JDialog((JFrame)null, "Mein erster Dialog", true); // Erzeugt neuen modalen JDialog ohne Besitzer-Fenster
    dialog.setBounds(100,100,300,300);
    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dialog.setVisible(true); // Hier wird die Ausführung gestopt, bis der JDialog geschlossen wird
    
    System.out.println("JDialog geschlossen"); //Wird erst nach dem Schließen des Dialogs angezeigt
  }
}

Bis auf wenige Ausnahmen sind alle weiteren Methoden von JFrame und JDialog identisch.

Die Close-Operation EXIT_ON_CLOSE wird von JDialog nicht unterstützt.

Ausblick

In diesem Kapitel haben Sie die beiden wichtigsten Fensterklassen von Swing kennen gelernt. Im nächsten Kapitel werden Sie Ihre ersten Komponenten (z.B. Buttons, Textfelder) auf diese Komponenten setzen.

Previous Article
Next Article

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.