From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100233.html | 1337 ++++++++++++++++++++ 1 file changed, 1337 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100233.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100233.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100233.html b/Master/Reference Architectures and Patterns/hjp5/html/k100233.html new file mode 100644 index 0000000..75e6385 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100233.html @@ -0,0 +1,1337 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 36 - Swing: Container und Menüs +
+
+ + + + +

36.1 Hauptfenster

+
+ +
+ + + + +

36.1.1 JFrame

+ +

+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äßt, können wir (analog zu den Beispielen in Kapitel 31) +wie folgt realisieren: + + +

+ + + + + +
+ +
+001 /* Listing3601.java */
+002 
+003 import javax.swing.*;
+004 import java.awt.event.*;
+005 
+006 public class Listing3601
+007 extends JFrame
+008 {
+009   public Listing3601()
+010   {
+011     super("Ein einfacher JFrame");
+012     addWindowListener(new WindowClosingAdapter(true));
+013   }
+014 
+015   public static void main(String[] args)
+016   {
+017     Listing3601 wnd = new Listing3601();
+018     wnd.setLocation(100, 100);
+019     wnd.setSize(300, 200);
+020     wnd.setVisible(true);
+021   }
+022 }
+
+
+Listing3601.java
+ +Listing 36.1: Verwendung der Klasse JFrame

+ +

+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äßt sich durch +einen Klick auf den Schließen-Button beenden: +

+ + +

+ +

+Abbildung 36.1: Ein einfaches JFrame-Beispiel

+ + + + +

RootPane, LayeredPane und ContentPane

+ +

+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 36.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 soviel 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. + + + + +

Dialogelemente platzieren

+ +

+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 /* Listing3602.java */
+002 
+003 import javax.swing.*;
+004 import java.awt.*;
+005 import java.awt.event.*;
+006 
+007 public class Listing3602
+008 extends JFrame
+009 {
+010   public Listing3602()
+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     Listing3602 wnd = new Listing3602();
+026     wnd.setLocation(100, 100);
+027     wnd.setSize(300, 200);
+028     wnd.setVisible(true);
+029   }
+030 }
+
+
+Listing3602.java
+ +Listing 36.2: Anordnen von Dialogelementen in einem Hauptfenster

+ +

+Das Programm hat nun folgendes Aussehen: +

+ + +

+ +

+Abbildung 36.3: Ein Hauptfenster mit Dialogelementen

+

+ + + + + + + + + + + +
+ +

+Gerade am Anfang passiert es mitunter, dass add +oder setLayout +versehentlich direkt aus dem Hauptfenster aufgerufen werden. Um das +zu verhindern, besitzen die Hauptfensterklassen einen Mechanismus, +der in einem solchen Fall eine Ausnahme mit einem entsprechenden Warnhinweis +auslöst. Dieser kann zwar mit der Methode setRootPaneCheckingEnabled +deaktiviert werden, normalerweise ist das aber nicht zu empfehlen.

+ + + + +
 Warnung 
+
+ + + + +

36.1.2 JWindow

+ +

+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 import java.awt.event.*;
+007 
+008 public class SplashScreen
+009 extends JWindow
+010 {
+011   public SplashScreen(String image, String text)
+012   {
+013     JPanel contentPane = new JPanel(); 
+014     contentPane.setLayout(new BorderLayout());
+015     Border bd1 = BorderFactory.createBevelBorder( 
+016       BevelBorder.RAISED
+017     );
+018     Border bd2 = BorderFactory.createEtchedBorder();
+019     Border bd3 = BorderFactory.createCompoundBorder(bd1, bd2);
+020     ((JPanel)contentPane).setBorder(bd3);
+021     ImageIcon icon = new ImageIcon(image);
+022     contentPane.add(new JLabel(" ", JLabel.CENTER), BorderLayout.NORTH);
+023     contentPane.add(new JLabel(icon, JLabel.CENTER), BorderLayout.CENTER);
+024     contentPane.add(new JLabel(text, JLabel.CENTER), BorderLayout.SOUTH);
+025     setContentPane(contentPane); 
+026   }
+027 
+028   public void showFor(int millis)
+029   {
+030     Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
+031     setLocation(dim.width / 3, dim.height / 3);
+032     setSize(dim.width / 3, dim.height / 3);
+033     setVisible(true);
+034     try {
+035       Thread.sleep(millis);
+036     } catch (InterruptedException e) {
+037     }
+038     setVisible(false);
+039   }
+040 
+041   public static void main(String[] args)
+042   {
+043     SplashScreen intro = new SplashScreen(
+044       "mine.gif",
+045       "(C) Copyright 2000, J. Krüger, All Rights Reserved"
+046     );
+047     intro.showFor(3000);
+048     System.exit(0);
+049   }
+050 }
+
+
+SplashScreen.java
+ +Listing 36.3: Ein einfacher SplashScreen

