Unter den JComponent-Objekten gibt es einige ausgezeichnete, die als Container für andere Kinder fungieren.
Wurzelkomponente der Top-Level-Komponenten (JRootPane)
Die Komponenten JFrame, JDialog, JWindow, JApplet und JInternalFrame enthalten als einziges Kind den leichtgewichtigen Container JRootPane. Die Methode getRootPane() liefert dieses JRootPane-Objekt. Die JRootPane verwaltet eine Layered Pane, die wiederum Content-Pane und Menü aufnimmt, und eine Glass-Pane, die wie eine Glasscheibe über allen anderen Komponenten liegt. Sie kann Ereignisse abfangen oder in einer paint(…)-Methode etwas über alle Komponenten zeichnen.
Beispiel: Weise der Glass-Pane einen wartenden Cursor zu:
Component c = getRootPane().getGlassPane();
if( c != null )
c.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
JDesktopPane und die Kinder von JInternalFrame
Die JDesktopPane ist eine Unterklasse von JLayeredPane und als Container für interne Fenster – also Objekte vom Typ JInternalFrame – gedacht. Mit internen Fenstern (engl. internal frames) lassen sich MDI-Applikationen implementieren, also GUI-Anwendungen, bei denen nicht das grafische Betriebssystem die Fenster verwaltet, sondern die eigene Anwendung.
Bevor ein JInternalFrame sichtbar wird, muss der Container erzeugt und sichtbar gemacht werden:
JDesktopPane desktop = new JDesktopPane();
container.add( desktop );
Jetzt können beliebig viele JInternalFrame-Objekte erzeugt und auf der JDesktopPane platziert werden. Der einfachste Konstruktor ist der Standard-Konstruktor, der einen nicht vergrößerbaren, nicht schließbaren, nicht maximierbaren und nicht zum Icon verkleinerbaren JInternal-Frame ohne Titel erzeugt. Der ausführlichste Konstruktor erlaubt eine genaue Parametrisierung:
JInternalFrame iframe = new JInternalFrame( title, resizable, closeable,
maximizable, iconifiable );
Zwar gibt es nun ein Exemplar, doch wäre es nach dem Aufsetzen auf den Container noch nicht sichtbar:
iframe.setVisible( true );
Bis zur Vollständigkeit fehlen aber noch die Maße:
iframe.setSize( /* width = */ 200, /* height = */ 100 );
Nun kann der iframe dem Container hinzugefügt werden:
desktop.add( iframe );
In einem kompletten Programm kann das so aussehen:
package com.tutego.insel.ui.swing;
import javax.swing.*;
import static java.lang.Math.random;
public class JInternalFrameDemo {
static void addInternalToDesktop( JDesktopPane desktop )
{
JInternalFrame iframe;
iframe = new JInternalFrame( "Ein internes Fenster", // title
true, // resizable
true, // closeable
true, // maximizable
true ); // iconifiable
iframe.setBounds( (int)(random() * 100), (int)(random() * 100),
100 + (int)(random() * 400), 100 + (int)(random() * 300) );
iframe.add( new JScrollPane(new JTextArea()) );
iframe.setVisible( true );
desktop.add( iframe );
}
public static void main( String[] args ) {
JFrame f = new JFrame();
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JDesktopPane desktop = new JDesktopPane();
f.add( desktop );
f.setSize( 500, 400 );
addInternalToDesktop( desktop );
addInternalToDesktop( desktop );
addInternalToDesktop( desktop );
f.setVisible( true );
}
}
Hinweis: Die Schnittstelle von JInternalFrame erinnert an JFrame, doch ist die Ereignisbehandlung anders. So besitzt JInternalFrame eine Methode addInternalFrameListener(…) an Stelle von addWindowListener(…). Ein JInternalFrame empfängt keine WindowEvents, daher darf es addWindowListener(…) – wie es JFrame von java.awt.Window erbt – auch nicht besitzen.