Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage |
<< | < | > | >> | API | Kapitel 37 - Swing: Container und Menüs |
Die Klasse JFrame ist die wichtigste Hauptfensterklasse in Swing. Sie ist aus java.awt.Frame abgeleitet und stellt ein Hauptfenster mit Rahmen, Systemmenü und Standardschaltflächen zur Verfügung. Ein JFrame kann ebenso einfach instanziert werden wie ein Frame:
public JFrame() public JFrame(String title) |
javax.swing.JFrame |
Der parameterlose Konstruktor erzeugt ein Hauptfenster mit einer leeren Titelzeile, der andere schreibt den übergebenen String hinein. Da JFrame aus Frame abgeleitet ist, stehen alle Methoden aus Window, Container und Component zur Verfügung. Ein einfaches Beispielprogramm mit einem leeren Hauptfenster, das sich über den Schließen-Button beenden lässt, können wir (analog zu den Beispielen in Kapitel 31) wie folgt realisieren:
001 /* Listing3701.java */ 002 003 import javax.swing.*; 004 import java.awt.event.*; 005 006 public class Listing3701 007 extends JFrame 008 { 009 public Listing3701() 010 { 011 super("Ein einfacher JFrame"); 012 addWindowListener( 013 new WindowClosingAdapter(true) 014 ); 015 } 016 017 public static void main(String[] args) 018 { 019 Listing3701 wnd = new Listing3701(); 020 wnd.setLocation(100, 100); 021 wnd.setSize(300, 200); 022 wnd.setVisible(true); 023 } 024 } |
Listing3701.java |
Das Programm erzeugt ein Hauptfenster der Größe 300 * 200 an der Bildschirmposition (100, 100). In der Titelzeile steht »Ein einfacher JFrame« und das Programm lässt sich durch einen Klick auf den Schließen-Button beenden:
Abbildung 37.1: Ein einfaches JFrame-Beispiel
Ein bedeutender Unterschied zwischen den AWT- und Swing-Hauptfenstern besteht in ihrer Komponentenstruktur und den sich daraus ergebenden Unterschieden in der Bedienung. Während die Komponenten eines AWT-Fensters direkt auf dem Fenster platziert werden, besitzt ein Swing-Hauptfenster eine einzige Hauptkomponente, die alle anderen Komponenten aufnimmt.
Diese Hauptkomponente wird als RootPane bezeichnet und ist vom Typ JRootPane. Sie übernimmt die Rolle einer Art Verwaltungsinstanz für alle anderen Komponenten des Hauptfensters. Eine RootPane enthält folgende Komponenten:
Die LayeredPane enthält ihrerseits zwei Unterkomponenten:
Damit ergibt sich folgende Struktur:
Abbildung 37.2: Die Struktur einer RootPane
LayeredPane und GlassPane liegen »übereinander« und füllen das Fenster jeweils komplett aus. Die GlassPane ist normalerweise durchsichtig und wird meist nicht zur Grafikausgabe benutzt. Sie könnte dann verwendet werden, wenn Effekte erzielt werden sollen, die das Fenster als Ganzes betreffen (und nicht seine einzelnen Dialogelemente). Eine (beispielsweise von JInternalFrame genutzte) Funktion besteht darin, Mausereignisse abzufangen, bevor sie an andere Komponenten weitergegeben werden.
Die LayeredPane enthält das Menü und die Dialogelemente der Anwendung. Als Instanz der Klasse JLayeredPane verfügt sie über die Fähigkeit, Dialogelemente nicht nur neben-, sondern in kontrollierter Weise auch übereinander anzuordnen. Das ist beispielsweise wichtig, um Menüs oder interne Dialoge über den Komponenten anzuzeigen, die sie verdecken. Tatsächlich verdeckt das in der LayeredPane gehaltene Menü die in seiner ContentPane platzierten Dialogelemente der Anwendung.
Das hört sich alles sehr kompliziert an und mancher wird sich fragen, ob so viel Aufwand wirklich nötig war. Glücklicherweise braucht eine Swing-Anwendung sich um die Details gar nicht zu kümmern. Einerseits wird die RootPane, und mit ihr die darin enthaltene GlassPane, LayeredPane und ContentPane, beim Anlegen des Fensters automatisch erzeugt (einzig die Menüleiste bleibt standardmäßig leer). Zweitens implementieren alle Hauptfenster das Interface RootPaneContainer, das den Zugriff auf die RootPane vereinfacht. Einige seiner Methoden sind:
public JRootPane getRootPane() public Container getContentPane() public JLayeredPane getLayeredPane() public Component getGlassPane() |
javax.swing.RootPaneContainer |
Um auf einem Hauptfenster Komponenten zu platzieren, ist es also nicht nötig, zunächst mit getRootPane die RootPane, dann mit getLayeredPane die LayeredPane und schließlich mit getContentPane die ContentPane zu beschaffen, sondern es kann direkt getContentPane aufgerufen werden. Neben den getter-Methoden gibt es auch setter-Methoden, mit denen der strukturelle Aufbau der RootPane vollständig verändert werden kann. Darauf wollen wir aber nicht weiter eingehen.
Das Einfügen und Anordnen von Dialogelementen auf einem Hauptfenster erfolgt also über dessen ContentPane. Die Aufrufe von add und setLayout werden damit nicht direkt auf dem Fenster ausgeführt, sondern auf dessen ContentPane, die über einen Aufruf von getContentPane beschafft werden kann.
Um das zu demonstrieren, wollen wir das vorige Beispiel um drei Buttons erweitern, die mit Hilfe eines GridLayout der Größe 3 * 1 angeordnet werden:
001 /* Listing3702.java */ 002 003 import javax.swing.*; 004 import java.awt.*; 005 import java.awt.event.*; 006 007 public class Listing3702 008 extends JFrame 009 { 010 public Listing3702() 011 { 012 super("Ein einfacher JFrame"); 013 //WindowListener hinzufügen 014 addWindowListener(new WindowClosingAdapter(true)); 015 //Layout setzen und Buttons hinzufügen 016 Container contentPane = getContentPane(); 017 contentPane.setLayout(new GridLayout(3, 1)); 018 contentPane.add(new JButton("Button 1")); 019 contentPane.add(new JButton("Button 2")); 020 contentPane.add(new JButton("Button 3")); 021 } 022 023 public static void main(String[] args) 024 { 025 Listing3702 wnd = new Listing3702(); 026 wnd.setLocation(100, 100); 027 wnd.setSize(300, 200); 028 wnd.setVisible(true); 029 } 030 } |
Listing3702.java |
Das Programm hat nun folgendes Aussehen:
Abbildung 37.3: Ein Hauptfenster mit Dialogelementen
Die zweite Hauptfensterklasse, die wir in diesem Kapitel vorstellen, ist JWindow. Sie ist aus Window abgeleitet und dient wie diese dazu, ein rahmenloses Fenster zu erzeugen, das an beliebiger Stelle und in beliebiger Größe auf dem Bildschirm platziert werden kann. JWindow besitzt drei Konstruktoren:
public JWindow() public JWindow(Frame owner) public JWindow(Window owner) |
javax.swing.JWindow |
Ebenso wie JFrame besitzt auch JWindow eine RootPane mit der im vorigen Abschnitt beschriebenen Struktur. Dialogelemente und Layoutmanager werden also nicht direkt auf dem Fenster, sondern auf der ContentPane platziert. Zur einfacheren Verwendung implementiert auch JWindow das Interface RootPaneContainer.
Als Beispiel für die Anwendung von JWindow wollen wir einen einfachen SplashScreen konstruieren, also ein Fenster, das nach dem Start eines Programms angezeigt wird und nach dessen Initialisierung wieder entfernt wird. Dazu leiten wir eine Klasse SplashScreen von JWindow ab und platzieren darin ein Icon und einen Text. Der Name der Icondatei und der Text können an den Konstruktor übergeben werden. Das Programm soll jeweils ein Drittel der verfügbaren Höhe und Breite des Bildschirms belegen und das Icon und den Text zentriert darin anzeigen.
001 /* SplashScreen.java */ 002 003 import javax.swing.*; 004 import javax.swing.border.*; 005 import java.awt.*; 006 007 public class SplashScreen 008 extends JWindow 009 { 010 public SplashScreen(String image, String text) 011 { 012 JPanel contentPane = new JPanel(); 013 contentPane.setLayout(new BorderLayout()); 014 Border bd1 = BorderFactory.createBevelBorder( 015 BevelBorder.RAISED 016 ); 017 Border bd2 = BorderFactory.createEtchedBorder(); 018 Border bd3 = BorderFactory.createCompoundBorder(bd1, bd2); 019 contentPane.setBorder(bd3); 020 ImageIcon icon = new ImageIcon(image); 021 contentPane.add(new JLabel(" ", JLabel.CENTER), BorderLayout.NORTH); 022 contentPane.add(new JLabel(icon, JLabel.CENTER), BorderLayout.CENTER); 023 contentPane.add(new JLabel(text, JLabel.CENTER), BorderLayout.SOUTH); 024 setContentPane(contentPane); 025 } 026 027 public void showFor(int millis) 028 { 029 Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 030 setLocation(dim.width / 3, dim.height / 3); 031 setSize(dim.width / 3, dim.height / 3); 032 setVisible(true); 033 try { 034 Thread.sleep(millis); 035 } catch (InterruptedException e) { 036 } 037 setVisible(false); 038 } 039 040 public static void main(String[] args) 041 { 042 SplashScreen intro = new SplashScreen( 043 "mine.gif", 044 "(C) Copyright 2000, J. Krüger, All Rights Reserved" 045 ); 046 intro.showFor(3000); 047 System.exit(0); 048 } 049 } |
SplashScreen.java |
Die Ausgabe des Programms sieht so aus:
Abbildung 37.4: Ein einfacher SplashScreen
Das Programm ist prinzipiell so aufgebaut wie die bisherigen Swing-Beispiele, zeigt aber bei näherem Hinsehen einige Besonderheiten. Zunächst definiert es einen eigenen ContentPane. In Zeile 012 wird dazu ein JPanel instanziert und mit einem BorderLayout versehen (der Standard-Layoutmanager von JPanel ist FlowLayout). Alle Dialogelemente werden auf diesem Panel platziert. In Zeile 024 wird das Panel durch Aufruf von setContentPane als ContentPane des Fensters definiert.
Zum anderen zeigt das Programm ein paar zusätzliche Möglichkeiten, Umrandungen zu verwenden. Ab Zeile 014 werden mit Hilfe der Methoden createBevelBorder und createEtchedBorder der Klasse BorderFactory zwei unabhängige Umrandungen konstruiert. Durch Aufruf von createCompoundBorder werden sie zu einer neuen Umrandung zusammengefasst und anschließend an den ContentPane übergeben.
Neben einem oder mehreren langlebigen Hauptfenstern besitzt eine Anwendung meist auch Dialogfenster. Sie werden oft nur vorübergehend aufgerufen, um eine temporäre Kommunikation zwischen Anwender und Programm zu etablieren. Dialogfenster unterscheiden sich meist dadurch von Hauptfenstern, dass sie kein Menü und nur eingeschränkte Systemfunktionen besitzen. Zudem ist ihre Größe oft nicht veränderbar und sie halten (als modale Fenster) während der eigenen Ausführung den Programmfluss im übrigen Programm an.
Mit der aus Dialog abgeleiteten Klasse JDialog stehen auch in Swing Dialogfenster zur Verfügung. Sie besitzen denselben strukturellen Aufbau wie JFrame und JWindow und implementieren ebenfalls das Interface RootPaneContainer. Auch hier erfolgt also das Hinzufügen und Anordnen von Komponenten nicht auf dem Fenster selbst, sondern auf seiner ContentPane. JDialog besitzt eine Vielzahl von Konstruktoren. Die wichtigsten sind:
public JDialog(Frame owner) public JDialog(Frame owner, boolean modal) public JDialog(Frame owner, String title) public JDialog(Frame owner, String title, boolean modal) |
javax.swing.JDialog |
Als owner sollte der Aufrufer dabei das Fenster übergeben, zu dem der Dialog logisch gehört. Alle Konstruktoren gibt es auch in einer Form, bei der der owner vom Typ Dialog ist. Wahlweise kann ein JDialog auch ohne owner konstruiert werden (mit dem parameterlosen Konstruktor), doch dann kann es unter Umständen Fokusprobleme beim Wechsel zwischen mehreren Anwendungen geben.
Die übrigen Parameter geben den Titel des Dialogs an und legen fest, ob er modal oder nichtmodal sein soll. Bei einem modalen Dialog wird der Aufruf von show (bzw. setVisible(true)) erst dann beendet, wenn der Dialog geschlossen wurde. Bei einem nichtmodalen Dialog fährt das Programm dagegen unmittelbar mit der nächsten Anweisung hinter show fort.
Eine weitere (und noch dazu sehr bequeme) Möglichkeit, Swing-Dialoge zu erzeugen, steht mit der Klasse JOptionPane zur Verfügung. Diese ist in der Lage, einfache Dialoge, die lediglich ein Icon und einen Text oder ein Eingabefeld und eine Auswahl der Buttons »Yes«, »No« und »Cancel« enthalten, mit einem einzigen Aufruf einer statischen Methode zu erzeugen. JOptionPane ist sehr vielseitig, wir wollen uns an dieser Stelle allerdings auf ihre wichtigsten Anwendungen beschränken.
In seiner einfachsten Form kann JOptionPane dazu verwendet werden, ein Dialogfenster mit Titel, Icon und Hinweistext anzuzeigen, das mit Hilfe eines »OK«-Buttons beendet werden kann. Dazu stehen verschiedene Varianten der Methode showMessageDialog zur Verfügung:
public static void showMessageDialog( Component parentComponent, Object message ) public static void showMessageDialog( Component parentComponent, Object message, String title, int messageType ) public static void showMessageDialog( Component parentComponent, Object message, String title, int messageType, Icon icon ) |
javax.swing.JOptionPane |
Aufrufe von showMessageDialog sind grundsätzlich modal. Erst wenn der Dialog vom Anwender beendet wurde, wird die nächste Anweisung ausgeführt. Der Parameter parentComponent bezeichnet die Vaterkomponente, aus der heraus der Dialog aufgerufen wurde, und message ist der anzuzeigende Text. Soll eine eigene Titelzeile angegeben werden, kann dazu title verwendet werden, andernfalls wird »Message« angezeigt. Wahlweise kann mit dem Parameter icon ein Icon angegeben werden, das neben dem Text angezeigt wird. Alternativ kann auch durch Übergabe einer der Konstanten ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE oder PLAIN_MESSAGE an den Parameter messageType ein Standard-Icon erzeugt werden:
Abbildung 37.5: Die Standard-Icons bei JOptionPane
Mit den verschiedenen Varianten der Methode showConfirmDialog kann ein Dialog erzeugt werden, der neben den zuvor besprochenen Fähigkeiten die Möglichkeit bietet, die Auswahl der Buttons zu beeinflussen, mit denen der Dialog beendet werden kann.
public static int showConfirmDialog( Component parentComponent, Object message ) public static int showConfirmDialog( Component parentComponent, Object message, String title, int optionType ) public static int showConfirmDialog( Component parentComponent, Object message, String title, int optionType, int messageType ) public static int showConfirmDialog( Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon ) |
javax.swing.JOptionPane |
Die Parameter entsprechen im Wesentlichen denen der Methode showMessageDialog. Zusätzlich kann mit optionType eine der Konstanten YES_NO_OPTION, OK_CANCEL_OPTION oder YES_NO_CANCEL_OPTION angegeben werden, um zu entscheiden, welche Kombination von Buttons der Dialog anzeigen soll:
Abbildung 37.6: Button-Kombinationen bei showConfirmDialog
showConfirmDialog ist ebenfalls modal und ihr Rückgabewert zeigt an, auf welche Weise der Dialog beendet wurde:
Rückgabewert | Bedeutung |
YES_OPTION | Mit dem »Yes«-Button |
NO_OPTION | Mit dem »No«-Button |
CANCEL_OPTION | Mit dem »Cancel«-Button |
OK_OPTION | Mit dem »OK«-Button |
CLOSED_OPTION | Mit dem »Schließen«-Button der Titelzeile |
Tabelle 37.1: Rückgabewerte von showConfirmDialog
Mit der Möglichkeit, neben dem Icon und dem Nachrichtentext auch ein Textfeld im Dialog zu platzieren, kann JOptionPane auch zur Erfassung einfacher Daten verwendet werden. Die dazu aufzurufende Methode showInputDialog gibt es ebenfalls in mehreren Varianten:
public static String showInputDialog( Component parentComponent, Object message ) public static String showInputDialog( Component parentComponent, Object message, String title, int messageType ) public static Object showInputDialog( Component parentComponent, Object message, String title, int messageType, Icon icon, Object[] selectionValues, Object initialSelectionValue ) |
javax.swing.JOptionPane |
In der einfachsten Form werden lediglich ein Dialog mit dem Titel »Input«, die angegebene Nachricht mit einem Icon und das Textfeld zur Eingabe der Daten angezeigt. Die zweite Variante erlaubt zusätzlich die Angabe der Titelzeile und die Auswahl des Icontyps. In der letzten Variante wird anstelle des Textfelds eine Combobox zur Dateneingabe verwendet. Der Parameter selectionValues gibt die in der Combobox anzuzeigenden Elemente an (sie werden mit toString in Strings konvertiert) und initialSelectionValue gibt an, welches von ihnen standardmäßig selektiert werden soll.
Bei allen Methoden ist der Rückgabewert ein String mit den vom Anwender eingegebenen Daten. Falls eine Combobox zur Auswahl verwendet wurde, wird der String-Wert des ausgewählten Elements zurückgegeben. Ein Rückgabewert von null zeigt an, dass der Anwender den Dialog abgebrochen hat.
Das folgende Programm zeigt eine einfache Anwendung von JOptionPane, bei der der Anwender einen Wert aus einer vordefinierten Liste auswählen kann:
001 /* Listing3704.java */ 002 003 import javax.swing.*; 004 import java.awt.*; 005 import java.awt.event.*; 006 007 public class Listing3704 008 extends JFrame 009 { 010 private static final String[] QUARTALE = { 011 "1. Quartal", "2. Quartal", "3. Quartal", "4. Quartal" 012 }; 013 014 public Listing3704() 015 { 016 super("Test von JOptionPane"); 017 addWindowListener(new WindowClosingAdapter(true)); 018 } 019 020 public static void main(String[] args) 021 { 022 Listing3704 wnd = new Listing3704(); 023 wnd.setLocation(100, 100); 024 wnd.setSize(300, 200); 025 wnd.setVisible(true); 026 String ret = (String)JOptionPane.showInputDialog( 027 wnd, 028 "Wählen Sie das Quartal aus", 029 "JOptionPane.showInputDialog", 030 JOptionPane.QUESTION_MESSAGE, 031 null, 032 QUARTALE, 033 QUARTALE[2] 034 ); 035 System.out.println("Ausgewählt wurde " + ret); 036 } 037 } |
Listing3704.java |
Der vom Programm erzeugte Dialog sieht unmittelbar nach dem Aufruf von showInputDialog so aus:
Abbildung 37.7: Die Methode showInputDialog
Die Klasse JApplet ist eine einfache Erweiterung von java.applet.Applet. Sie dient zur Entwicklung von Applets, die Swing-Dialogelemente zur Gestaltung der Oberfläche verwenden. Die Unterschiede zwischen beiden Klassen sind nicht sehr umfangreich; insbesondere werden die Methoden init, start, stop und destroy in derselben Weise verwendet wie bei der Klasse Applet.
Wie bei den anderen Hauptfenstern ist auch hier der wichtigste Unterschied, dass JApplet die in Abschnitt 37.1.1 beschriebene RootPane-Struktur realisiert. Die Klasse implementiert ebenfalls das RootPaneContainer-Interface und alle Komponenten müssen an die ContentPane übergeben werden. Da die Applet-Programmierung ab Kapitel 40 ausführlich beschrieben wird, wollen wir uns an dieser Stelle auf ein einfaches Beispiel beschränken:
001 /* JAppletTest.java */ 002 003 import javax.swing.*; 004 import java.awt.*; 005 006 public class JAppletTest 007 extends JApplet 008 { 009 public void init() 010 { 011 Container contentPane = getContentPane(); 012 contentPane.setLayout(new GridLayout(3, 1)); 013 contentPane.add(new JButton("Button 1")); 014 contentPane.add(new JButton("Button 2")); 015 contentPane.add(new JButton("Button 3")); 016 } 017 } |
JAppletTest.java |
Das Programm stellt ein sehr einfaches Applet dar, das - analog zu Listing 37.2 - drei Buttons in einem GridLayout anzeigt. Es kann wie folgt in eine HTML-Datei eingebettet werden:
001 <html> 002 <head><title>JAppletTest</title></head> 003 004 <body> 005 <h1>JAppletTest</h1> 006 007 <applet code="JAppletTest.class" width=300 height=200> 008 Hier steht das JAppletTest 009 </applet> 010 011 </body> 012 </html> |
japplet.html |
Das Applet kann nun mit Hilfe des AppletViewer gestartet werden:
appletviewer japplet.html
Bei vielen Programmen ist es üblich, dass sie ein einziges Hauptfenster besitzen und ihre zahlreichen, gleichzeitig geöffneten Kindfenster innerhalb dieses Hauptfensters anordnen. Diese unter Windows als MDI (Multiple Document Interface) bezeichnete Technik war bei bestimmten Typen von Anwendungen einmal recht verbreitet (z.B. bei Textverarbeitungen, Grafikprogrammen oder Entwicklungsumgebungen), ist aber mittlerweile etwas aus der Mode gekommen. Der Vollständigkeit halber wollen wir sie trotzdem kurz vorstellen.
Während im AWT keine Möglichkeit vorgesehen war, MDI-Anwendungen zu entwickeln, ist es in Swing recht einfach. Dazu werden lediglich zwei Arten von Komponenten benötigt:
Als Desktop ist prinzipiell jede beliebige Hauptfensterklasse geeignet, meist wird aber die Klasse JFrame verwendet. Um die Kindfenster zu verwalten, wird die vordefinierte ContentPane durch eine Instanz der Klasse JDesktopPane ersetzt. Diese von JLayeredPane abgeleitete Klasse besitzt einen DesktopManager, der für die Verwaltung der Kindfenster zuständig ist. Der DesktopManager wird beispielsweise benachrichtigt (und führt alle dazu erforderlichen Aktionen aus), wenn ein Kindfenster verkleinert, vergrößert oder verschoben werden soll.
DesktopManager ist ein Interface, das eine Vielzahl von Methoden enthält. Mit der Klasse DefaultDesktopManager gibt es eine Standardimplementierung, die für viele Zwecke ausreichend ist. |
|
Die Kindfenster werden aus JInternalFrame abgeleitet; einem Dialogelement, das recht überzeugend vortäuscht, ein Hauptfenster zu sein. Tatsächlich ist JInternalFrame direkt aus JComponent abgeleitet und nicht aus JFrame, wie man es vielleicht vermuten könnte. Der Grund liegt darin, dass JFrame als Frame stets eine betriebssystemspezifische Fensterressource besitzt und damit für die Verwendung innerhalb der Grenzen eines anderen Fensters ungeeignet ist.
Eine betriebssystemspezifische Ressource für MDI-Kindfenster steht aber nicht auf allen grafischen Oberflächen zur Verfügung und so haben sich die Swing-Entwickler entschlossen, JInternalFrame als leichtgewichtige Komponente selbst zu realisieren.
Das hat einige Konsequenzen:
Um die Kindfenster zu aktivieren, müssen sie durch Aufruf von setVisible sichtbar gemacht und mit add auf dem Desktop platziert werden.
JInternalFrame besitzt diverse Konstruktoren. Das nachfolgende Syntaxdiagramm zeigt nur den umfangreichsten von ihnen. Alle anderen ergeben sich, indem man auf der rechten Seite nicht benötigte Argumente wegfallen lässt:
public JInternalFrame( String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable ) |
javax.swing.JInternalFrame |
JInternalFrame implementiert das schon erläuterte Interface RootPaneContainer und stellt zusätzlich verschiedene Methoden zur Verfügung. Einige von ihnen sind:
public void setClosable(boolean b) public void setResizable(boolean b) public void setIconifiable(boolean b) public void setMaximizable(boolean b) public void setTitle(String title) public void setDefaultCloseOperation(int operation) |
javax.swing.JInternalFrame |
setClosable entscheidet, ob das Fenster geschlossen, und setResizable, ob seine Größe verändert werden kann. setIconifiable legt fest, ob das Fenster in ein Symbol verkleinert, und setMaximizable, ob es maximiert werden kann. Mit setTitle kann der Rahmentitel angegeben werden und mit setDefaultCloseOperation wird angegeben, wie das Fenster sich beim Schließen verhalten soll. Hier kann eine der Konstanten DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE oder DISPOSE_ON_CLOSE angegeben werden.
Nach diesen Vorbemerkungen wollen wir ein einfaches Beispielprogramm erstellen. Es soll einen JFrame als Desktop mit zwei Kindfenstern enthalten. Diese sollen alle Standardbedienelemente enthalten, vergrößer- und verkleinerbar sein und innerhalb des Desktops verschoben werden können.
Wir erstellen dazu eine Klasse DesktopFrame, die mit einem DefaultDesktopManager ein Desktop aufbaut. Mit ihrer Methode addChild kann ein Kindfenster an einer bestimmten Position auf dem Desktop platziert werden. Weiterhin definieren wir eine aus JInternalFrame abgeleitete Klasse ChildFrame. Sie legt im Konstruktor die Eigenschaften des Fensters fest, hat darüber hinaus aber keine Funktionalitäten.
001 /* Listing3707.java */ 002 003 import java.awt.*; 004 import java.awt.event.*; 005 import javax.swing.*; 006 007 class DesktopFrame 008 extends JFrame 009 { 010 private JDesktopPane desk; 011 012 public DesktopFrame() 013 { 014 super("DesktopFrame"); 015 this.desk = new JDesktopPane(); 016 desk.setDesktopManager(new DefaultDesktopManager()); 017 setContentPane(desk); 018 addWindowListener(new WindowClosingAdapter(true)); 019 } 020 021 public void addChild(JInternalFrame child, int x, int y) 022 { 023 child.setLocation(x, y); 024 child.setSize(200, 150); 025 child.setDefaultCloseOperation( 026 JInternalFrame.DISPOSE_ON_CLOSE 027 ); 028 desk.add(child); 029 child.setVisible(true); 030 } 031 } 032 033 class ChildFrame 034 extends JInternalFrame 035 { 036 public ChildFrame(String title) 037 { 038 super("Child " + title, true, true); 039 setIconifiable(true); 040 setMaximizable(true); 041 setBackground(Color.lightGray); 042 } 043 } 044 045 public class Listing3707 046 { 047 public static void main(String[] args) 048 { 049 //Desktop erzeugen 050 DesktopFrame desktop = new DesktopFrame(); 051 desktop.setLocation(100, 100); 052 desktop.setSize(400, 300); 053 desktop.setVisible(true); 054 //Zwei ChildFrames hinzufügen 055 desktop.addChild(new ChildFrame("1"), 10, 10); 056 desktop.addChild(new ChildFrame("2"), 20, 20); 057 } 058 } |
Listing3707.java |
Die Ausgabe des Programms sieht so aus:
Abbildung 37.8: Die Klasse JInternalFrame
Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0 |
<< | < | > | >> | API | © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de |