+ +

+Die Ausgabe des Programms sieht so aus: +

+ + +

+ +

+Abbildung 36.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 013 +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 025 +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 015 +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. + + + + +

36.1.3 JDialog

+ +

+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 nicht-modal sein soll. Bei einem modalen Dialog +wird der Aufruf von show +(bzw. setVisible(true)) erst +dann beendet, wenn der Dialog geschlossen wurde. Bei einem nicht-modalen +Dialog fährt das Programm dagegen unmittelbar mit der nächsten +Anweisung hinter show +fort. + + + + +

36.1.4 JOptionPane

+ +

+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. + + + + +

Anzeigen einer Nachricht

+ +

+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 36.5: Die Standard-Icons bei JOptionPane

+ + + + +

Eingabe einer Bestätigung

+ +

+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 36.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 36.1: Rückgabewerte von showConfirmDialog

+ + + + +

Eingabe von Daten

+ +

+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 /* Listing3604.java */
+002 
+003 import javax.swing.*;
+004 import java.awt.*;
+005 import java.awt.event.*;
+006 
+007 public class Listing3604
+008 extends JFrame
+009 {
+010   private static final String[] QUARTALE = {
+011     "1. Quartal", "2. Quartal", "3. Quartal", "4. Quartal"
+012   };
+013 
+014   public Listing3604()
+015   {
+016     super("Test von JOptionPane");
+017     addWindowListener(new WindowClosingAdapter(true));
+018   }
+019 
+020   public static void main(String[] args)
+021   {
+022     Listing3604 wnd = new Listing3604();
+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 }
+
+
+Listing3604.java
+ +Listing 36.4: Anwendungsbeispiel für JOptionPane

+ +

+Der vom Programm erzeugte Dialog sieht unmittelbar nach dem Aufruf +von showInputDialog +so aus: +

+ + +

+ +

+Abbildung 36.7: Die Methode showInputDialog

+ + + + +

36.1.5 JApplet

+ +

+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 36.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 39 +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 import java.awt.event.*;
+006 
+007 public class JAppletTest
+008 extends JApplet
+009 {
+010   public void init()
+011   {
+012     Container contentPane = getContentPane();
+013     contentPane.setLayout(new GridLayout(3, 1));
+014     contentPane.add(new JButton("Button 1"));
+015     contentPane.add(new JButton("Button 2"));
+016     contentPane.add(new JButton("Button 3"));
+017   }
+018 }
+
+
+JAppletTest.java
+ +Listing 36.5: Anwendungsbeispiel für JApplet

+ +

+Das Programm stellt ein sehr einfaches Applet dar, das - analog zu +Listing 36.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
+ +Listing 36.6: HTML-Datei für JApplet-Beispiel

+ +

+Das Applet kann nun mit Hilfe des AppletViewers gestartet werden: + +

+appletviewer japplet.html
+
+ + + + + +

36.1.6 JInternalFrame

+ +

+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 ist bei bestimmten Typen von Anwendungen mittlerweile +weitverbreitet (z.B. bei Textverarbeitungen, Grafikprogrammen oder +Entwicklungsumgebungen). + +

+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: +

+ + + + +

Der Desktop

+ +

+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.

+ + + + +
 Hinweis 
+
+ + + + +

Die Kindfenster

+ +

+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. Bis zum JDK 1.2 war der Aufruf von +setVisible +nicht unbedingt erforderlich, denn ein JInternalFrame +war standardmäßig sichtbar. Zur Angleichung an die anderen +Hauptfensterklassen wurde dies mit dem JDK 1.3 geändert.

+ + + + +
 JDK1.1-6.0 
+
+ +

+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äßt: +

+ + + + + +
+ +
+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. + + + + +

Beispielprogramm

+ +

+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 /* Listing3607.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 Listing3607
+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 }
+
+
+Listing3607.java
+ +Listing 36.7: Die Klasse JInternalFrame

+ +

+Die Ausgabe des Programms sieht so aus: +

+ + +

+ +

+Abbildung 36.8: Die Klasse JInternalFrame

+
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3