5. Grafische Benutzeroberflächen
Wir möchten hier zeigen, wie man mit JAVA grafische Benutzeroberflächen erstellt. Zunächst sehen wir uns an, welche Basisklassen uns die Erstellung einer grafischen Benutzeroberfläche ermöglichen. Zunächst verwenden wir kein Tool zur automatischen Generierung. Anschließend nutzen wir JBuilder, ein Entwicklungstool von Borland/Inprise, das die Entwicklung von Java-Anwendungen und insbesondere die Erstellung grafischer Benutzeroberflächen erleichtert.
5.1. Grundlagen grafischer Benutzeroberflächen
5.1.1. Ein einfaches Fenster
Betrachten wir den folgenden Code:
// importierte Klassen
import javax.swing.*;
import java.awt.*;
// die Formularklasse
public class form1 extends JFrame {
// der Konstruktor
public form1() {
// Fenstertitel
this.setTitle("Mon premier formulaire");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
}//Konstruktor
// Testfunktion
public static void main(String[] args) {
// Das Formular wird angezeigt
new form1().setVisible(true);
}
}//Klasse
Die Ausführung des obigen Codes zeigt das folgende Fenster an:

Eine grafische Benutzeroberfläche leitet sich in der Regel von der Basisklasse JFrame ab:
public class form1 extends JFrame {
Die Basisklasse JFrame definiert ein Basisfenster mit Schaltflächen zum Schließen, Vergrößern/Verkleinern, einer anpassbaren Größe usw. und verarbeitet die Ereignisse dieser grafischen Objekte. Hier spezialisieren wir die Basisklasse, indem wir ihr einen Titel sowie eine Breite (300 Pixel) und eine Höhe (100 Pixel) zuweisen. Dies geschieht in ihrem Konstruktor:
// der Konstruktor
public form1() {
// Fenstertitel
this.setTitle("Mon premier formulaire");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
}//Konstruktor
Der Titel des Fensters wird durch die Methode setTitle festgelegt, seine Abmessungen durch die Methode setSize. Diese Methode akzeptiert als Parameter ein Objekt vom Typ Dimension(largeur,hauteur), wobei largeur und hauteur die Breite und Höhe des Fensters in Pixeln angeben.
Die Methode main startet die Grafikanwendung wie folgt:
new form1().setVisible(true);
Anschließend wird ein Formular vom Typ form1 erstellt (new form1()) und angezeigt (setVisible(true)), woraufhin die Anwendung auf Ereignisse wartet, die auf dem Formular auftreten (Klicks, Mausbewegungen, ...) und lässt diejenigen ausführen, die das Formular verarbeitet. In diesem Fall verarbeitet unser Formular keine anderen Ereignisse als diejenigen, die von der Basisklasse JFrame verarbeitet werden (Klicks auf Schaltflächen zum Schließen, Vergrößern/Verkleinern, Ändern der Fenstergröße, Verschieben des Fensters usw.).
Wenn man dieses Programm testet, indem man es über ein DOS-Fenster mit folgendem Befehl startet:
um die Datei form1.class auszuführen, stellt man fest, dass beim Schließen des angezeigten Fensters die Eingabe im DOS-Fenster nicht zurückgegeben wird, als ob das Programm noch nicht beendet wäre. Dies ist tatsächlich der Fall. Die Ausführung des Programms erfolgt wie folgt:
- Zunächst wird ein erster Ausführungs-Thread gestartet, um die Methode main auszuführen
- Wenn diese das Formular erstellt und anzeigt, wird ein zweiter Thread erstellt, um speziell die mit dem Formular verbundenen Ereignisse zu verarbeiten
- Nach dieser Erstellung und in unserem Beispiel endet der Thread der Methode main, und es bleibt nur noch der Ausführungs-Thread der grafischen Benutzeroberfläche übrig.
- Wenn man das Fenster schließt, verschwindet es, unterbricht jedoch nicht den Thread, in dem es ausgeführt wurde
- Derzeit muss man diesen Thread zwangsläufig durch Drücken von Strg+C in dem DOS-Fenster beenden, von dem aus die Ausführung des Programms gestartet wurde.
Überprüfen wir das Vorhandensein von zwei getrennten Threads: einem, in dem die Methode main ausgeführt wird, und einem, in dem das grafische Fenster ausgeführt wird:
// importierte Klassen
import javax.swing.*;
import java.awt.*;
import java.io.*;
// die Formularklasse
public class form1 extends JFrame {
// der Konstruktor
public form1() {
// Fenstertitel
this.setTitle("Mon premier formulaire");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
}//Konstruktor
// Testfunktion
public static void main(String[] args) {
// Nachverfolgung
System.out.println("Début du thread main");
// Das Formular wird angezeigt
new form1().setVisible(true);
// Nachverfolgung
System.out.println("Fin du thread main");
}//Hauptprogramm
}//Klasse
Die Ausführung liefert folgende Ergebnisse:

Man kann feststellen, dass der Thread main beendet ist, während das Fenster noch angezeigt wird. Das Schließen des Fensters beendet nicht den Thread, in dem es ausgeführt wurde. Um diesen Thread zu beenden, drückt man erneut Strg+C im DOS-Fenster.
Zum Abschluss dieses Beispiels seien noch die importierten Pakete aufgeführt:
- javax.swing für die Klasse JFrame
- java.awt für die Klasse Dimension
5.1.2. Ein Ereignis verarbeiten
Im vorherigen Beispiel müssten wir das Schließen des Fensters selbst handhaben, damit die Anwendung beendet wird, sobald dies geschieht – was derzeit noch nicht der Fall ist. Dazu müssen wir ein Objekt erstellen, das die im Fenster auftretenden Ereignisse „abhört“ und das Ereignis „Fenster schließen“ erkennt. Dieses Objekt wird als „Listener“ oder Ereignisbehandler bezeichnet. Es gibt verschiedene Arten von Ereignisbehandlern für die unterschiedlichen Ereignisse, die an den Komponenten einer grafischen Benutzeroberfläche auftreten können. Für die Komponente JFrame heißt der Listener WindowListener und ist eine Schnittstelle, die die folgenden Methoden definiert (siehe Java-Dokumentation)
Methodenzusammenfassung | ||
void | windowActivated(WindowEvent e) Das Fenster wird zum aktiven Fenster | |
void | windowClosed(WindowEvent e) Das Fenster wurde geschlossen | |
void | windowClosing(WindowEvent e) Der Benutzer oder das Programm hat das Schließen des Fensters angefordert | |
void | windowDeactivated(WindowEvent e) Das Fenster ist nicht mehr das aktive Fenster | |
void | windowDeiconified(WindowEvent e) Das Fenster wechselt vom minimierten in den normalen Zustand | |
void | windowIconified(WindowEvent e) Das Fenster wechselt vom normalen Zustand in den minimierten Zustand | |
void | windowOpened(WindowEvent e) Das Fenster wird zum ersten Mal sichtbar | |
Es gibt also sieben Ereignisse, die abgehandelt werden können. Die Handler erhalten alle als Parameter ein Objekt vom Typ WindowEvent, das wir vorerst ignorieren. Das Ereignis, das uns hier interessiert, ist das Schließen des Fensters, ein Ereignis, das von der Methode windowClosing verarbeitet werden muss. Um dieses Ereignis zu behandeln, können wir mithilfe einer anonymen Klasse wie folgt ein Objekt vom Typ Windowlistener erstellen:
// Erstellung eines Ereignis-Handlers
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//Win-Definition
Unser Ereignismanager, der die Schnittstelle WindowListener implementiert, muss die sieben Methoden dieser Schnittstelle definieren. Da wir nur das Schließen des Fensters behandeln wollen, definieren wir nur Code für die Methode windowClosing. Wenn die anderen Ereignisse eintreten, werden wir darüber benachrichtigt, unternehmen aber nichts. Was tun wir, wenn wir darüber benachrichtigt werden, dass das Fenster gerade geschlossen wird (windowClosing)? Wir beenden die Anwendung:
public void windowClosing(WindowEvent e){System.exit(0);}
Wir haben hier ein Objekt, das die Ereignisse eines Fensters im Allgemeinen verarbeiten kann. Wie ordnen wir es einem bestimmten Fenster zu? Die Klasse JFrame verfügt über eine Methode addWindowListener(WindowListener win), mit der ein „Fenster“-Ereignishandler einem bestimmten Fenster zugeordnet werden kann. Hier schreiben wir also im Konstruktor des Fensters:
// Erstellung eines Ereignis-Handlers
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//Windows-Definition
// Dieser Ereignismanager verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win);
Das vollständige Programm lautet wie folgt:
// Importierte Klassen
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
// Die Formularklasse
public class form2 extends JFrame {
// der Konstruktor
public form2() {
// Fenstertitel
this.setTitle("Mon premier formulaire");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
// Erstellung eines Ereignishandlers
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//Win-Definition
// Dieser Ereignis-Handler verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win);
}//Konstruktor
// Testfunktion
public static void main(String[] args) {
// Das Formular wird angezeigt
new form2().setVisible(true);
}//main
}//Klasse
Das Paket java.awt.event enthält die Schnittstelle WindowListener. Wenn man dieses Programm ausführt und das angezeigte Fenster schließt, wird im DOS-Fenster, in dem das Programm gestartet wurde, das Ende der Programmausführung angezeigt, was zuvor nicht der Fall war.
In unserem Programm ist die Erstellung des Objekts, das für die Verwaltung der Fensterereignisse zuständig ist, etwas aufwendig, da man gezwungen ist, Methoden auch für Ereignisse zu definieren, die man gar nicht verarbeiten möchte. In diesem Fall kann man anstelle der Schnittstelle WindowListener die Klasse WindowAdapter verwenden. Diese implementiert die Schnittstelle WindowListener mit sieben leeren Methoden. Indem wir die Klasse WindowAdapter ableiten und nur die Methoden neu definieren, die uns interessieren, erzielen wir dasselbe Ergebnis wie mit der Schnittstelle WindowListener, ohne jedoch die Methoden definieren zu müssen, die uns nicht interessieren. Die Reihenfolge
- Definition des Ereignishandlers
- Zuordnung des Handlers zum Fenster
kann in unserem Beispiel wie folgt erfolgen:
// Erstellung eines Ereignishandlers
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//Win-Definition
// Dieser Ereignis-Handler verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win);
Wir verwenden hier eine anonyme Klasse, die von der Klasse WindowAdapter abgeleitet ist und deren Methode windowClosing neu definiert. Das Programm sieht dann wie folgt aus:
// importierte Klassen
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
// Die Formularklasse
public class form2 extends JFrame {
// der Konstruktor
public form2() {
// Fenstertitel
this.setTitle("Mon premier formulaire");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
// Erstellung eines Ereignishandlers
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//Win-Definition
// Dieser Ereignis-Handler verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win); }//Konstruktor
// Testfunktion
public static void main(String[] args) {
// Das Formular wird angezeigt
new form2().setVisible(true);
}//main
}//Klasse
Es liefert dieselben Ergebnisse wie das vorherige Programm, ist aber einfacher zu schreiben.
5.1.3. Ein Formular mit Schaltfläche
Fügen wir nun eine Schaltfläche zu unserem Fenster hinzu:
// importierte Klassen
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
// die Formularklasse
public class form3 extends JFrame {
// eine Schaltfläche
JButton btnTest=null;
Container conteneur=null;
// der Konstruktor
public form3() {
// Fenstertitel
this.setTitle("Formulaire avec bouton");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
// Erstellung eines Ereignishandlers
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//Win-Definition
// Dieser Ereignis-Handler verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win);
// Wir rufen den Container des Fensters ab
conteneur=this.getContentPane();
// Wir wählen einen Layout-Manager für die Komponenten in diesem Container aus
conteneur.setLayout(new FlowLayout());
// Es wird eine Schaltfläche erstellt
btnTest=new JButton();
// Die Beschriftung der Schaltfläche wird festgelegt
btnTest.setText("Test");
// Die Schaltfläche wird dem Container hinzugefügt
conteneur.add(btnTest);
}//Konstruktor
// Testfunktion
public static void main(String[] args) {
// Das Formular wird angezeigt
new form3().setVisible(true);
}//main
}//Klasse
Ein Fenster JFrame verfügt über einen Container, in den grafische Komponenten (Schaltflächen, Kontrollkästchen, Dropdown-Listen usw.) eingefügt werden können. Dieser Container ist über die Methode getContentPane der Klasse JFrame verfügbar:
Container conteneur=null;
..........
// Der Fenstercontainer wird abgerufen
conteneur=this.getContentPane();
Jede Komponente wird mithilfe der Methode add der Klasse Container in den Container eingefügt. Um also die Komponente C in das zuvor genannte Objekt conteneur einzufügen, schreibt man:
Wo wird diese Komponente im Container platziert? Es gibt verschiedene Layout-Manager für Komponenten mit dem Namen XXXLayout, wobei beispielsweise XXX mit Border, Flow, ... Jeder Layout-Manager hat seine Besonderheiten. Der Layout-Manager FlowLayout ordnet die Komponenten beispielsweise in Zeilen an, beginnend am oberen Rand des Formulars. Wenn eine Zeile gefüllt ist, werden die Komponenten in die nächste Zeile verschoben. Um einem Fenster JFrame einen Layout-Manager zuzuordnen, verwendet man die Methode setLayout der Klasse JFrame in folgender Form:
In unserem Beispiel haben wir also, um dem Fenster einen Handler vom Typ FlowLayout zuzuweisen, Folgendes geschrieben:
// einen Layout-Manager für die Komponenten in diesem Container auswählen
conteneur.setLayout(new FlowLayout());
Man kann auch auf einen Layout-Handler verzichten und schreiben:
In diesem Fall müssen die genauen Koordinaten der Komponente im Container in der Form (x, y, Breite, Höhe) angegeben werden, wobei (x, y) die Koordinaten der oberen linken Ecke der Komponente im Container sind. Diese Methode werden wir im weiteren Verlauf am häufigsten verwenden.
Wir wissen nun, wie die Komponenten im Container (add) platziert werden und wo (setLayout). Nun müssen wir noch wissen, welche
Komponenten, die in einen Container platziert werden können. Hier platzieren wir eine Schaltfläche, die durch die Klasse javax.swing.JButton modelliert wird:
JButton btnTest=null;
..........
// Man erstellt eine Schaltfläche
btnTest=new JButton();
// die Beschriftung wird festgelegt
btnTest.setText("Test");
// Die Schaltfläche wird dem Container hinzugefügt
conteneur.add(btnTest);
Wenn man dieses Programm testet, erscheint das folgende Fenster:

Wenn man die Größe des obigen Formulars ändert, wird automatisch der Layout-Manager des Containers aufgerufen, um die Komponenten neu anzuordnen:

Das ist der Hauptvorteil von Layout-Managern: Sie sorgen dafür, dass das Layout der Komponenten auch bei Änderungen der Containergröße konsistent bleibt. Verwenden wir den Layout-Manager null, um den Unterschied zu sehen. Die Schaltfläche wird nun durch die folgenden Anweisungen im Container platziert:
// Man wählt einen Formatierungsmanager für die Komponenten in diesem Container aus
conteneur.setLayout(null);
// Man erstellt eine Schaltfläche
btnTest=new JButton();
// Die Beschriftung wird festgelegt
btnTest.setText("Test");
// Man legt die Position und die Abmessungen fest
btnTest.setBounds(10,20,100,20);
// Die Schaltfläche wird dem Container hinzugefügt
conteneur.add(btnTest);
Hier wird die Schaltfläche explizit am Punkt (10,20) des Formulars platziert und ihre Abmessungen auf 100 Pixel Breite und 20 Pixel Höhe festgelegt. Das neue Fenster sieht nun wie folgt aus:

Wenn man die Größe des Fensters ändert, bleibt die Schaltfläche an derselben Stelle.

Wenn man auf die Schaltfläche Test klickt, passiert nichts. Das liegt daran, dass wir der Schaltfläche noch keinen Ereignis-Handler zugewiesen haben. Um herauszufinden, welche Arten von Ereignisbehandlungsroutinen für eine bestimmte Komponente verfügbar sind, kann man in der Definition ihrer Klasse nach Methoden wie addXXXListener suchen, mit denen der Komponente eine Ereignisbehandlungsroutine zugewiesen werden kann. Die Klasse javax.swing.JButton leitet sich von der Klasse javax.swing.AbstractButton ab, in der die folgenden Methoden zu finden sind:
Methodenzusammenfassung | ||
void | addActionListener(ActionListener l) | |
void | addChangeListener(ChangeListener l) | |
void | addItemListener(ItemListener l) | |
Hier muss man in der Dokumentation nachlesen, welcher Ereignis-Handler den Klick auf die Schaltfläche verarbeitet. Es handelt sich um die Schnittstelle ActionListener. Diese definiert nur eine Methode:
Methodenzusammenfassung | ||
void | actionPerformed(ActionEvent e) | |
Die Methode erhält einen Parameter ActionEvent, den wir vorerst ignorieren werden. Um den Klick auf die Schaltfläche btntest in unserem Programm zu verarbeiten, weisen wir ihr zunächst einen Ereignis-Handler zu:
btnTest.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt){
btnTest_clic(evt);
}
}//anonyme Klasse
);//Ereignisbehandler
Hier verweist die Methode actionPerformed auf die Methode btnTest_clic, die wir wie folgt definieren:
public void btnTest_clic(ActionEvent evt){
// Konsolenüberwachung
System.out.println("clic sur bouton");
}//btnTest_click
Jedes Mal, wenn der Benutzer auf die Schaltfläche Test klickt, wird eine Meldung in die Konsole geschrieben. Dies zeigt die folgende Ausführung:

Das vollständige Programm lautet wie folgt:
// importierte Klassen
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
// Formularklasse
public class form4 extends JFrame {
// eine Schaltfläche
JButton btnTest=null;
Container conteneur=null;
// der Konstruktor
public form4() {
// Fenstertitel
this.setTitle("Formulaire avec bouton");
// Fensterabmessungen
this.setSize(new Dimension(300,100));
// Erstellung eines Ereignishandlers
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//Windows-Definition
// Dieser Ereignis-Handler verwaltet die Ereignisse des aktuellen Fensters
this.addWindowListener(win);
// Wir rufen den Container des Fensters ab
conteneur=this.getContentPane();
// Wir wählen einen Layout-Manager für die Komponenten in diesem Container aus
conteneur.setLayout(null);
// Es wird eine Schaltfläche erstellt
btnTest=new JButton();
// Die Beschriftung wird festgelegt
btnTest.setText("Test");
// Man legt die Position und die Abmessungen fest
btnTest.setBounds(10,20,100,20);
// Man ordnet ihr einen Ereignis-Handler zu
btnTest.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt){
btnTest_clic(evt);
}
}//anonyme Klasse
);//Ereignisbehandler
// Die Schaltfläche wird dem Container hinzugefügt
conteneur.add(btnTest);
}//Konstruktor
public void btnTest_clic(ActionEvent evt){
// Konsolen-Tracking
System.out.println("clic sur bouton");
}//btnTest_click
// Testfunktion
public static void main(String[] args) {
// Das Formular wird angezeigt
new form4().setVisible(true);
}//Hauptprogramm
}//Klasse
5.1.4. Ereignisbehandler
Die wichtigsten Swing-Komponenten, die wir vorstellen werden, sind Fenster (JFrame), Schaltflächen (JButton), Kontrollkästchen (JCheckBox), Optionsfelder (JButtonRadio), Dropdown-Listen (JComboBox), Listen (JList), Schieberegler (JScrollBar), Beschriftungen (JLabel), einzeilige (JTextField) oder mehrzeilige (JTextArea) Eingabefelder, Menüs (JMenuBar), Menüelemente (JMenuItem).
Die folgenden Tabellen enthalten eine Liste einiger Ereignisbehandler und der Ereignisse, mit denen sie verknüpft sind.
Handler | Komponente(n) | Registrierungsmethode | Ereignis |
ActionListener | JButton, JCheckbox, JButtonRadio, JMenuItem | public void addActionListener(ActionListener) | Klick auf die Schaltfläche, das Kontrollkästchen, das Optionsfeld, das Menüelement |
JTextField | |||
ItemListener | JComboBox, JList | public void addItemListener(ItemListener) | Das ausgewählte Element hat sich geändert |
InputMethodListener | JTextField, JTextArea | public void addMethodInputListener(InputMethodListener) | Der Text im Eingabefeld hat sich geändert oder die Position des Eingabecursors hat sich geändert |
CaretListener | JTextField, JTextArea | public void addcaretListener(CaretListener) | Die Position des Eingabecursors hat sich geändert |
AdjustmentListener | JScrollBar | public void addAdjustmentListener(AdjustmentListener) | Der Wert des Reglers hat sich geändert |
MouseMotionListener | public void addMouseMotionListener(MouseMotionListener) | Die Maus wurde bewegt | |
WindowListener | JFrame | public void addWindowlistener(WindowListener) | Fensterereignis |
MouseListener | public void addMouselistener(MouseListener) | Mausereignisse (Klick, Ein-/Austritt aus dem Bereich einer Komponente, Taste gedrückt, losgelassen) | |
FocusListener | public void addFocuslistener(FocusListener) | Ereignis „Focus“ (erhalten, verloren) | |
KeyListener | public void addKeylistener(KeyListener) | Tastaturereignis (Taste getippt, gedrückt, losgelassen) |
Komponente | Methode zum Registrieren von Ereignisbehandlungsroutinen |
JButton | public void addActionListener(ActionListener) |
JCheckbox | public void addItemListener(ItemListener) |
JCheckboxMenuItem | public void addItemListener(ItemListener) |
JComboBox | public void addItemListener(ItemListener) public void addActionListener(ActionListener) |
Container | public void addContainerListener(ContainerListener) |
JComponent | public void addComponentListener(ComponentListener) public void addFocusListener(FocusListener) public void addKeyListener(KeyListener) public void addMouseListener(MouseListener) public void addMouseMotionListener(MouseMotionListener) |
JFrame | public void addWindowlistener(WindowListener) |
JList | public void addItemListener(ItemListener) |
JMenuItem | public void addActionListener(ActionListener) |
JPanel | als Container |
JScrollPane | als Container |
JScrollBar | public void addAdjustmentListener(AdjustmentListener) |
JTextComponent | public void addInputMethodListener(InputMethodListener) public void addCaretListener(CaretListener) |
JTextArea | wie JTextComponent |
JTextField | wie JTextComponent public void addActionListener(ActionListener) |
Alle Komponenten, mit Ausnahme derjenigen vom Typ TextXXX, sind von der Klasse JComponent abgeleitet und verfügen daher ebenfalls über die dieser Klasse zugeordneten Methoden.
5.1.5. Die Methoden der Ereignisbehandler
Die folgende Tabelle listet die Methoden auf, die von den verschiedenen Ereignisbehandlungsroutinen implementiert werden müssen.
Schnittstelle | Methoden |
ActionListener | public void actionPerformed(ActionEvent) |
AdjustmentListener | public void adjustmentValueChanged(AdjustmentEvent) |
ComponentListener | public void componentHidden(ComponentEvent) public void componentMoved(ComponentEvent) public void componentResized(ComponentEvent) public void componentShown(ComponentEvent) |
ContainerListener | public void componentAdded(ContainerEvent) public void componentRemoved(ContainerEvent) |
FocusListener | public void focusGained(FocusEvent) public void focusLost(FocusEvent) |
ItemListener | public void itemStateChanged(ItemEvent) |
KeyListener | public void keyPressed(KeyEvent) public void keyReleased(KeyEvent) public void keyTyped(KeyEvent) |
MouseListener | public void mouseClicked(MouseEvent) public void mouseEntered(MouseEvent) public void mouseExited(MouseEvent) public void mousePressed(MouseEvent) public void mouseReleased(MouseEvent) |
MouseMotionListener | public void mouseDragged(MouseEvent) public void mouseMoved(MouseEvent) |
TextListener | public void textValueChanged(TextEvent) |
InputmethodListener | public void InputMethodTextChanged(InputMethodEvent) public void caretPositionChanged(InputMethodEvent) |
CaretLisetner | public void caretUpdate(CaretEvent) |
WindowListener | public void windowActivated(WindowEvent) public void windowClosed(WindowEvent) public void windowClosing(WindowEvent) public void windowDeactivated(WindowEvent) public void windowDeiconified(WindowEvent) public void windowIconified(WindowEvent) public void windowOpened(WindowEvent) |
5.1.6. Die Adapterklassen
Wie wir bereits bei der Schnittstelle WindowListener gesehen haben, gibt es Klassen mit dem Namen XXXAdapter, die die Schnittstellen XXXListener mit leeren Methoden implementieren. Ein von einer Klasse XXXAdapter abgeleiteter Ereignisbehandler kann dann nur einen Teil der Methoden der Schnittstelle XXXListener implementieren, nämlich diejenigen, die die Anwendung benötigt.
Angenommen, man möchte Mausklicks auf einer Frame-Komponente f1 verarbeiten. Man könnte ihr einen Ereignis-Handler wie folgt zuweisen:
und schreiben:
public class gestionnaireSouris implements MouseListener{
// die 5 Methoden der Schnittstelle werden geschrieben MouseListener
// mouseClicked, ..., mouseReleased)
}// Ende der Klasse
Da wir jedoch nur Mausklicks verarbeiten möchten, ist es besser, Folgendes zu schreiben:
public class gestionnaireSouris extends MouseAdapter{
// Man schreibt nur eine einzige Methode, nämlich die, die die Mausklicks verarbeitet
public void mouseClicked(MouseEvent evt){
…
}
}// Ende der Klasse
Die folgende Tabelle listet die Adapterklassen der verschiedenen Ereignisbehandler auf:
Ereignis-Handler | Adapter |
ComponentListener | ComponentAdapter |
ContainerListener | ContainerAdapter |
FocusListener | FocusAdapter |
KeyListener | KeyAdapter |
MouseListener | MouseAdapter |
MouseMotionListener | MouseMotionAdapter |
WindowListener | WindowAdapter |
5.1.7. Fazit
Wir haben soeben die Grundkonzepte der Erstellung grafischer Benutzeroberflächen in Java vorgestellt:
- Erstellung eines Fensters
- Erstellung von Komponenten
- Zuordnung der Komponenten zum Fenster mithilfe eines Layout-Managers
- Zuordnung von Ereignisbehandlungsroutinen zu den Komponenten
Anstatt nun grafische Benutzeroberflächen wie gerade beschrieben „von Hand“ zu erstellen, werden wir JBuilder verwenden, ein Java-Entwicklungstool von Borland/Inprise in der Version 4, und die Komponenten aus der Bibliothek supérieure.Nous nutzen, die derzeit von Sun, dem Entwickler von Java, empfohlen wird.
5.2. Erstellen einer grafischen Benutzeroberfläche mit JBuilder
5.2.1. Unser erstes JBuilder-Projekt
Um uns mit JBuilder vertraut zu machen, erstellen wir eine ganz einfache Anwendung: ein leeres Fenster.
- Starten Sie JBuilder und wählen Sie die Option „Datei/Neues Projekt“. Daraufhin wird die erste Seite eines Assistenten angezeigt:

- Füllen Sie die folgenden Felder aus:
Projektname | Start Dadurch wird eine Projektdatei mit dem Namen début.jpr in dem Ordner erstellt, der im Feld „Name des Projektverzeichnisses“ angegeben ist |
Stammverzeichnis | Geben Sie den Ordner an, unter dem der Ordner für das von Ihnen zu erstellende Projekt angelegt werden soll. |
Name des Projektverzeichnisses | Geben Sie den Namen des Ordners an, in dem alle Projektdateien abgelegt werden sollen. Dieser Ordner wird in dem Verzeichnis erstellt, das im Feld „Stammverzeichnis“ angegeben ist |
Die Quelldateien (.java, .html, ...), die Zieldateien (.class, ...) und die Sicherungsdateien können in unterschiedlichen Verzeichnissen abgelegt werden. Wenn Sie die entsprechenden Felder leer lassen, werden sie im selben Verzeichnis wie das Projekt abgelegt.
Geben Sie „[suivant]“ ein
- Ein Bildschirm bestätigt die Auswahl aus dem vorherigen Schritt

Führen Sie [suivant] aus
- Ein neuer Bildschirm fordert Sie auf, Ihr Projekt zu beschreiben:

Führen Sie [terminer] aus
- Stellen Sie sicher, dass die Option Voir/projet aktiviert ist. Im linken Fenster sollte nun die Struktur Ihres Projekts angezeigt werden.

- Erstellen wir nun eine grafische Benutzeroberfläche in diesem Projekt. Wählen Sie die Option Fichier/Nouveau/Application:

Im Feld classe geben Sie den Namen der Klasse ein, die erstellt werden soll. Hier haben wir denselben Namen wie das Projekt verwendet.
Führen Sie [suivant] aus
- Der folgende Bildschirm erscheint:

Klasse | interfaceDébut Dies ist der Name der Klasse, die dem Fenster entspricht, das erstellt werden soll |
Titel | Dies ist der Text, der in der Titelleiste des Fensters angezeigt wird |
Beachten Sie, dass wir oben festgelegt haben, dass das Fenster beim Start der Anwendung auf dem Bildschirm zentriert werden soll.
Erstellen Sie [Terminer]
- Jetzt erweist sich JBuilder als nützlich.
- Es generiert die .java-Quelldateien der beiden Klassen, deren Namen wir angegeben haben: die Anwendungsklasse und die Klasse der grafischen Benutzeroberfläche. Diese beiden Dateien erscheinen in der Projektstruktur im linken Fenster

- Um auf den generierten Code für die beiden Klassen zuzugreifen, genügt ein Doppelklick auf die entsprechende .java-Datei. Wir werden später noch auf den generierten Code zurückkommen.
- Stellen Sie sicher, dass die Option Voir/Structure aktiviert ist. Damit können Sie die Struktur der aktuell ausgewählten Klasse anzeigen (Doppelklick auf die .java-Datei). Hier sehen Sie beispielsweise die Struktur der Klasse début:

Hier erfahren Sie:
-
welche Bibliotheken importiert wurden (imports)
-
dass es einen Konstruktor début() gibt
-
dass es eine statische Methode main() gibt
-
dass es ein Attribut packFrame gibt
Was ist der Vorteil, Zugriff auf die Struktur einer Klasse zu haben?
-
Sie erhalten einen Überblick darüber. Das ist nützlich, wenn Ihre Klasse komplex ist.
-
Sie können auf den Code einer Methode zugreifen, indem Sie im Strukturfenster der Klasse darauf klicken. Auch dies ist nützlich, wenn Ihre Klasse Hunderte von Zeilen umfasst. Sie müssen nicht alle Zeilen durchgehen, um den gesuchten Code zu finden.
Der von JBuilder generierte Code ist bereits einsatzbereit. Wählen Sie „Ausführen/Projekt ausführen“ oder „F9“, und Sie erhalten das gewünschte Fenster:

Außerdem wird es ordnungsgemäß geschlossen, wenn man auf die Schaltfläche zum Schließen des Fensters klickt. Wir haben soeben unsere erste grafische Benutzeroberfläche erstellt. Wir können unser Projekt über die Option „Datei/Projekte schließen“ speichern:

Wenn Sie auf Tous drücken, werden alle im obigen Fenster angezeigten Projekte markiert. OK schließt sie. Wenn wir neugierig sind und mit dem Windows-Explorer in den Ordner unseres Projekts wechseln (den wir dem Assistenten zu Beginn der Projektkonfiguration angegeben haben), finden wir dort die folgenden Dateien:

In unserem Beispiel hatten wir festgelegt, dass sich alle Dateien (Quelldatei .java, Zieldatei .class, Sicherungsdatei .jpr~) im selben Ordner wie die Projektdatei .jpr befinden sollen.
5.2.2. Die von JBuilder für eine grafische Benutzeroberfläche generierten Dateien
Schauen wir uns nun einmal an, welche .java-Quelldateien JBuilder generiert hat. Es ist wichtig, die generierten Dateien lesen zu können, da wir meistens Code zu dem Hinzufügen müssen, was generiert wurde. Beginnen wir damit, unser Projekt zu öffnen: „Datei“ > „Projekt öffnen“ und wählen wir das Projekt „début.jpr“ aus. Wir finden das zuvor erstellte Projekt wieder.
5.2.2.1. Die Hauptklasse
Sehen wir uns die Klasse „début.java“ an, indem wir im Fenster mit der Liste der Projektdateien auf ihren Namen doppelklicken. Wir erhalten folgenden Code:
import javax.swing.UIManager;
import java.awt.*;
public class début {
boolean packFrame = false;
/**Anwendung erstellen*/
public début() {
interfaceDébut frame = new interfaceDébut();
//Rahmen mit vordefinierten Größen validieren
//Rahmen mit bevorzugten Größenangaben komprimieren – z. B. anhand ihres Layouts
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//Fenster zentrieren
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
}
/**Hauptmethode*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new début();
}
}
Erläutern wir den generierten Code:
- Die Funktion main legt das Erscheinungsbild des Fensters (setLookAndFeel) fest und erstellt eine Instanz der Klasse début.
- Anschließend wird der Konstruktor début() ausgeführt. Er erstellt eine Instanz frame der Fensterklasse (new interfaceDébut()). Diese wird instanziiert, aber nicht angezeigt.
- Das Fenster wird dann entsprechend den für die einzelnen Fensterkomponenten verfügbaren Informationen dimensioniert (frame.validate). Es beginnt nun sein eigenständiges Dasein, indem es angezeigt wird und auf Benutzeraktionen reagiert.
- Das Fenster wird auf dem Bildschirm zentriert, da dies bei der Konfiguration des Fensters mit dem Assistenten festgelegt wurde.
Schauen wir uns an, was dabei herauskäme, wenn wir den Code début.java auf das absolute Minimum reduzieren würden, wie wir es zu Beginn des Kapitels getan haben. Erstellen wir eine neue Klasse. Wählen Sie die Option „Datei/Neue Klasse“:

Benennen Sie die neue Klasse in „début2“ um und erstellen Sie „[Terminer]“. Im Projekt erscheint eine neue Datei:

Die Datei „début2.java“ wird auf das Wesentliche reduziert:
Ergänzen wir die Klasse wie folgt:
public class début2 {
// Hauptfunktion
public static void main(String args[]){
// Erstellt das Fenster
new interfaceDébut().show(); // oder new interfaceDébut.setVisible(true);
}//main
}//Klasse „début2“
Die Funktion main erstellt eine Instanz des Fensters interfaceDébut und zeigt diese an (show). Bevor wir unser Projekt ausführen, müssen wir darauf hinweisen, dass die Klasse, die die auszuführende Funktion main enthält, nun die Klasse début2 ist. Klicken Sie mit der rechten Maustaste auf das Projekt début.jpr und wählen Sie die Option propriétés sowie anschließend die Registerkarte Exécution:
21

Hier wird angezeigt, dass die Hauptklasse début ist (1). Klicken Sie auf die Schaltfläche (2), um eine andere Hauptklasse auszuwählen:

Wählen Sie „début2“ aus und ändern Sie den Wert auf „[OK]“.

Geben Sie [OK] ein, um diese Auswahl zu bestätigen, und starten Sie anschließend das Projekt über „Ausführen/Projekt ausführen“ oder F9. Sie erhalten dasselbe Fenster wie bei der Klasse début, nur dass es nicht zentriert ist, da dies hier nicht angefordert wurde. Im weiteren Verlauf werden wir die von JBuilder generierte Hauptklasse nicht mehr vorstellen, da sie immer dasselbe tut: ein Fenster erstellen. Wir werden uns fortan auf die Klasse dieses Fensters konzentrieren.
5.2.2.2. Die Fensterklasse
Sehen wir uns nun den Code an, der für die Klasse interfaceDébut generiert wurde:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceDébut extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
/**Rahmen erstellen*/
public interfaceDébut() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Ma première interface graphique avec Jbuilder");
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
}
5.2.2.2.1. Die importierten Bibliotheken
Es handelt sich um die Bibliotheken java.awt, java.awt.event und javax.swing. Die ersten beiden waren die einzigen, die für die Erstellung grafischer Benutzeroberflächen mit den ersten Java-Versionen zur Verfügung standen. Die Bibliothek javax.swing ist neuer. Hier wird sie für das Fenster vom Typ JFrame benötigt, das hier verwendet wird.
5.2.2.2.2. Die Attribute
JPanel ist ein Containertyp, in den Komponenten eingefügt werden können. BorderLayout ist einer der verfügbaren Layout-Manager-Typen, um die Komponenten im Container zu platzieren. In allen unseren Beispielen werden wir keinen Layout-Manager verwenden und die Komponenten selbst an einer bestimmten Stelle im Container platzieren. Dazu verwenden wir den Layout-Manager null.
5.2.2.2.3. Der Fenster-Konstruktor
/**Rahmen erstellen*/
public interfaceDébut() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Ma première interface graphique avec Jbuilder");
}
- Der Hersteller gibt zunächst an, dass er die Ereignisse im Fenster (enableEvents) verarbeiten wird, und ruft dann die Methode jbInit auf.
- Der Container (JPanel) des Fensters (JFrame) wird abgerufen (getContentPane)
- Der Formatierungsmanager wird festgelegt (setLayout)
- Die Fenstergröße wird festgelegt (setSize)
- Der Fenstertitel wird festgelegt (setTitle)
5.2.2.2.4. Der Ereignismanager
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
Der Hersteller hatte angegeben, dass die Klasse die Ereignisse des Fensters verarbeiten würde. Diese Aufgabe übernimmt die Methode processWindowEvent. Zunächst leitet sie das empfangene Ereignis WindowEvent an ihre übergeordnete Klasse (JFrame) weiter. Handelt es sich dabei um das Ereignis WINDOW_CLOSING, das durch einen Klick auf die Schaltfläche zum Schließen des Fensters ausgelöst wurde, wird die Anwendung beendet.
5.2.2.2.5. Fazit
Der Code der Fensterklasse unterscheidet sich von dem im Beispiel zu Beginn des Kapitels vorgestellten. Würden wir ein anderes Java-Generierungstool als JBuilder verwenden, hätten wir zweifellos einen noch anderen Code. In der Praxis akzeptieren wir den von JBuilder erzeugten Code zum Erstellen des Fensters, um uns ausschließlich auf das Schreiben der Ereignisbehandler der grafischen Benutzeroberfläche zu konzentrieren.
5.2.3. Eine grafische Benutzeroberfläche zeichnen
5.2.3.1. Ein Beispiel
Im vorherigen Beispiel hatten wir keine Komponenten in das Fenster eingefügt. Erstellen wir nun ein Fenster mit einer Schaltfläche, einem Beschriftungsfeld und einem Eingabefeld:

Die Felder lauten wie folgt:
Nr. | Name | Typ | Rolle |
1 | lblSaisie | JLabel | eine Bezeichnung |
2 | txtSaisie | JTextField | ein Eingabefeld |
3 | cmdAfficher | JButton | um den Inhalt des Eingabefelds in einem Dialogfeld anzuzeigen txtSaisie |
Gehen Sie wie beim vorherigen Projekt vor und erstellen Sie das Projekt interface2.jpr, ohne vorerst Komponenten in das Fenster einzufügen.

Wählen Sie im obigen Fenster die Klasse interface2.java aus. Rechts neben diesem Fenster befindet sich eine Registerkarte:

Die Registerkarte „Source“ bietet Zugriff auf den Quellcode der Klasse „interface2.java“. Über die Registerkarte „Conception“ können Sie das Fenster visuell erstellen. Wählen Sie diese Registerkarte aus. Vor Ihnen sehen Sie den Fenstercontainer, in den Sie die Komponenten einfügen werden. Er ist derzeit noch leer. Im linken Fenster wird die Struktur der Klasse angezeigt:

this | steht für das Fenster |
contentPane | sein Container, in den Komponenten abgelegt werden, sowie die Art und Weise, wie diese Komponenten im Container angeordnet werden (standardmäßig BorderLayout) |
borderLayout1 | eine Instanz des Formatierungsmanagers |
Wählen Sie das Objekt this aus. Das zugehörige Eigenschaftenfenster wird daraufhin auf der rechten Seite angezeigt:

Einige dieser Eigenschaften sind besonders zu beachten:
background | zur Festlegung der Hintergrundfarbe des Fensters |
foreground | zum Festlegen der Farbe der Grafiken im Fenster |
JMenuBar | um dem Fenster ein Menü zuzuordnen |
title | um dem Fenster einen Titel zu geben |
resizable | um den Fenstertyp festzulegen |
font | um die Schriftart für die Texte im Fenster festzulegen |
Da das Objekt „this“ weiterhin ausgewählt ist, kann man die Größe des auf dem Bildschirm angezeigten Containers ändern, indem man an den Ankerpunkten rund um den Container zieht:

Wir sind nun bereit, Komponenten in den oben genannten Container abzulegen. Zuvor ändern wir jedoch den Formatierungsmanager. Wählen Sie das Objekt contentPane im Strukturfenster aus:

Wählen Sie anschließend im Eigenschaftenfenster dieses Objekts die Eigenschaft layout aus und wählen Sie aus den möglichen Werten den Wert null aus:

Da kein Formatierungsmanager vorhanden ist, können wir die Komponenten frei im Container platzieren. Nun ist es an der Zeit, diese auszuwählen.
Wenn der Bereich „Conception“ ausgewählt ist, stehen die Komponenten in einer Registerkartenleiste am oberen Rand des Entwurfsfensters zur Verfügung:

Zum Erstellen der grafischen Benutzeroberfläche stehen uns Komponenten vom Typ swing (1) und awt (2) zur Verfügung. Wir werden hier die Komponenten vom Typ swing verwenden. Wählen Sie in der obigen Komponentenleiste eine Komponente JLabel (3), eine Komponente JTextField (4) und eine Komponente JButton (5) aus und platzieren Sie diese im Container des Entwurfsfensters.

Nun passen wir jede dieser drei Komponenten an:
- das Label (JLabel) jLabel1
Wählen Sie die Komponente aus, um ihr Eigenschaftenfenster zu öffnen. Ändern Sie darin die folgenden Eigenschaften: name: lblSaisie, text: Eingabe
- das Eingabefeld (JTextField) jTextfield1
Wählen Sie die Komponente aus, um ihr Eigenschaftenfenster zu öffnen. Ändern Sie darin die folgenden Eigenschaften: name: txtSaisie, text: nichts eingeben
- die Schaltfläche (JButton): name: cmdAfficher, text: Anzeigen
Nun haben wir das folgende Fenster:

und die folgende Struktur:

Wir können (F9) unser Projekt ausführen, um einen ersten Eindruck vom Fenster in Aktion zu erhalten:

Schließen Sie das Fenster. Nun müssen wir noch die Prozedur schreiben, die beim Klicken auf die Schaltfläche Afficher ausgeführt wird. Wählen Sie die Schaltfläche aus, um das Eigenschaftenfenster aufzurufen. Dieses verfügt über zwei Registerkarten: propriétés und événements. Wählen Sie „événements“ aus.

In der linken Spalte des Fensters sind die möglichen Ereignisse für die Schaltfläche aufgelistet. Ein Klick auf eine Schaltfläche entspricht dem Ereignis actionPerformed. Die rechte Spalte enthält den Namen der Prozedur, die aufgerufen wird, wenn das entsprechende Ereignis eintritt. Klicken Sie auf die Zelle rechts neben dem Ereignis actionPerformed:

JBuilder generiert für jeden Ereignis-Handler einen Standardnamen in der Form nomComposant_nomEvénement, hier cmdAfficher_actionPerformed. Man könnte den vorgeschlagenen Standardnamen löschen und einen anderen eingeben. Um auf den Code des Handlers cmdAfficher_actionPerformed zuzugreifen, genügt ein Doppelklick auf den oben genannten Namen. Man gelangt dann automatisch in den Quellcode-Bereich der Klasse, der auf das Grundgerüst des Codes des Ereignis-Handlers ausgerichtet ist:
Nun müssen wir diesen Code nur noch vervollständigen. Hier möchten wir ein Dialogfeld anzeigen, das den Inhalt des Feldes txtSaisie enthält:
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(),
"Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
JOptionPane ist eine Klasse der Bibliothek javax.swing. Sie ermöglicht es, Meldungen zusammen mit einem Symbol anzuzeigen oder Informationen vom Benutzer abzufragen. Hier verwenden wir eine statische Methode der Klasse:

parentComponent | das „übergeordnete“ Container-Objekt des Dialogfelds: hier this. |
Meldung | ein anzuzeigendes Objekt. Hier der Inhalt des Eingabefelds |
title | Der Titel des Dialogfelds |
messageType | Der Typ der anzuzeigenden Meldung. Bestimmt das Symbol, das im Feld neben der Meldung angezeigt wird. Mögliche Werte: INFORMATION_MESSAGE, QUESTION_MESSAGE, ERROR_MESSAGE, WARNING_MESSAGE, PLAIN_MESSAGE |
Führen wir unsere Anwendung (F9) aus:


5.2.3.2. Der Code der Fensterklasse
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import javax.swing.event.*;
public class interface2 extends JFrame {
JPanel contentPane;
JLabel lblSaisie = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmdAfficher = new JButton();
/**Rahmen erstellen*/
public interface2() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(), "Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
}
5.2.3.2.1. Die Attribute
JPanel contentPane;
JLabel lblSaisie = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmdAfficher = new JButton();
Darin befinden sich der Behälter mit den Komponenten vom Typ JPanel sowie die drei Komponenten.
5.2.3.2.2. Der Hersteller
/**Rahmen erstellen*/
public interface2() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}
Der Konstruktor interface2 ähnelt dem Konstruktor der zuvor untersuchten grafischen Benutzeroberfläche. Unterschiede finden sich in der Methode jbInit: Der Code zum Erstellen des Fensters hängt von den darin platzierten Komponenten ab. Man kann den Code von jbInit übernehmen und eigene Kommentare hinzufügen:
private void jbInit() throws Exception {
// das Fenster selbst (Größe, Titel)
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
// der Container für die Komponenten
contentPane = (JPanel) this.getContentPane();
// kein Formatierungsmanager für diesen Container
contentPane.setLayout(null);
// das Etikett lblSaisie (Bezeichnung, Position, Größe)
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
// das Eingabefeld (Position, Größe)
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
// die Schaltfläche „Anzeigen“ (Bezeichnung, Position, Größe)
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
// der Ereignis-Handler der Schaltfläche
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
// Hinzufügen der 3 Komponenten zum Container
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}//jbInit
Zwei Punkte sind dabei zu beachten:
- Dieser Code hätte von Hand geschrieben werden können. Das bedeutet, dass man auf JBuilder verzichten kann, um eine grafische Benutzeroberfläche zu erstellen.
- die Art und Weise, wie der Ereignishandler der Schaltfläche cmdAfficher festgelegt ist. Der Ereignishandler der Komponente cmdAfficher hätte durch cmdAfficher.addActionListener(new Handler()) deklariert werden, wobei gestionnaire eine Klasse mit einer öffentlichen Methode actionPerformed wäre, die für die Verarbeitung des Klicks auf die Schaltfläche Afficher zuständig ist. Hier verwendet JBuilder als Handler eine Instanz einer anonymen Klasse:
new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
Es wird eine neue Instanz der Schnittstelle ActionListener erstellt, deren Methode actionPerformed im Anschluss definiert wird. Diese ruft lediglich eine Methode der Klasse interface2 auf. All dies ist lediglich ein Kunstgriff, um die Ereignisbehandlungsprozeduren der Komponenten dieses Fensters in derselben Klasse wie das Fenster selbst zu definieren. Man könnte auch anders vorgehen:
was dazu führt, dass die Methode actionPerformed in this, also in der Fensterklasse, gesucht wird. Diese zweite Methode scheint einfacher zu sein, doch die erste hat einen Vorteil: Sie ermöglicht es, unterschiedliche Handler für verschiedene Schaltflächen zu verwenden, während dies bei der zweiten Methode nicht möglich ist. Im letzteren Fall muss nämlich die einzige Methode actionPeformed die Klicks verschiedener Schaltflächen verarbeiten und daher zunächst ermitteln, welche Schaltfläche das Ereignis ausgelöst hat, bevor sie mit der Verarbeitung beginnt.
5.2.3.2.3. Die Ereignisbehandler
Es handelt sich um die bereits behandelten:
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
// Klick auf die Schaltfläche „Anzeigen“
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(), "Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
5.2.3.3. Conclusion
Aus den beiden untersuchten Projekten lässt sich schließen, dass die Aufgabe des Entwicklers, sobald die grafische Benutzeroberfläche mit JBuilder erstellt wurde, darin besteht, die Ereignisbehandler zu schreiben, die er für diese grafische Benutzeroberfläche verwalten möchte.
5.2.4. Hilfe suchen
Bei Java benötigt man oft Hilfe, insbesondere aufgrund der sehr großen Anzahl verfügbarer Klassen. Hier geben wir einige Hinweise, wie man Hilfe zu einer Klasse finden kann. Wählen Sie im Menü die Option „Hilfe/Hilfethemen“.

Der Hilfebildschirm besteht in der Regel aus zwei Fenstern:
- das linke, in dem man angibt, wonach man sucht. Es verfügt über drei Registerkarten: Sommaire, Index und Chercher.
- das rechte Fenster, in dem das Suchergebnis angezeigt wird
Es gibt eine Hilfe zur Verwendung der JBuilder-Hilfe. Wählen Sie in der JBuilder-Hilfe die Option „Hilfe/Verwendung der Hilfe“. Dort wird Ihnen erklärt, wie Sie die Hilfe nutzen können. Beispielsweise werden Ihnen die verschiedenen Komponenten des Hilfe-Viewers vorgestellt:

Sehen wir uns die Seiten Sommaire und Index etwas genauer an.
5.2.4.1. Hilfe: Inhaltsverzeichnis

5.2.4.1.1. Inhaltsverzeichnis: Einführung in Java
Hier finden sich die Grundlagen von Java, aber nicht nur das, wie die Liste der in dieser Option behandelten Themen zeigt:

5.2.4.1.2. Inhaltsverzeichnis: Tutorials
Wenn wir im obigen Inhaltsverzeichnis die Option „Tutorials“ auswählen, zeigt das rechte Fenster eine Liste der verfügbaren Tutorials an:

Die grundlegenden Tutorials sind besonders interessant, um sich mit JBuilder vertraut zu machen. Es gibt noch viele weitere neben den oben vorgestellten, und wenn man eine Anwendung entwickeln möchte, kann es hilfreich sein, vorher zu prüfen, ob es nicht ein Tutorial gibt, das einem dabei helfen könnte.
5.2.4.1.3. Inhaltsverzeichnis: JDK
Wenn man die Option „Java 2 JDK 1.3“ auswählt, erhält man Zugriff auf alle Bibliotheken von JDK. Im Allgemeinen sollte man hier nicht suchen, wenn man Informationen zu einer bestimmten Klasse benötigt und nicht weiß, in welcher Bibliothek sie sich befindet. Diese Option ist jedoch interessant, wenn man sich einen Überblick über die Java-Bibliotheken verschaffen möchte.
5.2.4.2. Hilfe: Index
Wählen Sie in der Hilfe die Registerkarte „Index“ im linken Fenster aus. Mit dieser Option können Sie beispielsweise Hilfe zu einer Klasse finden. Nehmen wir an, Sie möchten die Methoden der Eingabefelder swing und JTextField kennenlernen. Geben Sie „JTextField“ in das Suchfeld ein:
![]()
Die Hilfe zeigt die Indexeinträge an, die mit dem eingegebenen Text beginnen:

Nun müssen Sie nur noch auf den Eintrag doppelklicken, der Sie interessiert, in diesem Fall „JTextField class“. Die Hilfe zu dieser Klasse wird dann im rechten Fenster angezeigt:

Sie erhalten nun eine vollständige Beschreibung der Klasse.
5.2.5. Einige Swing-Komponenten
Im Folgenden stellen wir verschiedene Anwendungen vor, bei denen die gängigsten Komponenten swing zum Einsatz kommen, um deren wichtigste Methoden und Eigenschaften kennenzulernen. Für jede Anwendung präsentieren wir die grafische Benutzeroberfläche und den relevanten Code, insbesondere den der Ereignisbehandler.
5.2.5.1. Komponenten JLabel und JTextField
Diese beiden Komponenten haben wir bereits kennengelernt. JLabel ist eine Textkomponente und JTextField eine Eingabefeldkomponente. Ihre beiden wichtigsten Methoden sind
String getText() | , um den Inhalt des Eingabefelds oder den Beschriftungstext abzurufen |
void setText(String unTexte) | um unTexte in das Feld oder die Beschriftung einzufügen |
Die üblicherweise für JTextField verwendeten Ereignisse sind die folgenden:
actionPerformed | signalisiert, dass der Benutzer den eingegebenen Text bestätigt hat (Enter-Taste) |
caretUpdate | signalisiert, dass der Benutzer den Eingabecursor bewegt hat |
inputMethodChanged | zeigt an, dass der Benutzer das Eingabefeld geändert hat |
Hier ist ein Beispiel, das das Ereignis caretUpdate verwendet, um die Änderungen in einem Eingabefeld zu verfolgen:

Nr. | Typ | Name | Rolle |
1 | JTextField | txtSaisie | Eingabefeld |
2 | JTextField | txtControle | zeigt den Text von 1 in Echtzeit an |
3 | JButton | cmdEffacer | zum Löschen der Felder 1 und 2 |
4 | JButton | cmdQuitter | um die Anwendung zu beenden |
Der relevante Code dieser Anwendung lautet wie folgt:
import java.awt.*;
....
public class Cadre1 extends JFrame {
JPanel contentPane;
JTextField txtSaisie = new JTextField();
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JTextField txtControle = new JTextField();
JButton CmdEffacer = new JButton();
JButton CmdQuitter = new JButton();
/**Rahmen erstellen*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
....
txtSaisie.addCaretListener(new javax.swing.event.CaretListener() {
public void caretUpdate(CaretEvent e) {
txtSaisie_caretUpdate(e);
}
});
...
CmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
CmdEffacer_actionPerformed(e);
}
});
...
CmdQuitter.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
CmdQuitter_actionPerformed(e);
}
});
....
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_caretUpdate(CaretEvent e) {
// Der Eingabecursor hat sich bewegt
txtControle.setText(txtSaisie.getText());
}
void CmdQuitter_actionPerformed(ActionEvent e) {
// Die Anwendung wird beendet
System.exit(0);
}
void CmdEffacer_actionPerformed(ActionEvent e) {
// Der Inhalt des Eingabefelds wird gelöscht
txtSaisie.setText("");
}
}
Hier ein Ausführungsbeispiel:

5.2.5.2. Komponente JComboBox


Eine Komponente vom Typ JComboBox ist eine Dropdown-Liste mit einem Eingabefeld: Der Benutzer kann entweder ein Element aus (2) auswählen oder Text in (1) eingeben. Standardmäßig sind die JComboBox-Komponenten nicht bearbeitbar. Um sie bearbeitbar zu machen, muss die Methode setEditable(true) explizit aufgerufen werden. Um mehr über die Klasse JComboBox zu erfahren, geben Sie JComboBox in den Hilfe-Index ein.
Das Objekt JComboBox kann auf verschiedene Arten instanziiert werden:
new JComboBox() | erstellt ein leeres Kombinationsfeld |
new JComboBox (Object[] items) | erstellt ein Kombinationsfeld, das ein Array von Objekten enthält |
new JComboBox(Vector items) | dasselbe mit einem Vektor von Objekten |
Es mag überraschen, dass ein Kombinationsfeld Objekte enthalten kann, obwohl es üblicherweise Zeichenfolgen enthält. Optisch ist dies der Fall. Wenn ein JComboBox ein Objekt obj enthält, wird die Zeichenfolge obj.toString angezeigt() an. Man erinnere sich daran, dass jedes Objekt eine Methode toString besitzt, die von der Klasse Object geerbt wurde und eine Zeichenkette zurückgibt, die das Objekt „repräsentativ“ darstellt.
Die nützlichen Methoden der Klasse JCombobox sind die folgenden:
void addItem(Object unObjet) | fügt ein Objekt zur Combobox hinzu |
int getItemCount() | gibt die Anzahl der Elemente in der Combobox zurück |
Object getItemAt(int i) | gibt das Objekt Nr. i aus der Combobox zurück |
void insertItemAt(Object unObjet, int i) | fügt unObjet an Position i in das Kombinationsfeld ein |
int getSelectedIndex() | gibt die Nummer des in der Combobox ausgewählten Elements zurück |
Object getSelectedItem() | gibt das in der Combobox ausgewählte Objekt zurück |
void setSelectedIndex(int i) | wählt das Element i aus der Combobox aus |
void setSelectedItem(Object unObjet) | wählt das angegebene Objekt aus der Combobox aus |
void removeAllItems() | leert das Kombinationsfeld |
void removeItemAt(int i) | entfernt das Element Nr. i aus der Combobox |
void removeItem(Object unObjet) | entfernt das angegebene Objekt aus der Combobox |
void setEditable(boolean val) | macht das Kombinationsfeld bearbeitbar (val=true) oder nicht bearbeitbar (val=false) |
Bei der Auswahl eines Elements aus der Dropdown-Liste wird das Ereignis actionPerformed ausgelöst, das genutzt werden kann, um über die Änderung der Auswahl in der Combobox informiert zu werden. In der folgenden Anwendung verwenden wir dieses Ereignis, um das aus der Liste ausgewählte Element anzuzeigen.

Wir zeigen hier nur den relevanten Code des Fensters.
public class Cadre1 extends JFrame {
JPanel contentPane;
JComboBox jComboBox1 = new JComboBox();
JLabel jLabel1 = new JLabel();
/**Rahmen erstellen*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// Verarbeitung – das Kombinationsfeld wird ausgefüllt
String[] infos={"un","deux","trois","quatre"};
for(int i=0;i<infos.length;i++)
jComboBox1.addItem(infos[i]);
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
....
jComboBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jComboBox1_actionPerformed(e);
}
});
....
}
void jComboBox1_actionPerformed(ActionEvent e) {
// Ein neues Element wurde ausgewählt – es wird angezeigt
JOptionPane.showMessageDialog(this,jComboBox1.getSelectedItem(),
"actionPerformed",JOptionPane.INFORMATION_MESSAGE);
}
}
5.2.5.3. Komponente JList
Die Swing-Komponente JList ist komplexer als ihr Pendant aus der Bibliothek, awt. Es gibt zwei wesentliche Unterschiede:
- Der Inhalt der Liste wird von einem anderen Objekt als der Liste selbst verwaltet. Hier verwenden wir ein Objekt DefaultListModel, das wie ein Vector verwendet wird, das jedoch zusätzlich das Objekt JList benachrichtigt, sobald sich sein Inhalt ändert, damit sich auch die visuelle Darstellung der Liste entsprechend ändert.
- Die Liste ist standardmäßig nicht scrollbar. Man muss die Liste in einen Container ScrollPane einfügen, der das Scrollen ermöglicht.
Im Quellcode kann eine Liste wie folgt definiert werden:
// Der Vektor der Werte der Liste
DefaultlistModel valeurs=new DefaultListModel();
// die Liste selbst, der der Vektor ihrer Werte zugeordnet wird
JList jList1 = new JList(valeurs);
// der scrollbare Container, in den die Liste eingefügt wird, um eine scrollbare Liste zu erhalten
JScrollPane jScrollPane1 = new JScrollPane(jList1);
Um die Liste jList1 in den Container jScrollPane1 aufzunehmen, geht der von JBuilder generierte Code anders vor:
- Deklaration des Containers in den Attributen des Fensters
- anschließend wird die Liste im Code von jbInit dem Container zugeordnet
Um der oben genannten Liste JList1 Werte hinzuzufügen, müssen diese lediglich in den zugehörigen Wertevektor valeurs eingefügt werden:
und man erhält dann das folgende Fenster:

Wie ist diese Benutzeroberfläche aufgebaut?
- Man wählt eine Komponente JScrollPane auf der Seite „Swing-Container“ der Komponenten aus und zieht sie in das Fenster, wobei man sie auf die gewünschte Größe anpasst
- Man wählt eine Komponente JList auf der Seite „Swing“ der Komponenten aus und zieht sie in den Container JScrollPane, dessen gesamten Platz sie nun einnimmt.
Der von JBuilder generierte Code muss leicht überarbeitet werden, um den folgenden Code zu erhalten:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
DefaultListModel valeurs=new DefaultListModel();
JList jList1 = new JList(valeurs);
JScrollPane jScrollPane1 = new JScrollPane();
JLabel jLabel2 = new JLabel();
/**Rahmen erstellen*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// Verarbeitung
// Die Liste wird in den scrollPane eingebunden
// Liste initialisieren
for(int i=0;i<10;i++)
valeurs.addElement(""+i);
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
....
// Die Liste jList1 ist dem Container jcrollPane1 zugeordnet
jScrollPane1.getViewport().add(jList1, null);
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
....
}
}
Sehen wir uns nun die wichtigsten Methoden der Klasse JList an, indem wir im Hilfeindex nach JList suchen. Das Objekt JList kann auf verschiedene Arten instanziiert werden:

Eine einfache Methode ist die, die wir verwendet haben: Erstellen Sie ein leeres DefaultListModel V und verknüpfen Sie es dann mit der zu erstellenden Liste durch new JList(V). Der Inhalt der Liste wird nicht vom Objekt JList verwaltet, sondern von dem Objekt, das die Werte der Liste enthält. Wenn der Inhalt mithilfe eines Objekts DefaultListModel erstellt wurde, das auf der Klasse Vector basiert, können die Methoden der Klasse Vector verwendet werden, um Elemente zur Liste hinzuzufügen, einzufügen und zu löschen. Eine Liste kann eine Einfach- oder Mehrfachauswahl sein. Dies wird durch die Methode setSelectionMode festgelegt:

Mit getSelectionMode lässt sich der aktuelle Auswahlmodus ermitteln:
![]()
Das oder die ausgewählten Elemente können über die folgenden Methoden abgerufen werden:

Mit dem Konstruktor JList(DefaultListModel) können wir einem Vektor von Werten eine Liste zuordnen. Umgekehrt können wir das Objekt DefaultListModel aus einer Liste JList wie folgt abrufen:

Damit wissen wir genug, um die folgende Anwendung zu schreiben:

Dieses Fenster besteht aus folgenden Komponenten:
Nr. | Typ | Name | Funktion |
1 | JTextField | txtSaisie | Eingabefeld |
2 | JList | jList1 | Liste in einem Container jScrollPane1 |
3 | JList | jList2 | Liste in einem Container jScrollPane2 |
4 | JButton | cmd1To2 | überträgt die ausgewählten Elemente aus Liste 1 in Liste 2 |
5 | JButton | cmd2To1 | führt den umgekehrten Vorgang aus |
6 | JButton | cmdRaz1 | Liste 1 leeren |
7 | JButton | cmdRaz2 | Leert Liste 2 |
Der Benutzer gibt Text in das Feld (1) ein und bestätigt die Eingabe. Daraufhin wird das Ereignis actionPerformed im Eingabefeld ausgelöst, das dazu dient, den eingegebenen Text in Liste 1 hinzuzufügen. Hier ist der Code für diese erste Funktion:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**Rahmen erstellen*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**Komponente initialisieren*/
private void jbInit() throws Exception {
...
txtSaisie.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtSaisie_actionPerformed(e);
}
});
...
// Jlist1 wird in den Container jScrollPane1 eingefügt
jScrollPane1.getViewport().add(jList1, null);
// Jlist2 wird in den Container jScrollPane2 eingefügt
jScrollPane2.getViewport().add(jList2, null);
...
}
/**Ersetzt, damit wir das Fenster schließen können, wenn es geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_actionPerformed(ActionEvent e) {
// Der eingegebene Text wurde validiert
// Er wird ohne führende und abschließende Leerzeichen abgerufen
String texte=txtSaisie.getText().trim();
// Wenn er leer ist, wird er verworfen
if(texte.equals("")){
// Fehlermeldung
JOptionPane.showMessageDialog(this,"Vous devez taper un texte",
"Erreur",JOptionPane.WARNING_MESSAGE);
// Ende
return;
}//if
// wenn er nicht leer ist, wird er zu den Werten in Liste 1 hinzugefügt
v1.addElement(texte);
// und das Eingabefeld wird geleert
txtSaisie.setText("");
}/// txtSaisie_actionperformed
}//Klasse
Der Code zum Übertragen der ausgewählten Elemente von einer Liste in die andere lautet wie folgt:
void cmd1To2_actionPerformed(ActionEvent e) {
// Übertragung der in Liste 1 ausgewählten Elemente in Liste 2
transfert(jList1,jList2);
}//cmd1To2
void cmd2To1_actionPerformed(ActionEvent e) {
// Übertragung der ausgewählten Elemente aus jList2 nach jList1
transfert(jList2,jList1);
}//cmd2TO1
private void transfert(JList L1, JList L2){
// Übertragung der in Liste 1 ausgewählten Elemente in Liste 2
// Das Array mit den Indizes der ausgewählten Elemente wird in L1 abgerufen
int[] indices=L1.getSelectedIndices();
// Was ist zu tun?
if (indices.length==0) return;
// Die Werte aus L1 werden abgerufen
DefaultListModel v1=(DefaultListModel)L1.getModel();
// sowie die aus L2
DefaultListModel v2=(DefaultListModel)L2.getModel();
for(int i=indices.length-1;i>=0;i--){
// Die in L1 ausgewählten Werte werden zu L2 hinzugefügt
v2.addElement(v1.elementAt(indices[i]));
// Die aus L1 in L2 kopierten Elemente müssen aus L1 gelöscht werden
v1.removeElementAt(indices[i]);
}//für
}//Übertragung
Der zu den Schaltflächen Raz gehörende Code ist äußerst einfach:
void cmdRaz1_actionPerformed(ActionEvent e) {
// Liste 1 leeren
v1.removeAllElements();
}//Befehl „Raz1“
void cmdRaz2_actionPerformed(ActionEvent e) {
// Liste 2 leeren
v2.removeAllElements();
}///Befehl Raz2
5.2.5.4. Kontrollkästchen JCheckBox, Optionsfelder JButtonRadio
Wir wollen die folgende Anwendung schreiben:

Das Fenster enthält folgende Komponenten:
Nr. | Typ | Name | Funktion |
1 | JButtonRadio | jButtonRadio1 jButtonRadio2 jButtonRadio3 | 3 Optionsfelder, die zur Gruppe buttonGroup1 gehören |
2 | JCheckBox | jCheckBox1 jCheckBox2 jCheckBox3 | 3 Kontrollkästchen |
3 | JList | jList1 | eine Liste in einem Container jScrollPane1 |
4 | ButtonGroup | buttonGroup1 | Nicht sichtbare Komponente – dient dazu, die drei Optionsfelder so zu gruppieren, dass beim Aktivieren eines davon die anderen deaktiviert werden. |
Eine Gruppe von Optionsfeldern lässt sich wie folgt erstellen:
- Man platziert die einzelnen Optionsfelder, ohne darauf zu achten, sie zu gruppieren
- Man fügt in den Container eine Swing-Komponente ButtonGroup ein. Diese Komponente ist nicht sichtbar. Sie erscheint daher nicht im Fenster-Designer. Sie ist jedoch in der Struktur sichtbar:

Oben im Zweig „Autre“ sind die nicht-visuellen Attribute des Fensters zu sehen. Sobald eine Gruppe von Optionsfeldern erstellt wurde, kann man ihr jedes der Optionsfelder zuordnen. Dazu wählt man die Eigenschaften des Optionsfelds aus:

und in der Eigenschaft buttonGroup des Optionsfelds gibt man den Namen der Gruppe ein, in die das Optionsfeld eingefügt werden soll, hier buttonGroup1. Diesen Vorgang wiederholt man für alle drei Optionsfelder.
Die wichtigste Methode für Optionsfelder und Kontrollkästchen ist die Methode isSelected(), die angibt, ob das Kontrollkästchen oder das Optionsfeld aktiviert ist. Der der Komponente zugeordnete Text kann mit getText() abgerufen und mit setText(String unTexte) festgelegt werden. Das Kontrollkästchen bzw. die Optionsschaltfläche kann mit der Methode setSelected(boolean value) aktiviert werden.
Beim Klicken auf ein Optionsfeld oder ein Kontrollkästchen wird das Ereignis actionPerformed ausgelöst. Im folgenden Code nutzen wir dieses Ereignis, um die Wertänderungen bei Optionsfeldern und Kontrollkästchen zu verfolgen:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JRadioButton jRadioButton1 = new JRadioButton();
JRadioButton jRadioButton2 = new JRadioButton();
JRadioButton jRadioButton3 = new JRadioButton();
JCheckBox jCheckBox1 = new JCheckBox();
JCheckBox jCheckBox2 = new JCheckBox();
JCheckBox jCheckBox3 = new JCheckBox();
ButtonGroup buttonGroup1 = new ButtonGroup();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel valeurs=new DefaultListModel();
JList jList1 = new JList(valeurs);
/**Rahmen erstellen*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
jRadioButton1.setSelected(true);
jRadioButton1.setText("un");
jRadioButton1.setBounds(new Rectangle(57, 31, 49, 23));
jRadioButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton2.setBounds(new Rectangle(113, 30, 49, 23));
jRadioButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton2.setText("deux");
jRadioButton3.setBounds(new Rectangle(168, 30, 49, 23));
jRadioButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton3.setText("trois");
// Die Optionsfelder sind gruppiert
buttonGroup1.add(jRadioButton1);
buttonGroup1.add(jRadioButton2);
buttonGroup1.add(jRadioButton3);
// Kontrollkästchen
jCheckBox1.setText("A");
jCheckBox1.setBounds(new Rectangle(58, 69, 32, 17));
jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
jCheckBox2.setBounds(new Rectangle(112, 69, 40, 17));
jCheckBox2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
jCheckBox2.setText("B");
jCheckBox3.setText("C");
jCheckBox3.setBounds(new Rectangle(170, 69, 37, 17));
jCheckBox3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
....
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
...
}
private void afficheRadioButtons(ActionEvent e){
// zeigt die Werte der 3 Optionsfelder an
valeurs.addElement("boutons radio=("+jRadioButton1.isSelected()+","+
jRadioButton2.isSelected()+","+jRadioButton3.isSelected()+")");
}//afficheRadioButtons
void afficheCases(ActionEvent e) {
// zeigt die Werte der Kontrollkästchen an
valeurs.addElement("cases à cocher=["+jCheckBox1.isSelected()+","+
jCheckBox2.isSelected()+","+jCheckBox3.isSelected()+")");
}//afficheCases
}//sortiert
Hier ein Ausführungsbeispiel:

5.2.5.5. Komponente JScrollBar
Lassen Sie uns die folgende Anwendung erstellen:

Nr. | Typ | Name | Rolle |
1 | JScrollBar | jScrollBar1 | ein horizontaler Regler |
2 | JScrollBar | jScrollBar2 | ein vertikaler Regler |
3 | JTextField | txtvaleurHS | zeigt den Wert des horizontalen Reglers 1 an – ermöglicht auch die Festlegung dieses Werts |
4 | JTextField | txtvaleurVS | zeigt den Wert des vertikalen Reglers 2 an – ermöglicht auch die Festlegung dieses Werts |
- Ein Schieberegler vom Typ JScrollBar ermöglicht es dem Benutzer, einen Wert aus einem Bereich ganzer Zahlen auszuwählen, der durch den „Streifen“ des Schiebereglers symbolisiert wird, auf dem sich ein Cursor bewegt.
- Bei einem horizontalen Schieberegler stellt das linke Ende den Minimalwert des Bereichs dar, das rechte Ende den Maximalwert und der Schieberegler den aktuell gewählten Wert. Bei einem vertikalen Schieberegler wird der Minimalwert durch das obere Ende und der Maximalwert durch das untere Ende dargestellt. Das Paar (min, max) ist standardmäßig auf (0, 100) gesetzt.
- Ein Klick auf die Endpunkte des Schiebereglers verändert den Wert um einen Schritt (positiv oder negativ), je nach dem angeklickten Endpunkt, der als unitIncrement bezeichnet wird und standardmäßig den Wert 1 hat.
- Ein Klick auf beiden Seiten des Schiebereglers verändert den Wert um einen Schritt (positiv oder negativ), je nach dem angeklickten Ende, das als blockIncrement bezeichnet wird und standardmäßig den Wert 10 hat.
- Diese fünf Werte (min, max, Wert, unitIncrement, blockIncrement) können mit den Methoden getMinimum(), getMaximum(), getValue(), getUnitIncrement() und getBlockIncrement() ermittelt werden, die alle eine Ganzzahl zurückgeben und über die Methoden setMinimum(int min), setMaximum(int max), setValue(int val), setUnitIncrement(int uInc), setBlockIncrement(int bInc)
Bei der Verwendung der Komponente JScrollBar sind einige Punkte zu beachten. Zunächst einmal findet man sie in der Swing-Komponentenleiste:

Wenn man sie auf den Container zieht, ist sie standardmäßig vertikal ausgerichtet. Mit der unten aufgeführten Eigenschaft orientation lässt sie sich horizontal ausrichten:

Im obigen Eigenschaftenblatt sieht man, dass man Zugriff auf die Eigenschaften minimum, maximum, value, unitIncrement, blockIncrement des JScrollbar. Diese können daher bereits beim Entwurf festgelegt werden. Wenn man eine Bildlaufleiste auf dem Container platziert, wird deren „Einstellbereich“ nicht angezeigt:

Dieses Problem lässt sich beheben, indem man der Komponente einen Rahmen zuweist. Dies geschieht über die Eigenschaft border, die verschiedene Werte annehmen kann:

So sieht es beispielsweise mit RaisedBevel aus:
![]()
Wenn man auf das obere Ende eines vertikalen Schiebereglers klickt, verringert sich dessen Wert. Dies kann den durchschnittlichen Benutzer überraschen, der normalerweise erwartet, dass der Wert „steigt“. Dieses Problem lässt sich beheben, indem man den Werten unitIncrement und blockIncrement einen negativen Wert zuweist.
Wie lässt sich die Wertentwicklung eines Schiebereglers verfolgen? Wenn sich dessen Wert ändert, wird das Ereignis adjustmentValueChanged ausgelöst. Es reicht aus, diesem Ereignis eine Prozedur zuzuordnen, um über jede Änderung des Wertes des Schiebereglers informiert zu werden.

Der relevante Code unserer Anwendung lautet wie folgt:
....
public class cadreAppli extends JFrame {
JPanel contentPane;
JScrollBar jScrollBar1 = new JScrollBar();
Border border1;
JTextField txtValeurHS = new JTextField();
JScrollBar jScrollBar2 = new JScrollBar();
JTextField txtValeurVS = new JTextField();
TitledBorder titledBorder1;
/**Rahmen erstellen*/
public cadreAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
...
// einen Rahmen für die Bildlaufleisten
border1 = BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.white,Color.white,new Color(134, 134, 134),new Color(93, 93, 93));
// kein Titel in der Umrandung
titledBorder1 = new TitledBorder("");
jScrollBar1.setOrientation(JScrollBar.HORIZONTAL);
jScrollBar1.setBorder(BorderFactory.createRaisedBevelBorder());
jScrollBar1.setAutoscrolls(true);
jScrollBar1.setBounds(new Rectangle(37, 17, 218, 20));
jScrollBar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
jScrollBar1_adjustmentValueChanged(e);
}
});
txtValeurHS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtValeurHS_actionPerformed(e);
}
});
jScrollBar2.setBounds(new Rectangle(39, 51, 30, 27));
jScrollBar2.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
jScrollBar2_adjustmentValueChanged(e);
}
});
jScrollBar2.setAutoscrolls(true);
jScrollBar2.setUnitIncrement(-1);
jScrollBar2.setBorder(BorderFactory.createRaisedBevelBorder());
txtValeurVS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtValeurVS_actionPerformed(e);
}
});
......
}
/**Ersetzt, damit wir das Fenster beim Schließen verlassen können*/
protected void processWindowEvent(WindowEvent e) {
...
}
void jScrollBar1_adjustmentValueChanged(AdjustmentEvent e) {
// Der Wert von Bildlaufleiste 1 hat sich geändert
txtValeurHS.setText(""+jScrollBar1.getValue());
}
void jScrollBar2_adjustmentValueChanged(AdjustmentEvent e) {
// Der Wert von Bildlaufleiste 2 hat sich geändert
txtValeurVS.setText(""+jScrollBar2.getValue());
}
void txtValeurHS_actionPerformed(ActionEvent e) {
// Der Wert der horizontalen Bildlaufleiste wird festgelegt
setValeur(jScrollBar1,txtValeurHS);
}
void txtValeurVS_actionPerformed(ActionEvent e) {
// Der Wert der vertikalen Bildlaufleiste wird festgelegt
setValeur(jScrollBar2,txtValeurVS);
}
private void setValeur(JScrollBar jS, JTextField jT){
// Der Wert der Bildlaufleiste jS wird mit dem Text aus dem Feld jT festgelegt
int valeur=0;
try{
valeur=Integer.parseInt(jT.getText());
jS.setValue(valeur);
}
catch (Exception e){
// Der Fehler wird angezeigt
afficher(""+e);
}//try-catch
}//setValeur
void afficher(String message){
// zeigt eine Meldung in einem Dialogfeld an
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//anzeigen
}
Hier ein Ausführungsbeispiel:

5.2.5.6. Komponente JTextArea
Die Komponente JTextArea ist eine Komponente, in die mehrere Textzeilen eingegeben werden können, im Gegensatz zur Komponente JTextField, in die nur eine Zeile eingegeben werden kann. Wird diese Komponente in einen scrollbaren Container (JScrollPane) eingefügt, entsteht ein scrollbares Texteingabefeld. Diese Art von Komponente könnte beispielsweise in einer E-Mail-Anwendung vorkommen, in der der Text der zu versendenden Nachricht in eine Komponente JTextArea eingegeben wird. Die üblichen Methoden sind String getText(), um den Inhalt des Textfelds abzurufen, setText(String unTexte), um unTexte in das Textfeld einzufügen, sowie append(String unTexte), um unTexte an den bereits im Textfeld vorhandenen Text anzuhängen. Betrachten wir die folgende Anwendung:

Nr. | Typ | Name | Rolle |
1 | JTextArea | txtTexte | ein mehrzeiliges Textfeld |
2 | JButton | cmdAfficher | zeigt den Inhalt von 1 in einem Dialogfeld an |
3 | JButton | cmdEffacer | löscht den Inhalt von 1 |
4 | JTextField | txtAjout | Text, der dem Text von 1 hinzugefügt wird, wenn er mit der Eingabetaste bestätigt wird. |
5 | JScrollPane | jScrollPane1 | Scrollbarer Container, in den Textfeld 1 eingefügt wurde, um ein scrollbares Textfeld zu erhalten. |
Der entsprechende Code lautet wie folgt:
.....
public class cadreAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JButton cmdAfficher = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
JTextArea txtTexte = new JTextArea();
JLabel jLabel2 = new JLabel();
JTextField txtAjout = new JTextField();
JButton cmdEffacer = new JButton();
/**Rahmen erstellen*/
public cadreAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
txtAjout.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtAjout_actionPerformed(e);
}
});
cmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdEffacer_actionPerformed(e);
}
});
.......
jScrollPane1.getViewport().add(txtTexte, null);
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
........
}
void cmdAfficher_actionPerformed(ActionEvent e) {
// zeigt den Inhalt von TextArea an
afficher(txtTexte.getText());
}
void afficher(String message){
// zeigt eine Meldung in einem Dialogfeld an
JOptionPane.showMessageDialog(this,message,"Suivi",JOptionPane.INFORMATION_MESSAGE);
}// anzeigen
void cmdEffacer_actionPerformed(ActionEvent e) {
txtTexte.setText("");
}//cmdEffacer_actionPerformed
void txtAjout_actionPerformed(ActionEvent e) {
// Text hinzufügen
txtTexte.append(txtAjout.getText());
// Leeren und Hinzufügen
txtAjout.setText("");
}//
}
5.2.6. Mausereignisse
Wenn man in einem Container zeichnet, ist es wichtig, die Position der Maus zu kennen, um beispielsweise bei einem Klick einen Punkt anzuzeigen. Mausbewegungen lösen Ereignisse in dem Container aus, in dem sich die Maus bewegt. Hier sind zum Beispiel die von JBuilder für einen Container JPanel angebotenen Ereignisse:

mouseClicked | Mausklick |
mouseDragged | Maus bewegt sich, linke Maustaste gedrückt |
mouseEntered | Die Maus hat gerade den Bereich des Containers betreten |
mouseExited | Die Maus hat gerade den Bereich des Containers verlassen |
mouseMoved | Die Maus bewegt sich |
mousePressed | Druck auf die linke Maustaste |
mouseReleased | Loslassen der linken Maustaste |
Hier ist ein Programm, mit dem Sie besser verstehen können, wann die verschiedenen Mausereignisse auftreten:

Nr. | Typ | Name | Rolle |
1 | JTextField | txtPosition | um die Mausposition im Container anzuzeigen (ggf. MouseMoved) |
2 | JList | lstAffichage | um andere Mausereignisse als MouseMoved anzuzeigen |
3 | JButton | cmdEffacer | um den Inhalt von 2 zu löschen |
Wenn man dieses Programm ausführt, erhält man bei einem Klick folgende Ausgabe:

Die Ereignisse werden in der Liste von oben nach unten gestapelt. Der obige Screenshot zeigt also, dass ein Klick drei Ereignisse auslöst, und zwar in folgender Reihenfolge:
- MousePressed beim Drücken der Schaltfläche
- MouseReleased beim Loslassen
- MouseClicked, was bedeutet, dass die Abfolge der beiden vorherigen Ereignisse als Klick gewertet wird. Dies könnte ein Doppelklick sein. Die obige Information clickCount=1 zeigt jedoch an, dass es sich um einen einfachen Klick handelt.
Wenn man nun die Taste drückt, die Maus bewegt und die Taste loslässt:

Hier sieht man die drei Ereignisse:
- MousePressed beim anfänglichen Drücken der Taste
- MouseDragged beim Bewegen der Maus bei gedrückter Taste
- MouseReleased beim Loslassen der Taste
In den beiden obigen Beispielen sieht man, dass ein Mausereignis verschiedene Informationen mit sich bringt, darunter die (x,y)-Koordinaten der Maus, zum Beispiel (408,65) in der ersten Zeile oben.
Fährt man so fort, stellt man fest, dass das Ereignis MouseExited ausgelöst wird, sobald die Maus den Container verlässt oder über eine seiner Komponenten fährt. Im letzteren Fall erhält der Container das Ereignis MouseExited und die Komponente das Ereignis MouseEntered. Das Gegenteil tritt ein, wenn die Maus die Komponente verlässt und wieder auf den Container zurückkehrt.
Was passiert bei einem Doppelklick?

Es treten genau dieselben Ereignisse auf wie bei einem einfachen Klick. Lediglich enthält das Ereignis die Information clickCount=2 (siehe oben), die angibt, dass es sich tatsächlich um einen Doppelklick handelt.
Der relevante Code dieser Anwendung lautet wie folgt:
public class Cadre1 extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JTextField txtPosition = new JTextField();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel valeurs=new DefaultListModel();
JList lstAffichage = new JList(valeurs);
JButton cmdEffacer = new JButton();
/**Rahmen erstellen*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
contentPane.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
contentPane_mouseMoved(e);
}
public void mouseDragged(MouseEvent e) {
contentPane_mouseDragged(e);
}
});
contentPane.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(MouseEvent e) {
contentPane_mouseEntered(e);
}
public void mouseExited(MouseEvent e) {
contentPane_mouseExited(e);
}
public void mousePressed(MouseEvent e) {
contentPane_mousePressed(e);
}
public void mouseClicked(MouseEvent e) {
contentPane_mouseClicked(e);
}
public void mouseReleased(MouseEvent e) {
contentPane_mouseReleased(e);
}
});
cmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdEffacer_actionPerformed(e);
}
});
jScrollPane1.getViewport().add(lstAffichage, null);
...............
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
.........
}
void contentPane_mouseMoved(MouseEvent e) {
txtPosition.setText("("+e.getX()+","+e.getY()+")");
}
void contentPane_mouseDragged(MouseEvent e) {
afficher(e);
}
void contentPane_mouseEntered(MouseEvent e) {
afficher(e);
}
void afficher(MouseEvent e){
// zeigt das Ereignis in der Liste an lstAffichage
valeurs.insertElementAt(e,0);
}
void contentPane_mouseExited(MouseEvent e) {
afficher(e);
}
void contentPane_mousePressed(MouseEvent e) {
afficher(e);
}
void contentPane_mouseClicked(MouseEvent e) {
afficher(e);
}
void contentPane_mouseReleased(MouseEvent e) {
afficher(e);
}
void cmdEffacer_actionPerformed(ActionEvent e) {
// löscht die Liste
valeurs.removeAllElements();
}
}
5.2.7. Ein Fenster mit Menü erstellen
Schauen wir uns nun an, wie man mit JBuilder ein Fenster mit Menü erstellt. Wir werden das folgende Fenster erstellen:


Erstellen Sie ein neues Projekt mit einem leeren Fenster als Ausgangspunkt. Wählen Sie aus der Liste der Komponenten unter „Swing-Container“ die Komponente JMenuBar (siehe Abbildung 1 unten) aus und ziehen Sie sie auf das zu entwerfende Fenster.

Im Entwurfsfenster wird nichts angezeigt, aber die Komponente JMenuBar erscheint im Strukturbereich Ihres Fensters:

Doppelklicken Sie auf das oben genannte Element jMenuBar1, um das Menü im Entwurfsmodus aufzurufen:

1 | Ein Menüelement einfügen |
2 | Trennzeichen einfügen |
3 | Ein verschachteltes Menü einfügen |
4 | Ein Menüelement löschen |
5 | Ein Menüelement deaktivieren |
6 | Menüpunkt zum Ankreuzen |
7 | Optionsfeld umkehren |
Um Ihr erstes Menüelement zu erstellen, geben Sie „Optionen A“ in das Feld A oben ein und anschließend darunter in dieser Reihenfolge: A1, A2, Trennzeichen, A3, A4.

Dann daneben:

Verwenden Sie das Werkzeug 3, um anzugeben, dass B3 ein verschachteltes Untermenü ist.
Im Laufe der Menügestaltung verändert sich die logische Struktur unseres Fensters:

Wenn wir unsere Anwendung nun ausführen, sehen wir ein leeres Fenster ohne Menü. Wir müssen das erstellte Menü unserem Fenster zuordnen. Wählen Sie dazu in der Fensterstruktur das Objekt this aus:

Sie haben nun Zugriff auf die Eigenschaften von this:

Eine davon ist „JMenuBar“, mit der das dem Fenster zugeordnete Menü festgelegt wird. Klicken Sie in die Zelle rechts neben „JMenuBar“. Daraufhin werden Ihnen alle erstellten Menüs zur Auswahl angezeigt. In diesem Fall steht nur jMenuBar1 zur Auswahl. Wählen Sie dieses aus.
Starten Sie die Anwendung (F9):

Nun haben wir ein Menü, aber die Optionen haben vorerst noch keine Funktion. Die Menüoptionen werden wie Komponenten behandelt: Sie verfügen über Eigenschaften und Ereignisse. Wählen Sie in der Menüstruktur die Option jMenuItem1 aus:

Sie haben nun Zugriff auf deren Eigenschaften und Ereignisse:

Wählen Sie die Seite „Ereignisse“ aus und klicken Sie auf die Zelle rechts neben dem Ereignis „actionPerformed“: Dies ist das Ereignis, das ausgelöst wird, wenn auf ein Menüelement geklickt wird. Standardmäßig wird Ihnen eine Verarbeitungsprozedur vorgeschlagen. Doppelklicken Sie darauf, um Zugriff auf den Code zu erhalten:

Wir schreiben den folgenden einfachen Code:
void jMenuItem1_actionPerformed(ActionEvent e) {
afficher("L'option A1 a été sélectionnée");
}
void afficher(String message){
// zeigt eine Meldung in einem Dialogfeld an
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//anzeigen
Führen Sie die Anwendung aus und wählen Sie die Option A1 aus, um die folgende Meldung zu erhalten:

Der relevante Code dieser Anwendung lautet wie folgt:
.....
public class Cadre1 extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenu1 = new JMenu();
JMenuItem jMenuItem1 = new JMenuItem();
JMenuItem jMenuItem2 = new JMenuItem();
JMenuItem jMenuItem3 = new JMenuItem();
JMenuItem jMenuItem4 = new JMenuItem();
JMenu jMenu2 = new JMenu();
JMenuItem jMenuItem5 = new JMenuItem();
JMenuItem jMenuItem6 = new JMenuItem();
JMenu jMenu3 = new JMenu();
JMenuItem jMenuItem7 = new JMenuItem();
JMenuItem jMenuItem8 = new JMenuItem();
JMenuItem jMenuItem9 = new JMenuItem();
/**Rahmen erstellen*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Komponente initialisieren*/
private void jbInit() throws Exception {
// Das Fenster ist mit einem Menü verknüpft
this.setJMenuBar(jMenuBar1);
jMenu1.setText("Options A");
jMenuItem1.setText("A1");
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jMenuItem1_actionPerformed(e);
}
});
jMenuItem2.setText("A2");
jMenuItem3.setText("A3");
jMenuItem4.setText("A4");
jMenu2.setText("Options B");
jMenuItem5.setText("B1");
jMenuItem6.setText("B2");
jMenu3.setText("B3");
jMenuItem7.setText("B31");
jMenuItem8.setText("B32");
jMenuItem9.setText("B4");
jMenuBar1.add(jMenu1);
jMenuBar1.add(jMenu2);
jMenu1.add(jMenuItem1);
jMenu1.add(jMenuItem2);
jMenu1.addSeparator();
jMenu1.add(jMenuItem3);
jMenu1.add(jMenuItem4);
jMenu2.add(jMenuItem5);
jMenu2.add(jMenuItem6);
jMenu2.add(jMenu3);
jMenu2.add(jMenuItem9);
jMenu3.add(jMenuItem7);
jMenu3.add(jMenuItem8);
}
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
....
}
void jMenuItem1_actionPerformed(ActionEvent e) {
afficher("L'option A1 a été sélectionnée");
}
void afficher(String message){
// Zeigt eine Meldung in einem Dialogfeld an
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//anzeigen
}
5.3. Dialogfelder
5.3.1. Meldungsfelder
Wir haben die Klasse JOptionPane bereits zur Anzeige von Meldungen verwendet. So sieht der folgende Code aus:
import javax.swing.*;
public class dialog1 {
public static void main(String arg[]){
JOptionPane.showMessageDialog(null,"Un message","Titre de la boîte",JOptionPane.INFORMATION_MESSAGE);
}
}
erzeugt die Anzeige des folgenden Feldes:

Wenn man dieses Fenster schließt, verschwindet es, aber der Ausführungs-Thread, in dem es lief, wird nicht beendet. Dieses Phänomen tritt normalerweise nicht auf. Die Dialogfelder werden innerhalb einer Anwendung verwendet, die zu einem bestimmten Zeitpunkt die Anweisung System.exit(n) verwendet, um alle Threads zu beenden. Daran werden wir uns in den folgenden Beispielen erinnern, die alle nach dem gleichen Muster aufgebaut sind. Unter DOS kann die Anwendung mit Strg-C unterbrochen werden. Bei JBuilder verwenden wir die Option „Programm ausführen/zurücksetzen“ (Strg-F2). Übrigens ist das erste Argument von showMessageDialog hier null. Im Allgemeinen ist dies jedoch nicht der Fall. Meistens ist es this, wobei this das Hauptfenster der Anwendung bezeichnet.
5.3.2. Darstellung und Handhabung
Das Erscheinungsbild des obigen Fensters könnte anders aussehen. Dieses Erscheinungsbild lässt sich über die Klasse javax.swing.UIManager konfigurieren. Als wir den von JBuilder für unser erstes Fenster generierten Code kommentiert haben, sind wir auf eine Anweisung gestoßen, auf die wir nicht näher eingegangen sind:
Die Methode setLookAndFeel der Klasse UIManager (UI = Benutzeroberfläche) ermöglicht es, das Erscheinungsbild der grafischen Benutzeroberflächen festzulegen. Die Klasse UIManager verfügt über eine Methode, mit der sich die möglichen „Darstellungsformen“ für die Benutzeroberflächen ermitteln lassen:
static UIManager.LookAndFeelInfo[] | getInstalledLookAndFeels() |
Die Methode gibt ein Array von Elementen des Typs LookAndFeelInfo zurück. Diese Klasse verfügt über eine Methode:
String | getClassName() |
die den Namen der Klasse zurückgibt, die ein bestimmtes Erscheinungsbild „implementiert“. Probieren wir das folgende Programm aus:
import javax.swing.*;
public class LookAndFeels {
// zeigt die verfügbaren Look-and-Feels an
public static void main(String[] args) {
// Listet die installierten Look-and-Feels auf
UIManager.LookAndFeelInfo[] lf=UIManager.getInstalledLookAndFeels();
// Anzeige
for(int i=0;i<lf.length;i++){
System.out.println(lf[i].getClassName());
}//für
}//Hauptmenü
}//sortiert
Dies liefert folgende Ergebnisse:
javax.swing.plaf.metal.MetalLookAndFeel
com.sun.java.swing.plaf.motif.MotifLookAndFeel
com.sun.java.swing.plaf.windows.WindowsLookAndFeel
Es scheint also drei verschiedene „Darstellungsvarianten“ zu geben. Kehren wir zu unserem Programm zur Anzeige von Meldungen zurück und probieren wir die verschiedenen möglichen Darstellungsvarianten aus:
import javax.swing.*;
public class LookAndFeel2 {
// zeigt die verfügbaren Look-and-Feels an
public static void main(String[] args) {
// Liste der installierten Look-and-Feels
UIManager.LookAndFeelInfo[] lf=UIManager.getInstalledLookAndFeels();
// Anzeige
for(int i=0;i<lf.length;i++){
// Look-and-Feel-Manager
try{
UIManager.setLookAndFeel(lf[i].getClassName());
}catch(Exception ex){
System.err.println(ex.getMessage());
}//Catch
// Meldung
JOptionPane.showMessageDialog(null,"Un message",lf[i].getClassName(),JOptionPane.INFORMATION_MESSAGE);
}//for
}//main
}//Klasse
Die Ausführung liefert folgende Ausgaben:
![]() | ![]() | ![]() |
die von rechts nach links den „Looks“ Metal, Motif und Windows entsprechen.
5.3.3. Bestätigungsdialoge
Die Klasse JOptionPane verfügt über eine Methode showConfirmDialog zum Anzeigen von Bestätigungsdialogen mit den Schaltflächen Oui, Non, Annuler. Es gibt mehrere überladene Methoden showConfirmDialog. Wir betrachten eine davon:
static int | showConfirmDialog(Component parentComponent, Object message, String title, int optionType) |
parentComponent | die übergeordnete Komponente des Dialogfelds. Oft das Fenster oder der Wert null |
message | Die anzuzeigende Meldung |
title | der Titel des Dialogfelds |
optionType | JOptionPane.YES_NO_OPTION: Schaltflächen „Ja“, „Nein“ JOptionPane.YES_NO_CANCEL_OPTION: Schaltflächen „Ja“, „Nein“, „Abbrechen“ |
Das von der Methode zurückgegebene Ergebnis lautet:
JOptionPane.YES_OPTION | Der Benutzer hat auf „Ja“ geklickt |
JOptionPane.NO_OPTION | Der Benutzer hat auf „Nein“ geklickt |
JOptionPane.CANCEL_OPTION | Der Benutzer hat auf „Abbrechen“ geklickt |
JOptionPane.CLOSED_OPTION | Der Benutzer hat das Fenster geschlossen |
Hier ein Beispiel:
import javax.swing.*;
public class confirm1 {
public static void main(String[] args) {
// zeigt Bestätigungsfelder an
int réponse;
affiche(JOptionPane.showConfirmDialog(null,"Voulez-vous continuer ?","Confirmation",JOptionPane.YES_NO_OPTION));
affiche(JOptionPane.showConfirmDialog(null,"Voulez-vous continuer ?","Confirmation",JOptionPane.YES_NO_CANCEL_OPTION));
}//Hauptprogramm
private static void affiche(int réponse){
// gibt an, welche Art von Antwort man erhalten hat
switch(réponse){
case JOptionPane.YES_OPTION :
System.out.println("Oui");
break;
case JOptionPane.NO_OPTION :
System.out.println("Non");
break;
case JOptionPane.CANCEL_OPTION :
System.out.println("Annuler");
break;
case JOptionPane.CLOSED_OPTION :
System.out.println("Fermeture");
break;
}//-Schalter
}//-Display
}//klassifizieren
![]() | ![]() |
Auf der Konsole werden die Meldungen Non und Annuler angezeigt.
5.3.4. Eingabefeld
Die Klasse JOptionPane bietet zudem die Möglichkeit, eine Eingabe mit der Methode showInputDialog vorzunehmen. Auch hier gibt es mehrere überladene Methoden. Wir stellen eine davon vor:
static String | showInputDialog(Component parentComponent, Object message, String title, int messageType) |
Die Argumente sind die bereits mehrfach erwähnten. Die Methode gibt die vom Benutzer eingegebene Zeichenkette zurück. Hier ein Beispiel:
import javax.swing.*;
public class input1 {
public static void main(String[] args) {
// Eingabe
System.out.println("Chaîne saisie ["+
JOptionPane.showInputDialog(null,"Quel est votre nom","Saisie du nom",JOptionPane.QUESTION_MESSAGE )
+ "]");
}//Hand
}//Klasse
Die Darstellung des Eingabefelds:

Die Konsolenanzeige:
5.4. Auswahlfelder
Wir befassen uns nun mit einer Reihe von vordefinierten Auswahllisten in Java 2:
JFileChooser | Auswahlfeld zum Auswählen einer Datei in der Dateistruktur |
JColorChooser | Auswahlfeld zur Auswahl einer Farbe |
5.4.1. Auswahlfeld JFileChooser
Wir werden die folgende Anwendung erstellen:

Die Steuerelemente sind folgende:
Nr. | Typ | Name | Rolle |
0 | JScrollPane | jScrollPane1 | Scrollbarer Container für Textfeld 1 |
1 | JTextArea selbst im JScrollPane | txtTexte | vom Benutzer eingegebener oder aus einer Datei geladener Text |
2 | JButton | btnSauvegarder | ermöglicht das Speichern des Textes aus 1 in einer Textdatei |
3 | JButton | btnCharger | ermöglicht das Einlesen des Inhalts einer Textdatei in 1 |
4 | JButton | btnEffacer | löscht den Inhalt von 1 |
Es wird ein nicht-visuelles Steuerelement verwendet: jFileChooser1. Dieses wird aus der Swing-Container-Palette von JBuilder entnommen:

Wir platzieren die Komponente im Entwurfsfenster, jedoch außerhalb des Formulars. Sie erscheint in der Komponentenliste:

Wir geben nun den relevanten Programmcode an, um einen Überblick zu erhalten:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
public class dialogues extends JFrame {
// die Rahmenkomponenten
JPanel contentPane;
JButton btnSauvegarder = new JButton();
JButton btnCharger = new JButton();
JButton btnEffacer = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
JTextArea txtTexte = new JTextArea();
JFileChooser jFileChooser1 = new JFileChooser();
// Dateifilter
javax.swing.filechooser.FileFilter filtreTxt = null;
//Rahmen erstellen
public dialogues() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
// weitere Initialisierungen
moreInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
// moreInit
private void moreInit(){
// Initialisierungen beim Erstellen des Fensters
// Filter *.txt
filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
// Wird „f“ akzeptiert?
return f.getName().toLowerCase().endsWith(".txt");
}//akzeptiert
public String getDescription(){
// Beschreibung des Filters
return "Fichiers Texte (*.txt)";
}//getDescription
};
// Der Filter wird hinzugefügt
jFileChooser1.addChoosableFileFilter(filtreTxt);
// man möchte außerdem den Filter für alle Dateien
jFileChooser1.setAcceptAllFileFilterUsed(true);
// Das Startverzeichnis der Box FileChooser wird auf das aktuelle Verzeichnis festgelegt
jFileChooser1.setCurrentDirectory(new File("."));
}
//Die Komponente initialisieren
private void jbInit() throws Exception {
.......................
}
//Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird
protected void processWindowEvent(WindowEvent e) {
......................
}
}
void btnCharger_actionPerformed(ActionEvent e) {
// Auswahl einer Datei mithilfe eines Objekts JFileChooser
// Der anfängliche Filter wird festgelegt
jFileChooser1.setFileFilter(filtreTxt);
// Das Auswahlfeld wird angezeigt
int returnVal = jFileChooser1.showOpenDialog(this);
// Hat der Benutzer etwas ausgewählt?
if(returnVal == JFileChooser.APPROVE_OPTION) {
// Die Datei wird in das Textfeld eingefügt
lireFichier(jFileChooser1.getSelectedFile());
}//if
}//btnCharger_actionPerformed
// lireFichier
private void lireFichier(File fichier){
// zeigt den Inhalt der Textdatei „fichier“ im Textfeld an
// Das Textfeld wird gelöscht
txtTexte.setText("");
// einige Daten
BufferedReader IN=null;
String ligne=null;
try{
// Datei zum Lesen öffnen
IN=new BufferedReader(new FileReader(fichier));
// Die Datei wird zeilenweise gelesen
while((ligne=IN.readLine())!=null){
txtTexte.append(ligne+"\n");
}//while
// Datei schließen
IN.close();
}catch(Exception ex){
// Es ist ein Fehler aufgetreten
txtTexte.setText(""+ex);
}//catch
}
// Löschen
void btnEffacer_actionPerformed(ActionEvent e) {
// Textfeld wird gelöscht
txtTexte.setText("");
}
// speichern
void btnSauvegarder_actionPerformed(ActionEvent e) {
// speichert den Inhalt des Textfelds in einer Datei
// Der anfängliche Filter wird festgelegt
jFileChooser1.setFileFilter(filtreTxt);
// Das Auswahlfeld zum Speichern wird angezeigt
int returnVal = jFileChooser1.showSaveDialog(this);
// Hat der Benutzer etwas ausgewählt?
if(returnVal == JFileChooser.APPROVE_OPTION) {
// Der Inhalt des Textfelds wird in eine Datei geschrieben
écrireFichier(jFileChooser1.getSelectedFile());
}//if
}
// lireFichier
private void écrireFichier(File fichier){
// schreibt den Inhalt des Textfelds in eine Datei
// einige Daten
PrintWriter PRN=null;
try{
// Datei zum Schreiben öffnen
PRN=new PrintWriter(new FileWriter(fichier));
// Der Inhalt des Textfelds wird geschrieben
PRN.print(txtTexte.getText());
// Datei schließen
PRN.close();
}catch(Exception ex){
// Es ist ein Fehler aufgetreten
txtTexte.setText(""+ex);
}//Abfangen
}
Wir werden den Code der Methoden btnEffacer_Click, lireFichier und écrireFichier nicht näher erläutern, da sie nichts Neues enthalten, was nicht bereits behandelt wurde. Wir werden uns mit der Klasse JFileChooser und ihrer Verwendung näher befassen. Diese Klasse ist komplex, fast schon „unübersichtlich“. Wir verwenden hier nur die folgenden Methoden:
addChoosableFilter(FileFilter) | legt die zur Auswahl angebotenen Dateitypen fest |
setAcceptAllFileFilterUsed(boolean) | gibt an, ob der Typ „Alle Dateien“ zur Auswahl angeboten werden soll oder nicht |
File getSelectedFile() | die vom Benutzer ausgewählte Datei (File) |
int showSaveDialog() | Methode, die das Auswahlfeld zum Speichern anzeigt. Gibt ein Ergebnis vom Typ int zurück. Der Wert jFileChooser.APPROVE_OPTION zeigt an, dass der Benutzer eine gültige Auswahl getroffen hat. Andernfalls hat er entweder die Auswahl abgebrochen oder es ist ein Fehler aufgetreten. |
setCurrentDirectory | um das Startverzeichnis festzulegen, von dem aus der Benutzer mit der Erkundung des Dateisystems beginnt |
setFileFilter(FileFilter) | um den aktiven Filter festzulegen |
Die Methode showSaveDialog zeigt ein Auswahlfeld an, das in etwa wie folgt aussieht:

1 | Dropdown-Liste, die mit der Methode addChoosableFilter erstellt wurde. Sie enthält sogenannte Auswahlfilter, die durch die Klasse FileFilter repräsentiert werden. Es ist Aufgabe des Entwicklers, diese Filter zu definieren und zur Liste 1 hinzuzufügen. |
2 | Aktuelles Verzeichnis, festgelegt durch die Methode setCurrentDirectory, sofern diese Methode verwendet wurde; andernfalls ist das aktuelle Verzeichnis unter Windows der Ordner „Eigene Dateien“ oder unter Unix das Home-Verzeichnis. |
3 | Name der ausgewählten oder vom Benutzer direkt eingegebenen Datei. Wird mit der Methode getSelectedFile() bereitgestellt |
4 | Schaltflächen „Speichern“/„Abbrechen“. Wenn die Schaltfläche Enregistrer verwendet wird, liefert die Methode showSaveDialog das Ergebnis jFileChooser.APPROVE_OPTION |
Wie werden die Dateifilter der Dropdown-Liste 1 erstellt? Die Filter werden mithilfe der folgenden Methode zur Liste 1 hinzugefügt:
addChoosableFilter(FileFilter) | legt die zur Auswahl angebotenen Dateitypen fest |
der Klasse JFileChooser. Nun müssen wir noch die Klasse FileFilter kennenlernen. Dabei handelt es sich eigentlich um die Klasse javax.swing.filechooser.FileFilter, die eine abstrakte Klasse ist, c.a.d – eine Klasse, die nicht instanziiert, sondern nur abgeleitet werden kann. Sie ist wie folgt definiert:
FileFilter() | Konstruktor |
boolean accept(File) | Gibt an, ob die Datei f zum Filter gehört oder nicht |
String getDescription() | Beschreibungszeichenfolge des Filters |
Nehmen wir ein Beispiel. Wir möchten, dass die Dropdown-Liste 1 einen Filter zur Auswahl der Dateien *.txt mit der Beschreibung „Textdateien (*.txt)“ anbietet.
- Dazu müssen wir eine Klasse erstellen, die von der Klasse FileFilter abgeleitet ist
- die Methode `boolean accept(File f)` verwenden, um den Wert `true` zurückzugeben, wenn der Dateiname `f` auf `.txt` endet
- die Methode String getDescription() verwenden, um die Beschreibung „Textdateien (*.txt)“ zurückzugeben
Dieser Filter könnte in unserer Anwendung wie folgt definiert werden:
javax.swing.filechooser.FileFilter filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
// Wird „f“ akzeptiert?
return f.getName().toLowerCase().endsWith(".txt");
}//akzeptiert
public String getDescription(){
// Filterbeschreibung
return "Fichiers Texte (*.txt)";
}//getDescription
};
Dieser Filter würde durch die folgende Anweisung zur Filterliste des Objekts jFileChooser1 hinzugefügt:
All dies und einige weitere Initialisierungen werden in der Methode moreInit durchgeführt, die beim Erstellen des Fensters ausgeführt wird (siehe vollständiges Programm oben). Der Code der Schaltfläche Sauvegarder lautet wie folgt:
void btnSauvegarder_actionPerformed(ActionEvent e) {
// speichert den Inhalt des Textfelds in einer Datei
// Der anfängliche Filter wird festgelegt
jFileChooser1.setFileFilter(filtreTxt);
// Das Auswahlfeld zum Speichern wird angezeigt
int returnVal = jFileChooser1.showSaveDialog(this);
// Hat der Benutzer eine Auswahl getroffen?
if(returnVal == JFileChooser.APPROVE_OPTION) {
// Der Inhalt des Textfelds wird in eine Datei geschrieben
écrireFichier(jFileChooser1.getSelectedFile());
}//if
}
Die Abfolge der Schritte ist wie folgt:
- Der aktive Filter wird auf den Filter *.txt festgelegt, damit der Benutzer vorrangig nach diesem Dateityp suchen kann. Der Filter „Alle Dateien“ ist ebenfalls vorhanden. Er wurde in der Prozedur moreInit hinzugefügt. Es stehen also zwei Filter zur Verfügung.
- Das Auswahlfeld zum Speichern wird angezeigt. An dieser Stelle haben wir keine Kontrolle mehr, da der Benutzer das Auswahlfeld nutzt, um eine Datei aus dem Dateisystem auszuwählen.
- Wenn er das Auswahlfeld verlässt, wird der Rückgabewert geprüft, um festzustellen, ob das Textfeld gespeichert werden soll oder nicht. Falls ja, muss es in der Datei gespeichert werden, die über die Methode getSelectedFile abgerufen wird.
Der Code für die Schaltfläche „Laden“ ist dem Code für die Schaltfläche „Speichern“ sehr ähnlich.
void btnCharger_actionPerformed(ActionEvent e) {
// Auswahl einer Datei mithilfe eines Objekts JFileChooser
// Der anfängliche Filter wird festgelegt
jFileChooser1.setFileFilter(filtreTxt);
// Anzeige des Auswahlfelds
int returnVal = jFileChooser1.showOpenDialog(this);
// Hat der Benutzer etwas ausgewählt?
if(returnVal == JFileChooser.APPROVE_OPTION) {
// Die Datei wird in das Textfeld eingefügt
lireFichier(jFileChooser1.getSelectedFile());
}//if
}//btnCharger_actionPerformed
Es gibt zwei Unterschiede:
- Um das Dateiauswahlfeld anzuzeigen, wird die Methode showOpenDialog anstelle der Methode showSaveDialog verwendet. Das angezeigte Auswahlfeld entspricht demjenigen, das von der Methode showSaveDialog angezeigt wird.
- Wenn der Benutzer eine Datei ausgewählt hat, wird die Methode lireFichier anstelle der Methode écrireFichier aufgerufen.
5.4.1.1. Auswahldialoge JColorChooser und JFontChooser
Wir setzen das vorherige Beispiel fort und fügen zwei neue Schaltflächen hinzu:

Nr. | Typ | Name | Rolle |
6 | JButton | btnCouleur | um die Schriftfarbe von TextBox festzulegen |
7 | JButton | btnPolice | zum Festlegen der Schriftart für TextBox |
Die Komponente JColorChooser, mit der ein Farbauswahlfeld angezeigt werden kann, ist in der Liste der Swing-Komponenten von JBuilder zu finden:

Wir fügen diese Komponente in das Entwurfsfenster ein, jedoch außerhalb des Formulars. Sie ist im Formular nicht sichtbar, aber dennoch in der Komponentenliste des Fensters vorhanden:

Die Klasse JColorChooser ist sehr einfach aufgebaut. Das Farbauswahlfeld wird mit der Methode int showDialog angezeigt:
static Color | showDialog(Component component, String title, Color initialColor) |
Component component | die übergeordnete Komponente des Farbauswahlfelds, in der Regel ein Fenster JFrame |
String title | der Titel in der Titelleiste des Auswahlfelds |
Farbe intialColor | ursprünglich im Auswahlfeld ausgewählte Farbe |
Wenn der Benutzer eine Farbe auswählt, gibt die Methode eine Farbe zurück, andernfalls den Wert null. Der mit der Schaltfläche verknüpfte Code Couleur lautet wie folgt:
void btnCouleur_actionPerformed(ActionEvent e) {
// Auswahl einer Textfarbe mithilfe der Komponente JColorChooser
Color couleur;
if((couleur=jColorChooser1.showDialog(this,"Choix d'une couleur",Color.BLACK))!=null){
// Festlegen der Schriftfarbe im Textfeld
txtTexte.setForeground(couleur);
}//if
}
Die Klasse Color ist in java.awt.Color definiert. Dort sind verschiedene Konstanten definiert, darunter Color.BLACK für die Farbe Schwarz. Das angezeigte Auswahlfeld sieht wie folgt aus

Seltsamerweise bietet die Swing-Bibliothek keine Klasse zur Auswahl einer Schriftart an. Glücklicherweise gibt es die Java-Ressourcen im Internet. Bei einer Suche nach dem Stichwort „JFontChooser“, das ein möglicher Name für eine solche Klasse zu sein scheint, findet man mehrere Treffer. Das folgende Beispiel gibt uns die Gelegenheit, JBuilder so zu konfigurieren, dass es Pakete verwendet, die in der ursprünglichen Konfiguration nicht vorgesehen waren.
Das heruntergeladene Paket heißt swingextras.jar und wurde im Ordner <jdk>\jre\lib\perso abgelegt, wobei <jdk> das Installationsverzeichnis des von JBuilder verwendeten JDK bezeichnet. Es hätte auch an einer beliebigen anderen Stelle abgelegt werden können.
![]() | ![]() |
Sehen wir uns den Inhalt des Pakets SwingExtras.jar an:

Darin befindet sich der Java-Quellcode der im Paket enthaltenen Komponenten. Außerdem sind dort die Klassen selbst enthalten:

Aus diesem Archiv geht hervor, dass die Klasse JFontChooser eigentlich com.lamatek.swingextras.JFontChooser heißt. Wenn wir den vollständigen Namen nicht schreiben möchten, müssen wir am Anfang des Programms Folgendes schreiben:
Wie finden der Compiler und die Java-Virtual-Machine dieses neue Paket? Im Falle einer direkten Verwendung von JDK wurde dies bereits erläutert; der Leser findet die Erläuterungen im Abschnitt über Java-Pakete. Hier gehen wir näher auf die Vorgehensweise bei der Verwendung von JBuilder ein. Die Pakete werden im Menü „Optionen/JDK konfigurieren“ eingerichtet:

1 | Über die Schaltfläche „Modifier“ (1) kann man JBuilder mitteilen, welches JDK verwendet werden soll. In diesem Beispiel hatte JBuilder die Version 1.3.1 von JDK mitgebracht. Als JDK 1.4 veröffentlicht wurde, wurde es separat von JBuilder installiert, und man nutzte die Schaltfläche Modifier, um JBuilder anzuweisen,künftig JDK 1.4 zu verwenden, indem das Installationsverzeichnis des letzteren angegeben wurde |
2 | Stammverzeichnis von JDK, das derzeit von JBuilder verwendet wird |
3 | Liste der von JBuilder verwendeten Java-Archive (.jar). Über die Schaltfläche Ajouter (4) können weitere hinzugefügt werden |
4 | Über die Schaltfläche Ajouter (4) können neue Pakete hinzugefügt werden, die JBuilder sowohl für die Kompilierung als auch für die Ausführung von Programmen verwendet. Hier wurde sie verwendet, um das Paket SwingExtras.jar (5) hinzuzufügen |
Nun ist JBuilder korrekt konfiguriert, um die Klasse JFontChooser nutzen zu können. Allerdings bräuchten wir Zugriff auf die Definition dieser Klasse, um sie korrekt verwenden zu können. Das Archiv swingextras.jar enthält HTML-Dateien, die wir extrahieren könnten, um sie zu nutzen. Das ist jedoch nicht notwendig. Die in den .jar-Dateien enthaltene Java-Dokumentation ist direkt über JBuilder zugänglich. Dazu muss die Registerkarte Documentation (6) oben konfiguriert werden. Es erscheint das folgende neue Fenster:

Über die Schaltfläche Ajouter können wir festlegen, dass die Datei SwingExtras.jar nach Dokumentation durchsucht werden soll. Nach Bestätigung dieses Vorgangs lässt sich feststellen, dass wir tatsächlich Zugriff auf die Dokumentation von SwingExtras.jar haben. Dies bringt verschiedene Vorteile mit sich:
- Wenn man mit der Eingabe des Importbefehls beginnt
wird man feststellen, dass JBuilder eine Hilfe bereitstellt:

Das Paket com.lamatek wurde erfolgreich gefunden.
- Wenn wir nun zum folgenden Programm übergehen:
Wenn man F1 auf das Schlüsselwort JFontChooser anwendet, erhält man eine Hilfe zu dieser Klasse:

In der Statusleiste 1 ist zu sehen, dass tatsächlich eine HTML-Datei aus dem Paket swingextras.jar verwendet wird. Das oben gezeigte Beispiel ist aussagekräftig genug, um den Code für die Schaltfläche Police unserer Anwendung zu schreiben:
void btnPolice_actionPerformed(ActionEvent e) {
// Auswahl einer Schriftart mithilfe der Komponente JFontChooser
jFontChooser1 = new JFontChooser(new Font("Arial", Font.BOLD, 12));
if (jFontChooser1.showDialog(this, "Choix d'une police") == JFontChooser.ACCEPT_OPTION) {
// Ändern der Schriftart der Zeichen im Textfeld
txtTexte.setFont(jFontChooser1.getSelectedFont());
}//if
}
Das von der oben genannten Methode showDialog angezeigte Auswahlfeld sieht wie folgt aus:

5.5. Die grafische Anwendung IMPOTS
Wir greifen auf die Anwendung IMPOTS zurück, die bereits zweimal behandelt wurde. Nun fügen wir ihr eine grafische Benutzeroberfläche hinzu:

Die Steuerelemente sind wie folgt
Nr. | Typ | Name | Rolle |
1 | JRadioButton | rdOui | ankreuzen, wenn verheiratet |
2 | JRadioButton | rdNon | ankreuzen, wenn unverheiratet |
3 | JSpinner | spinEnfants | Anzahl der Kinder des Steuerpflichtigen Minimum=0, Maximum=20, Schrittweite=1 |
4 | JTextField | txtSalaire | Jahresgehalt des Steuerpflichtigen in F |
5 | JLabel | lblImpots | Höhe der zu zahlenden Steuer |
6 | JTextField | txtStatus | Feld für Statusmeldungen – nicht änderbar |
Das Menü sieht wie folgt aus:
Hauptoption | Unteroption | Name | Rolle |
Steuern | |||
Initialisieren | mnuInitialiser | Lädt die für die Berechnung erforderlichen Daten aus einer Textdatei | |
Berechnen | mnuCalculer | berechnet die zu zahlende Steuer, sobald alle erforderlichen Daten vorliegen und korrekt sind | |
Löschen | mnuEffacer | Setzt das Formular in seinen Ausgangszustand zurück | |
Beenden | mnuQuitter | beendet die Anwendung |
Funktionsregeln
- Das Menü Calculer bleibt ausgeblendet, solange das Gehaltsfeld leer ist
- Wenn sich bei Start der Berechnung herausstellt, dass das Gehalt falsch ist, wird der Fehler gemeldet:

Das Programm ist unten aufgeführt. Es verwendet die Klasse impots, die im Kapitel über Klassen erstellt wurde. Ein Teil des Codes, der automatisch von JBuilder generiert wird, wurde hier nicht wiedergegeben.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
import java.util.*;
import javax.swing.event.*;
public class frmImpots extends JFrame {
// die Komponenten des Fensters
JPanel contentPane;
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenu1 = new JMenu();
JMenuItem mnuInitialiser = new JMenuItem();
JMenuItem mnuCalculer = new JMenuItem();
JMenuItem mnuEffacer = new JMenuItem();
JMenuItem mnuQuitter = new JMenuItem();
JLabel jLabel1 = new JLabel();
JFileChooser jFileChooser1 = new JFileChooser();
JTextField txtStatus = new JTextField();
JRadioButton rdOui = new JRadioButton();
JRadioButton rdNon = new JRadioButton();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSalaire = new JTextField();
JLabel jLabel4 = new JLabel();
JLabel jLabel5 = new JLabel();
JLabel lblImpots = new JLabel();
JLabel jLabel7 = new JLabel();
ButtonGroup buttonGroup1 = new ButtonGroup();
JSpinner spinEnfants=null;
FileFilter filtreTxt=null;
// die Attribute der Klasse
double[] limites=null;
double[] coeffr=null;
double[] coeffn=null;
impots objImpots=null;
//Den Rahmen erstellen
public frmImpots() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// weitere Initialisierungen
moreInit();
}
// Formularinitialisierung
private void moreInit(){
// Menü „Berechnen“ gesperrt
mnuCalculer.setEnabled(false);
// Eingabefelder gesperrt
txtSalaire.setEditable(false);
txtSalaire.setBackground(Color.WHITE);
// Statusfeld
txtStatus.setBackground(Color.WHITE);
// Spinner „Kinder“ – zwischen 0 und 20 Kindern
spinEnfants=new JSpinner(new SpinnerNumberModel(0,0,20,1));
spinEnfants.setBounds(new Rectangle(137,60,40,27));
contentPane.add(spinEnfants);
// Filter *.txt für das Auswahlfeld
filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
// Wird „f“ akzeptiert?
return f.getName().toLowerCase().endsWith(".txt");
}//akzeptiert
public String getDescription(){
// Filterbeschreibung
return "Fichiers Texte (*.txt)";
}//getDescription
};
// Der Filter *.txt wird hinzugefügt
jFileChooser1.addChoosableFileFilter(filtreTxt);
// man möchte außerdem den Filter für alle Dateien
jFileChooser1.setAcceptAllFileFilterUsed(true);
// Das Startverzeichnis der Box wird festgelegt FileChooser
jFileChooser1.setCurrentDirectory(new File("."));
}//moreInit
//Die Komponente initialisieren
private void jbInit() throws Exception {
................
}
//Ersetzt, damit wir die Anwendung beenden können, wenn das Fenster geschlossen wird
protected void processWindowEvent(WindowEvent e) {
.....................
}
void mnuQuitter_actionPerformed(ActionEvent e) {
// Die Anwendung wird beendet
System.exit(0);
}
void mnuInitialiser_actionPerformed(ActionEvent e) {
// Die Datendatei wird geladen
// die über das Auswahlfeld ausgewählt wird JFileChooser1
jFileChooser1.setFileFilter(filtreTxt);
if (jFileChooser1.showOpenDialog(this)!=JFileChooser.APPROVE_OPTION)
return;
// Die ausgewählte Datei wird verarbeitet
try{
// Daten einlesen
lireFichier(jFileChooser1.getSelectedFile());
// Erstellung des Steuerobjekts
objImpots=new impots(limites,coeffr,coeffn);
// Bestätigung
txtStatus.setText("Données chargées");
// Das Gehalt kann geändert werden
txtSalaire.setEditable(true);
// Keine weiteren Änderungen möglich
mnuInitialiser.setEnabled(false);
}catch(Exception ex){
// Problem
txtStatus.setText("Erreur : " + ex.getMessage());
// Ende
return;
}//Abfangen
}
private void lireFichier(File fichier) throws Exception {
// die Datentabellen
ArrayList aLimites=new ArrayList();
ArrayList aCoeffR=new ArrayList();
ArrayList aCoeffN=new ArrayList();
String[] champs=null;
// Datei zum Lesen öffnen
BufferedReader IN=new BufferedReader(new FileReader(fichier));
// Die Datei wird zeilenweise gelesen
// sie haben die Form „Grenzwert, Koeffizient, Koeffizient“
String ligne=null;
int numLigne=0; // aktuelle Zeilennummer
while((ligne=IN.readLine())!=null){
// eine weitere Zeile
numLigne++;
// Die Zeile wird in Felder zerlegt
champs=ligne.split("\\s+");
// 3 Felder?
if(champs.length!=3)
throw new Exception("ligne " + numLigne + "erronée dans fichier des données");
// die drei Felder werden abgerufen
aLimites.add(champs[0]);
aCoeffR.add(champs[1]);
aCoeffN.add(champs[2]);
}//while
// Datei schließen
IN.close();
// Übertragung der Daten in begrenzte Arrays
int n=aLimites.size();
limites=new double[n];
coeffr=new double[n];
coeffn=new double[n];
for(int i=0;i<n;i++){
limites[i]=Double.parseDouble((String)aLimites.get(i));
coeffr[i]=Double.parseDouble((String)aCoeffR.get(i));
coeffn[i]=Double.parseDouble((String)aCoeffN.get(i));
}//for
}
void mnuCalculer_actionPerformed(ActionEvent e) {
// Berechnung der Steuer
// Lohnprüfung
int salaire=0;
try{
salaire=Integer.parseInt(txtSalaire.getText().trim());
if(salaire<0) throw new Exception();
}catch (Exception ex){
// Fehlermeldung
txtStatus.setText("Salaire incorrect. Recommencez");
// Fokus auf fehlerhaftes Feld
txtSalaire.requestFocus();
// Zurück zur Benutzeroberfläche
return;
}
// Anzahl der Kinder
Integer InbEnfants=(Integer)spinEnfants.getValue();
// Steuerberechnung
lblImpots.setText(""+objImpots.calculer(rdOui.isSelected(),InbEnfants.intValue(),salaire));
// Statusmeldung löschen
txtStatus.setText("");
}
void txtSalaire_caretUpdate(CaretEvent e) {
// Das Gehalt hat sich geändert – das Menü „Berechnen“ wird aktualisiert
mnuCalculer.setEnabled(! txtSalaire.getText().trim().equals(""));
}
void mnuEffacer_actionPerformed(ActionEvent e) {
// Formular zurücksetzen
rdNon.setSelected(true);
spinEnfants.getModel().setValue(new Integer(0));
txtSalaire.setText("");
mnuCalculer.setEnabled(false);
lblImpots.setText("");
}
}
Wir haben hier eine Komponente verwendet, die erst ab JDK 1.4 verfügbar ist: die JSpinner. Es handelt sich um einen Inkrementierer, mit dem der Benutzer hier die Anzahl der untergeordneten Elemente festlegen kann. Diese Swing-Komponente war in der Swing-Komponentenleiste von JBuilder 6, die für den Test verwendet wurde, nicht verfügbar. Das hindert jedoch nicht an ihrer Verwendung, auch wenn die Vorgehensweise etwas komplizierter ist als bei den in der Komponentenleiste verfügbaren Komponenten. Tatsächlich kann die Komponente JSpinner während der Entwurfsphase nicht auf das Formular gezogen werden. Dies muss zur Laufzeit erfolgen. Sehen wir uns den Code an, der dies bewirkt:
// Spinner „Kinder“ – Eingabe zwischen 0 und 20 Kindern
spinEnfants=new JSpinner(new SpinnerNumberModel(0,0,20,1));
spinEnfants.setBounds(new Rectangle(137,60,40,27));
contentPane.add(spinEnfants);
Die erste Zeile erstellt die Komponente JSpinner. Diese Komponente kann für verschiedene Zwecke verwendet werden und nicht nur, wie hier, als Inkrementierer für Ganzzahlen. Das Argument des Konstruktors JSpinner ist hier ein Modell für einen Zahleninkrementierer, der vier Parameter akzeptiert (Wert, Min, Max, Inkrement). Die Komponente hat folgende Form:
![]()
valeur | in der Komponente angezeigter Anfangswert |
min | in der Komponente anzeigbarer Mindestwert |
max | in der Komponente anzeigbarer Maximalwert |
incrément | Inkrementwert des angezeigten Werts bei Verwendung der Auf-/Ab-Pfeile der Komponente |
Der Wert der Komponente wird über ihre Methode getValue abgerufen, die einen Typ Object zurückgibt. Daher sind einige Typumwandlungen erforderlich, um die benötigte Ganzzahl zu erhalten:
// Anzahl der Kinder
Integer InbEnfants=(Integer)spinEnfants.getValue();
// Steuerberechnung
lblImpots.setText(""+objImpots.calculer(rdOui.isSelected(),
InbEnfants.intValue(),salaire));
Sobald die Komponente JSpinner definiert ist, wird sie im Fenster platziert:
Zunächst muss der Benutzer die Menüoption Initialiser verwenden, die ein Objekt impots mit dem Konstruktor erstellt
der Klasse impots erstellt. Zur Erinnerung: Diese Klasse wurde im Kapitel über Klassen als Beispiel definiert. Bei Bedarf kann dort nachgeschlagen werden. Die drei für den Konstruktor erforderlichen Arrays werden anhand des Inhalts einer Textdatei mit folgendem Format gefüllt:
12620.0 | 0 | 0 |
13190 | 0,05 | 631 |
15640 | 0,1 | 1290,5 |
24.740 | 0,15 | 2072,5 |
31.810 | 0,2 | 3309,5 |
39.970 | 0,25 | 4900 |
48360 | 0,3 | 6898,5 |
55.790 | 0,35 | 9316,5 |
92.970 | 0,4 | 12106 |
127.860 | 0,45 | 16.754,5 |
151250 | 0,50 | 23.147,5 |
172.040 | 0,55 | 30710 |
195.000 | 0,60 | 39312 |
0 | 0,65 | 49062 |
Jede Zeile enthält drei Zahlen, die durch mindestens ein Leerzeichen voneinander getrennt sind. Diese Textdatei wird vom Benutzer mithilfe einer Komponente vom Typ JFileChooser ausgewählt. Sobald das Objekt vom Typ impots erstellt wurde, muss der Benutzer lediglich die drei benötigten Angaben machen: verheiratet oder nicht, Anzahl der Kinder, Jahresgehalt, und anschließend die Methode calculer der Klasse impots aufrufen. Dieser Vorgang kann mehrmals wiederholt werden. Das Objekt vom Typ impots wird hingegen nur einmal erstellt, und zwar bei Verwendung der Option Initialiser.
5.6. Applets schreiben
5.6.1. Einführung
Wenn man eine Anwendung mit grafischer Benutzeroberfläche geschrieben hat, ist es relativ einfach, diese in applet umzuwandeln. Auf einem Rechner A gespeichert, kann sie über einen Webbrowser von einem Rechner B aus dem Internet heruntergeladen werden. Die ursprüngliche Anwendung wird so von zahlreichen Benutzern gemeinsam genutzt, und genau darin liegt der Hauptvorteil der Umwandlung einer Anwendung in ein Applet. Allerdings lässt sich nicht jede Anwendung auf diese Weise umwandeln: Um den Benutzer, der ein Applet in seinem Browser nutzt, nicht zu beeinträchtigen, ist die Umgebung des Applets reglementiert:
- Ein Applet darf weder auf der Festplatte des Nutzers lesen noch schreiben
- es kann nur mit dem Rechner kommunizieren, von dem aus es vom Browser heruntergeladen wurde.
Das sind erhebliche Einschränkungen. Sie bedeuten beispielsweise, dass eine Anwendung, die Informationen aus einer Datei oder einer Datenbank lesen muss, diese über eine Zwischenanwendung anfordern muss, die sich auf dem Server befindet, von dem sie heruntergeladen wurde.
Der allgemeine Aufbau einer einfachen Webanwendung sieht wie folgt aus:

- Der Client fordert ein Dokument HTML vom Webserver an, in der Regel über einen Browser. Dieses Dokument kann ein Applet enthalten, das als eigenständige grafische Anwendung innerhalb des vom Browser des Clients angezeigten Dokuments HTML läuft.
- Dieses Applet hat Zugriff auf Daten, jedoch nur auf solche, die sich auf dem Webserver befinden. Es hat weder Zugriff auf die Ressourcen des Client-Rechners, auf dem es ausgeführt wird, noch auf die Ressourcen anderer Rechner im Netzwerk außer demjenigen, von dem es heruntergeladen wurde.
5.6.2. Die Klasse JApplet
5.6.2.1. Définition
Eine Anwendung kann von einem Webbrowser heruntergeladen werden, wenn es sich um eine Instanz der Klasse java.applet.Applet oder der Klasse javax.swing.JApplet handelt. Letztere leitet sich von der ersten ab, die wiederum von der Klasse Panel abgeleitet ist, welche wiederum von der Klasse Container abgeleitet ist. Da eine Instanz von Applet oder JApplet vom Typ container ist, kann sie daher Komponenten (Component) wie Schaltflächen, Kontrollkästchen, Listen usw. enthalten. Hier einige Hinweise zur Funktion der verschiedenen Methoden:
Methode | Funktion |
public void destroy(); | löscht die Applet-Instanz |
public AppletContext getAppletContext(); | Ruft den Ausführungskontext des Applets ab (das Dokument „HTML“, in dem es sich befindet, andere Applets desselben Dokuments usw.) |
public String getAppletInfo(); | gibt eine Zeichenkette zurück, die Informationen über das Applet enthält |
public AudioClip getAudioClip(URL url); | lädt die durch URL angegebene Audiodatei |
public AudioClip getAudioClip(URL url, String name); | Lädt die durch URL/name angegebene Audiodatei |
public URL getCodeBase(); | gibt das URL des Applets zurück |
public URL getDocumentBase(); | gibt das Dokument URL aus, das das Applet HTML enthält |
public Image getImage(URL url); | ruft das durch URL angegebene Bild ab |
public Image getImage(URL url, String name); | ruft das durch URL/name angegebene Bild ab |
public String getParameter(String name); | Ruft den Wert des Parameters name ab, der im Tag <applet> des Dokuments HTML enthalten ist, das das Applet enthält. |
public void init(); | Diese Methode wird vom Browser beim ersten Start des Applets aufgerufen |
public boolean isActive(); | Status des Applets |
public void play(URL url); | Spielt die durch URL angegebene Audiodatei ab |
public void play(URL url, String name); | spielt die durch UR/name angegebene Audiodatei ab |
public void resize(Dimension d); | legt die Größe des Applet-Rahmens fest |
public void resize(int width, int height); | dasselbe |
public final void setStub(AppletStub stub); | |
public void showStatus(String msg); | Zeigt eine Meldung in der Statusleiste des Applets an |
public void start(); | Diese Methode wird vom Browser bei jeder Anzeige des Dokuments, das das Applet enthält, aufgerufen |
public void stop(); | Diese Methode wird vom Browser jedes Mal aufgerufen, wenn das Dokument, das das Applet enthält, zugunsten eines anderen verlassen wird (Wechsel von URL durch den Benutzer) |
Die Klasse JApplet hat einige Verbesserungen gegenüber der Klasse Applet mit sich gebracht, insbesondere die Möglichkeit, Komponenten der Klassen JMenuBar und c.a.d zu enthalten. Menüs, was mit der Klasse Applet nicht möglich war.
5.6.2.2. Ausführung eines Applets: die Methoden init, start und stop
Wenn ein Browser ein Applet lädt, ruft er drei Methoden des Applets auf:
init | Diese Methode wird beim ersten Laden des Applets aufgerufen. Hier werden daher die für die Anwendung erforderlichen Initialisierungen vorgenommen. |
start | Diese Methode wird jedes Mal aufgerufen, wenn das Dokument, das das Applet enthält, zum aktuellen Dokument des Browsers wird. Wenn ein Benutzer also ein Applet lädt, werden die Methoden `init` und `start` in dieser Reihenfolge ausgeführt. Wenn er das Dokument verlässt, um ein anderes anzuzeigen, wird die Methode `stop` ausgeführt. Kehrt er später zu diesem Dokument zurück, wird die Methode `start` ausgeführt. |
stop | Diese Methode wird jedes Mal aufgerufen, wenn der Benutzer das Dokument verlässt, das das Applet enthält. |
Bei vielen Applets ist lediglich die Methode „init“ erforderlich. Die Methoden „start“ und „stop“ sind nur dann notwendig, wenn die Anwendung Aufgaben (Threads) startet, die parallel und kontinuierlich laufen – oft ohne Wissen des Benutzers. Wenn dieser das Dokument verlässt, verschwindet der sichtbare Teil der Anwendung, doch diese Hintergrundaufgaben laufen weiter. Das ist oft unnötig. Man nutzt daher den Aufruf der Methode stop durch den Browser, um sie anzuhalten. Kehrt der Benutzer zum Dokument zurück, nutzt man den Aufruf der Methode start durch den Browser, um sie wieder zu starten.
Nehmen wir zum Beispiel ein Applet, das eine Uhr in seiner grafischen Benutzeroberfläche enthält. Diese wird von einem Hintergrundauftrag (Thread) verwaltet. Wenn der Benutzer im Browser die Seite des Applets verlässt, ist es unnötig, die Uhr weiterlaufen zu lassen, da sie nicht mehr sichtbar ist: In der „stop“-Methode des Applets wird der Thread, der die Uhr verwaltet, angehalten. In der Methode „start“ wird der Thread neu gestartet, damit der Benutzer, wenn er zur Applet-Seite zurückkehrt, eine Uhr vorfindet, die die richtige Uhrzeit anzeigt.
5.6.3. Umwandlung einer grafischen Anwendung in ein Applet
Wir gehen hier davon aus, dass diese Umwandlung möglich ist, d. h., dass sie die Ausführungsbeschränkungen von Applets erfüllt. Eine Anwendung wird über die Methode main einer ihrer Klassen gestartet:
Eine solche Anwendung wird wie folgt in ein Applet umgewandelt:
import java.applet.JApplet;
…
public class application extends JApplet{
…
public void init(){
…
}
…
}// Ende der Klasse
Es ist Folgendes zu beachten:
- Die Klasse application leitet sich nun von der Klasse JApplet ab.
- Die Methode main wird durch die Methode init ersetzt.
Als Beispiel greifen wir eine bereits behandelte Anwendung wieder auf: die Listenverwaltung.

Dieses Fenster enthält folgende Komponenten:
Nr. | Typ | Name | Funktion |
1 | JTextField | txtSaisie | Eingabefeld |
2 | JList | jList1 | Liste in einem Container jScrollPane1 |
3 | JList | jList2 | Liste in einem Container jScrollPane2 |
4 | JButton | cmd1To2 | überträgt die ausgewählten Elemente aus Liste 1 in Liste 2 |
5 | JButton | cmd2To1 | führt den umgekehrten Vorgang aus |
6 | JButton | cmdRaz1 | Liste 1 leeren |
7 | JButton | cmdRaz2 | Liste 2 löschen |
Der Aufbau der Anwendung sah wie folgt aus:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**Rahmen erstellen*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**Komponente initialisieren*/
private void jbInit() throws Exception {
...
txtSaisie.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtSaisie_actionPerformed(e);
}
});
...
// Jlist1 wird in den Container jScrollPane1 eingefügt
jScrollPane1.getViewport().add(jList1, null);
// Jlist2 wird in den Container jScrollPane2 eingefügt
jScrollPane2.getViewport().add(jList2, null);
...
}
/**Ersetzt, damit wir das Fenster schließen können, wenn es geschlossen wird*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_actionPerformed(ActionEvent e) {
.............
}//Klasse
void cmdRaz1_actionPerformed(ActionEvent e) {
// Liste 1 leeren
v1.removeAllElements();
}//Befehl „Raz1“
void cmdRaz2_actionPerformed(ActionEvent e) {
// Liste 2 leeren
v2.removeAllElements();
}///Befehl „Raz2“
Um die Klasse appli in applet umzuwandeln, gehen Sie wie folgt vor:
- Ändern Sie die vorherige Klasse interfaceAppli so, dass sie nicht mehr von JFrame, sondern von JApplet abgeleitet ist:
- Die Anweisung, die den Titel des Fensters JFrame festlegt, löschen. Ein Applet JApplet hat keine Titelleiste
- Den Konstruktor in eine Methode umwandeln (init) und in dieser Methode die Fensterereignisbehandlung entfernen (WindowListener, ...). Ein Applet ist ein Container, dessen Größe nicht geändert und der nicht geschlossen werden kann.
/**Rahmen erstellen*/
public init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
- Die Methode processWindowEvent muss gelöscht oder auskommentiert werden
/**Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird*/
//protected void processWindowEvent(WindowEvent e) {
// super.processWindowEvent(e);
// if (e.getID() == WindowEvent.WINDOW_CLOSING) {
// System.exit(0);
// }
// }
Als Beispiel wird der vollständige Code des Applets angegeben, mit Ausnahme des Teils, der automatisch von JBuilder generiert wurde
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceAppli extends JApplet {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**Rahmen erstellen*/
public void init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**Komponente initialisieren*/
private void jbInit() throws Exception {
//setIconImage(Toolkit.getDefaultToolkit().createImage(interfaceAppli.class.getResource("[Votre icône]")));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(400, 308));
// this.setTitle("JList");
jScrollPane1.setBounds(new Rectangle(37, 133, 124, 101));
jScrollPane2.setBounds(new Rectangle(232, 132, 124, 101));
.............
}
void txtSaisie_actionPerformed(ActionEvent e) {
// Der eingegebene Text wurde validiert
// er wird ohne führende und abschließende Leerzeichen zurückgegeben
String texte=txtSaisie.getText().trim();
// Wenn er leer ist, wird er verworfen
if(texte.equals("")){
// Fehlermeldung
JOptionPane.showMessageDialog(this,"Vous devez taper un texte",
"Erreur",JOptionPane.WARNING_MESSAGE);
// Ende
return;
}//if
// wenn er nicht leer ist, wird er zu den Werten in Liste 1 hinzugefügt
v1.addElement(texte);
// und das Eingabefeld wird geleert
txtSaisie.setText("");
}
void cmd1To2_actionPerformed(ActionEvent e) {
// Übertragung der ausgewählten Elemente aus Liste 1 in Liste 2
transfert(jList1,jList2);
}//cmd1To2
private void transfert(JList L1, JList L2){
// Übertragung der in Liste 1 ausgewählten Elemente in Liste 2
// Das Array mit den Indizes der in L1 ausgewählten Elemente wird abgerufen
int[] indices=L1.getSelectedIndices();
// Was ist zu tun?
if (indices.length==0) return;
// Die Werte aus L1 werden abgerufen
DefaultListModel v1=(DefaultListModel)L1.getModel();
// sowie die aus L2
DefaultListModel v2=(DefaultListModel)L2.getModel();
for(int i=indices.length-1;i>=0;i--){
// Die in L1 ausgewählten Werte werden zu L2 hinzugefügt
v2.addElement(v1.elementAt(indices[i]));
// Die aus L1 in L2 kopierten Elemente müssen aus L1 gelöscht werden
v1.removeElementAt(indices[i]);
}//für
}//Übertragung
private void affiche(String message){
// zeigt Meldung an
JOptionPane.showMessageDialog(this,message,
"Suivi",JOptionPane.INFORMATION_MESSAGE);
}// zeigt an
void cmd2To1_actionPerformed(ActionEvent e) {
// Übertragung der ausgewählten Elemente aus jList2 nach jList1
transfert(jList2,jList1);
}//cmd2TO1
void cmdRaz1_actionPerformed(ActionEvent e) {
// Liste 1 leeren
v1.removeAllElements();
}//Befehl „Raz1“
void cmdRaz2_actionPerformed(ActionEvent e) {
// Liste 2 löschen
v2.removeAllElements();
}//Befehl „Raz2“
}//Klasse
Der Quellcode dieses Applets kann kompiliert werden. Dies geschieht hier mit JDK, ohne JBuilder.
E:\data\serge\Jbuilder\interfaces\JApplets\1>javac.bat interfaceAppli.java
E:\data\serge\Jbuilder\interfaces\JApplets\1>dir
12/06/2002 16:40 6 148 interfaceAppli.java
12/06/2002 16:41 527 interfaceAppli$1.class
12/06/2002 16:41 525 interfaceAppli$2.class
12/06/2002 16:41 525 interfaceAppli$3.class
12/06/2002 16:41 525 interfaceAppli$4.class
12/06/2002 16:41 525 interfaceAppli$5.class
12/06/2002 16:41 4 759 interfaceAppli.class
Die Anwendung kann mit dem Programm AppletViewer aus dem Paket JDK getestet werden, das die Ausführung von Applets oder eines Browsers ermöglicht. Dazu muss das Dokument HTML appli.htm erstellt werden, das das folgende Applet enthält:
<html>
<head>
<title>listes swing</title>
</head>
<body>
<applet
code="interfaceAppli.class"
width="400"
height="300">
</applet>
</body>
</html>
Hier handelt es sich um ein klassisches HTML-Dokument, abgesehen vom Vorhandensein des Applet-Tags. Dieses wurde mit drei Parametern verwendet:
code="interfaceAppli.class" | Name der kompilierten JAVA-Klasse, die zum Ausführen des Applets geladen werden soll |
width="400" | Breite des Applet-Rahmens im Dokument |
height="300" | Höhe des Applet-Frames im Dokument |
Nachdem die Datei „appli.htm“ erstellt wurde, kann sie mit dem Programm „appletviewer“ aus dem Ordner „JDK“ oder mit einem Browser geladen werden. Geben Sie in einem DOS-Fenster den folgenden Befehl im Ordner der Datei „appli.htm“ ein:
appletviewer appli.htm
Hier wird davon ausgegangen, dass sich das Verzeichnis der ausführbaren Datei appletviewer.exe im Verzeichnis PATH des DOS-Fensters befindet; andernfalls müsste der vollständige Pfad zur ausführbaren Datei appletviewer.exe angegeben werden. Es erscheint das folgende Fenster:

Die Ausführung des Applets wird mit der Option Applet/Quitter beendet. Testen wir nun das Applet mit einem Browser. Dieser muss eine Java 2-Virtual Machine verwenden, um die Swing-Komponenten anzeigen zu können. Bis vor kurzem (2001) stellte diese Anforderung ein Problem dar, da Sun JDK-Dateien herausgab, denen die Browserhersteller nur mit großer Verzögerung folgten. Schließlich hat Sun dieses Hindernis beseitigt, indem es den Nutzern eine Anwendung namens „Java-Plugin“ zur Verfügung stellte, die es den Browsern Internet Explorer und Netscape Navigator ermöglicht, die neuesten von Sun veröffentlichten JRE (JRE = Java Runtime Environment) zu nutzen. Die folgenden Tests wurden mit IE 5.5 in Verbindung mit dem Java-Plugin 1.4 durchgeführt.
Eine erste Möglichkeit, das Applet interfaceAppli.class zu testen, besteht darin, die Datei HTML appli.htm durch Doppelklick direkt im Browser zu laden. Der Browser zeigt dann die Seite HTML und ihr Applet ohne Hilfe eines Webservers an:

Anhand von URL (1) ist ersichtlich, dass die Datei direkt in den Browser geladen wurde. Im folgenden Beispiel wurde die Datei appli.htm von einem Apache-Webserver angefordert, der auf Port 81 des lokalen Rechners läuft:

5.6.4. Die Formatierungsoption <applet> in einem HTML-Dokument
Wir haben gesehen, dass in einem Dokument mit der Nummer HTML das Applet durch den Formatierungsbefehl (Tag) <applet> referenziert wurde. Dieser Befehl kann verschiedene Parameter haben:
<applet
code=
width=
height=
codebase=
align=
hspace=
vspace=
alt=
>
<param name1=nom1 value=val1>
<param name2=nom2 value=val2>
texte
>
</applet>
Die Parameter haben folgende Bedeutung:
Parameter | Bedeutung |
code | obligatorisch – Name der auszuführenden .class-Datei |
width | erforderlich – Breite des Applets im Dokument |
height | erforderlich – Höhe … |
codebase | optional – URL des Verzeichnisses, das das auszuführende Applet enthält. Wenn „codebase“ nicht angegeben ist, wird das Applet im Verzeichnis des HTML-Dokuments gesucht, das darauf verweist |
align | optional – Positionierung (LEFT, RiGHT, CENTER) des Applets im Dokument |
hspace | optional – horizontaler Rand um das Applet, angegeben in Pixeln |
vspace | optional – vertikaler Rand um das Applet, angegeben in Pixeln |
alt | optional – Text, der anstelle des Applets angezeigt wird, wenn der Browser es nicht laden kann |
param | optional – an das Applet übergebener Parameter, der dessen Namen (name) und Wert (value) angibt. Das Applet kann den Wert des Parameters „name1“ über „val1=getParameter(„name1“)“ abrufen Es können beliebig viele Parameter verwendet werden |
texte | optional – wird von jedem Browser angezeigt, der kein Applet ausführen kann, beispielsweise weil er keine Java-Virtual-Machine besitzt. |
Nehmen wir ein Beispiel, um die Übergabe von Parametern an ein Applet zu veranschaulichen:
<html>
<head>
<title>paramètres applet</title>
</head>
<body>
<applet code="interfaceParams.class" width="400" height="300">
<param name="param1" value="val1">
<param name="param2" value="val2">
</applet>
</body>
</html>
Der Java-Code des Applets interfaceParams wurde wie zuvor beschrieben generiert. Es wurde eine Anwendung JBuilder erstellt und anschließend wurden die oben genannten Änderungen vorgenommen:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceParams extends JApplet {
JPanel contentPane;
JScrollPane jScrollPane1 = new JScrollPane();
JLabel jLabel1 = new JLabel();
DefaultListModel params=new DefaultListModel();
JList lstParams = new JList(params);
//Rahmen erstellen
public void init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// weitere Initialisierungen
moreInit();
}
// Initialisierungen
public void moreInit(){
// zeigt die Werte der Applet-Parameter an
params.addElement("nom=param1 valeur="+getParameter("param1"));
params.addElement("nom=param2 valeur="+getParameter("param2"));
}//Weitere Initialisierungen
//Komponente initialisieren
private void jbInit() throws Exception {
............
this.setSize(new Dimension(205, 156));
//this.setTitle("Parameter eines Applets");
jScrollPane1.setBounds(new Rectangle(19, 53, 160, 73));
............
}
}
Die Ausführung mit AppletViewer:

5.6.5. Zugriff auf entfernte Ressourcen aus einem Applet heraus
Viele Anwendungen müssen auf Informationen in Dateien oder Datenbanken zugreifen. Wir haben bereits erwähnt, dass ein Applet keinen Zugriff auf die Ressourcen des Rechners hat, auf dem es ausgeführt wird. Das ist eine vernünftige Maßnahme. Andernfalls würde es ausreichen, ein Applet zu schreiben, um die Festplatte derjenigen auszuspionieren, die es laden. Das Applet hat jedoch Zugriff auf die Ressourcen des Servers, von dem es heruntergeladen wurde, beispielsweise auf Dateien. Das werden wir nun betrachten.
5.6.5.1. Die Klasse URL
Jede Java-Anwendung kann mithilfe der Klasse java.net.URL (URL = Uniform Resource Locator) eine Datei lesen, die sich auf einem Rechner im Netzwerk befindet. Ein URL identifiziert eine Ressource im Netzwerk, den Rechner, auf dem sie sich befindet, sowie das Protokoll und den Kommunikationsport, die zum Abrufen der Ressource verwendet werden sollen, in der Form:
Protokoll:Port//Rechner/Datei
So bezeichnet beispielsweise der URL http://www.ibm.com/index.html die Datei index.html auf dem Rechner www.ibm.com. Der Zugriff erfolgt über das Protokoll http. Der Port ist nicht angegeben: Der Browser verwendet Port 80, den Standardport des HTTP-Dienstes.
Sehen wir uns einige Elemente der Klasse URL genauer an:
public URL(String spec) | erstellt eine Instanz von URL anhand einer Zeichenkette vom Typ „protokoll:port//Rechner/Datei“ – löst eine Ausnahme aus, wenn die Syntax der Zeichenkette nicht mit einer URL übereinstimmt |
public String getFile() | gibt das Feld „Datei“ der Zeichenkette „Protokoll:Port//Rechner/Datei“ des URL zurück |
public String getHost() | ermöglicht es, das Feld „Rechner“ aus der Zeichenkette „Protokoll:Port//Rechner/Datei“ des URL zu extrahieren |
public String getPort() | ermöglicht es, das Feld „port“ aus der Zeichenkette „protokoll:port//Rechner/Datei“ von URL zu extrahieren |
public String getProtocol() | ermöglicht es, das Feld „protokoll“ aus der Zeichenkette „protokoll:port//Rechner/Datei“ von URL zu extrahieren |
public URLConnection openConnection() | öffnet die Verbindung zum Remote-Rechner getHost() auf dessen Port getPort() gemäß dem Protokoll getProtocol(), um die Datei getFile() zu lesen. Löst eine Ausnahme aus, wenn die Verbindung nicht geöffnet werden konnte |
public final InputStream openStream() | Abkürzung für openConnection().getInputStream(). Ermöglicht das Abrufen eines Eingabestroms, aus dem der Inhalt der Datei getFile() gelesen werden kann. Löst eine Ausnahme aus, wenn der Strom nicht abgerufen werden konnte |
public String toString() | Gibt die Identität der Instanz von URL zurück |
Hier gibt es zwei Methoden, die für uns von Interesse sind:
- public URL(String spec) zur Angabe der zu verarbeitenden Datei
- public final InputStream openStream() zur Verarbeitung der Datei
5.6.5.2. Ein Beispiel für die Befehlszeile
Wir schreiben ein Java-Programm ohne grafische Benutzeroberfläche, das den Inhalt einer URL, die als Parameter übergeben wird, auf dem Bildschirm anzeigt. Ein Beispiel für einen Aufruf könnte wie folgt aussehen:
Das Programm ist relativ einfach:
import java.net.*; // für die Klasse URL
import java.io.*; // für die Streams
public class urlcontenu{
// zeigt den Inhalt des als Argument übergebenen URL an
// Dieser Inhalt muss aus Text bestehen, damit er lesbar ist
public static void main (String arg[]){
// Überprüfung der Argumente
if(arg.length==0){
System.err.println("Syntaxe pg url");
System.exit(0);
}
try{
// Erstellung von URL
URL url=new URL(arg[0]);
// Inhalt wird gelesen
try{
// Erstellung des Eingabestroms
BufferedReader is=new BufferedReader(new InputStreamReader(url.openStream()));
try{
// Einlesen der Textzeilen aus dem Eingabestrom
String ligne;
while((ligne=is.readLine())!=null)
System.out.println(ligne);
} catch (Exception e){
System.err.println("Erreur lecture : " +e);
}
finally{
try { is.close(); } catch (Exception e) {}
}
} catch (Exception e){
System.err.println("Erreur openStream : " +e);
}
} catch (Exception e){
System.err.println("Erreur création URL : " +e);
}
}// Ende der Hauptschleife
}// Ende der Klasse
Nachdem überprüft wurde, dass tatsächlich ein Argument vorhanden ist, wird versucht, mit diesem ein URL zu erstellen:
// Erstellung des URL
URL url=new URL(arg[0]);
Diese Erstellung kann fehlschlagen, wenn das Argument nicht der Syntax von URL protocole:port//machine/fichier entspricht. Liegt ein syntaktisch korrektes URL vor, wird versucht, einen Eingabestrom zu erstellen, aus dem Textzeilen gelesen werden können. Der von einer URL URL.openStream() bereitgestellte Eingabestrom liefert einen Strom vom Typ InputStream, bei dem es sich um einen zeichenorientierten Strom handelt: Das Einlesen erfolgt zeichenweise, und die Zeilen müssen selbst gebildet werden. Um Textzeilen lesen zu können, muss die Methode readLine der Klassen BufferedReader oder DataInputStream.On verwendet werden; hier wurde BufferedReader gewählt. Nun müssen wir nur noch den Datenstrom InputStream aus URL in den Datenstrom BufferedReader umwandeln. Dies geschieht durch die Erstellung eines Zwischendatenstroms InputStreamReader:
BufferedReader is=new BufferedReader(new InputStreamReader(url.openStream()));
Die Erstellung dieses Flusses kann fehlschlagen. Die entsprechende Ausnahme wird behandelt. Sobald der Fluss vorliegt, müssen wir nur noch die Textzeilen daraus auslesen und diese auf dem Bildschirm anzeigen.
String ligne;
while((ligne=is.readLine())!=null)
System.out.println(ligne);
Auch hier kann das Einlesen eine Ausnahme auslösen, die abgefangen werden muss. Hier ist ein Beispiel für die Ausführung des Programms, das eine lokale URL anfordert:
E:\data\serge\Jbuilder\interfaces\JApplets\3>java urlcontenu http://localhost
<html>
<head>
<title>Bienvenue dans le Serveur Web personnel</title>
</head>
<body bgcolor="#FFFFFF" link="#0080FF" vlink="#0080FF"
topmargin="0" leftmargin="0">
<table border="0" cellpadding="0" cellspacing="0" width="100%"
bgcolor="#000000">
............
</table>
</center></div></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
5.6.5.3. Ein grafisches Beispiel
Die grafische Benutzeroberfläche sieht wie folgt aus:

Nummer | Name | Typ | Rolle |
1 | txtURL | JTextField | URL – bitte lesen |
2 | btnCharger | JButton | Schaltfläche zum Starten der Wiedergabe von URL |
3 | JScrollPane1 | JScrollPane | Laufband |
4 | lstURL | JList | Liste mit dem Inhalt des angeforderten URL |
Bei der Ausführung erhalten wir ein Ergebnis, das dem des Konsolenprogramms ähnelt:

Der relevante Code der Anwendung lautet wie folgt:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.net.*;
import java.io.*;
public class interfaceURL extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JTextField txtURL = new JTextField();
JButton btnCharger = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel lignes=new DefaultListModel();
JList lstURL = new JList(lignes);
//Rahmen erstellen
public interfaceURL() {
..............
}
//Komponente initialisieren
private void jbInit() throws Exception {
..............
}
//Ersetzt, damit wir das Programm beenden können, wenn das Fenster geschlossen wird
protected void processWindowEvent(WindowEvent e) {
...................
}
void txtURL_caretUpdate(CaretEvent e) {
// legt den Status der Schaltfläche „Laden“ fest
btnCharger.setEnabled(! txtURL.getText().trim().equals(""));
}
void btnCharger_actionPerformed(ActionEvent e) {
// zeigt den Inhalt von URL in der Liste an
try{
afficherURL(txtURL.getText().trim());
}catch(Exception ex){
// Fehleranzeige
JOptionPane.showMessageDialog(this,"Erreur : " + ex.getMessage(),"Erreur",JOptionPane.ERROR_MESSAGE);
}//Try-Catch
}
private void afficherURL(String strURL) throws Exception {
// zeigt den Inhalt von URL und strURL in der Liste an
// Es wird keine Ausnahme speziell behandelt. Sie werden lediglich weitergeleitet
// Erstellung des URL
URL url=new URL(strURL);
// Erstellung des Eingabestroms
BufferedReader IN=new BufferedReader(new InputStreamReader(url.openStream()));
// Lesen der Textzeilen aus dem Eingabestrom
String ligne;
while((ligne=IN.readLine())!=null)
lignes.addElement(ligne);
// Schließen des Lesestroms
IN.close();
}
}
5.6.5.4. Ein Applet
Die vorstehende grafische Anwendung wird, wie bereits mehrfach gezeigt, in ein Applet umgewandelt. Das Applet wird in ein Dokument HTML appliURL.htm eingefügt:
<html>
<head>
<title>Applet lisant une URL</title>
</head>
<body>
<h1>Applet lisant une URL</h1>
<applet
code="appletURL.class"
width="400"
height="300"
>
</applet>
</body>
</html>

Im obigen Beispiel hat der Browser die URL „URLhttp://localhost:81/Japplets/2/appliURL.htm“ von einem Webserver mit der Adresse „apache“ angefordert, der auf Port 81 läuft. Das Applet wurde daraufhin im Browser angezeigt. Darin wurde erneut die URL „URL http://localhost:81/Japplets/2/appliURL.htm“ aufgerufen, um zu überprüfen, ob tatsächlich die von uns erstellte Datei „appliURL.htm“ abgerufen wurde. Versuchen wir nun, eine URL-Datei zu laden, die nicht von dem Rechner stammt, der das Applet bereitgestellt hat (hier localhost):

Das Laden der Datei „URL“ wurde abgelehnt. Hier zeigt sich die Einschränkung bei Applets: Sie können nur auf die Netzwerkressourcen des Rechners zugreifen, von dem aus sie heruntergeladen wurden. Es gibt eine Möglichkeit für das Applet, diese Einschränkung zu umgehen, nämlich die Netzwerkanfragen an ein Serverprogramm weiterzuleiten, das sich auf dem Rechner befindet, von dem es heruntergeladen wurde. Dieses Programm führt die Netzwerkanfragen anstelle des Applets durch und sendet ihm die Ergebnisse zurück. Man bezeichnet dies als Relaisprogramm.
5.7. Das Applet IMPOTS
Wir werden nun die grafische Anwendung IMPOTS in ein Applet umwandeln. Dies ist insofern interessant, als die Anwendung dadurch für jeden Internetnutzer verfügbar wird, der über einen Browser und ein Java-Plugin 1.4 verfügt (aufgrund der Komponente JSpinner). Unsere Anwendung wird somit weltweit zugänglich... Diese Änderung erfordert etwas mehr als die mittlerweile klassische Umwandlung von einer grafischen Anwendung in ein Applet. Die Anwendung nutzt eine Menüoption Initialiser, deren Zweck darin besteht, den Inhalt einer lokalen Datei zu lesen. Wenn man sich jedoch eine Webanwendung vorstellt, wird deutlich, dass dieses Schema nicht mehr zutrifft:

Es liegt auf der Hand, dass sich die Daten, die die Steuertabellen definieren, auf dem Webserver und nicht auf jedem einzelnen Client-Rechner befinden werden. Die auf dem Webserver einzulesende Datei wird hier im selben Ordner wie das Applet abgelegt, und die Option Initialiser muss sie dort abrufen. Die vorangegangenen Beispiele haben gezeigt, wie dies zu bewerkstelligen ist. Um die Datendatei lokal auszuwählen, wurde zudem eine Komponente JFileChooser verwendet, die hier nicht mehr erforderlich ist.
Das Dokument HTML, das das Applet enthält, sieht wie folgt aus:
<html>
<head>
<title>Applet de calcul d'impôts</title>
</head>
<body>
<h2>Calcul d'impôts</h2>
<applet
code="appletImpots.class"
width="320"
height="270"
>
<param name="data" value="impots.txt">
Zu beachten ist der Parameter data, dessen Wert der Name der Datei ist, die die Daten des Steuertarifs enthält. Das Dokument HTML, die Klasse appletImpots, die Klasse impots und die Datei impots.txt befinden sich alle im selben Ordner auf dem Webserver:
E:\data\serge\web\JApplets\impots>dir
12/06/2002 13:24 247 impots.txt
13/06/2002 10:17 654 appletImpots$2.class
13/06/2002 10:17 653 appletImpots$3.class
13/06/2002 10:17 653 appletImpots$4.class
13/06/2002 10:17 651 appletImpots$5.class
13/06/2002 10:06 651 appletImpots$6.class
13/06/2002 10:17 8 655 appletImpots.class
13/06/2002 10:17 657 appletImpots$1.class
13/06/2002 10:24 286 appletImpots.htm
13/06/2002 10:17 1 305 impots.class
Der Code des Applets lautet wie folgt (wir haben nur die Änderungen gegenüber der grafischen Anwendung hervorgehoben):
...........
import java.net.*;
import java.applet.Applet;
public class appletImpots extends JApplet {
// die Komponenten des Fensters
JPanel contentPane;
............................
// die Attribute der Klasse
double[] limites=null;
double[] coeffr=null;
double[] coeffn=null;
impots objImpots=null;
String urlDATA=null;
//Rahmen erstellen
public void init() {
//enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// weitere Initialisierungen
moreInit();
}
// Formularinitialisierung
private void moreInit(){
// Menü „Berechnen“ deaktiviert
mnuCalculer.setEnabled(false);
................
// Der Name der Steuertafel-Datei wird abgerufen
String nomFichier=getParameter("data");
// Fehler?
if(nomFichier==null){
// Fehlermeldung
txtStatus.setText("Le paramètre data de l'applet n'a pas été initialisé");
// Die Option „Initialisieren“ wird gesperrt
mnuInitialiser.setEnabled(false);
// Ende
return;
}//if
// URL der Daten wird festgelegt
urlDATA=getCodeBase()+"/"+nomFichier;
}//moreInit
//Komponente initialisieren
private void jbInit() throws Exception {
...................
}
void mnuQuitter_actionPerformed(ActionEvent e) {
// Die Anwendung wird beendet
System.exit(0);
}
void mnuInitialiser_actionPerformed(ActionEvent e) {
// Die Datendatei wird geladen
try{
// Daten lesen
lireDATA();
// Erstellung des Objekts „Steuern“
objImpots=new impots(limites,coeffr,coeffn);
................
}
private void lireDATA() throws Exception {
// Die Datentabellen
ArrayList aLimites=new ArrayList();
ArrayList aCoeffR=new ArrayList();
ArrayList aCoeffN=new ArrayList();
String[] champs=null;
// Datei zum Lesen öffnen
BufferedReader IN=new BufferedReader(new InputStreamReader(new URL(urlDATA).openStream()));
// Die Datei wird zeilenweise gelesen
....................
}
void mnuCalculer_actionPerformed(ActionEvent e) {
// Berechnung der Steuer
......................
}
void txtSalaire_caretUpdate(CaretEvent e) {
..........
}
void mnuEffacer_actionPerformed(ActionEvent e) {
...............
}
}
Wir gehen hier nur auf die Änderungen ein, die sich daraus ergeben, dass sich die zu lesende Datendatei nun auf einem Remote-Rechner statt auf einem lokalen Rechner befindet:
Der Name der einzulesenden Datendatei „URL“ wird durch den folgenden Code ermittelt:
// Abruf des Dateinamens des Steuertarifs
String nomFichier=getParameter("data");
// Fehler?
if(nomFichier==null){
// Fehlermeldung
txtStatus.setText("Le paramètre data de l'applet n'a pas été initialisé");
// Die Option „Initialisieren“ wird gesperrt
mnuInitialiser.setEnabled(false);
// Ende
return;
}//if
// URL der Daten wird festgelegt
urlDATA=getCodeBase()+"/"+nomFichier;
Denken wir daran, dass der Dateiname „impots.txt“ in den Parameter data des Applets übergeben wurde:
Der obige Code beginnt also damit, den Wert des Parameters data abzurufen und dabei einen möglichen Fehler zu behandeln. Wenn der Wert von URL des Dokuments HTML, das das Applet enthält, „http://localhost:81/JApplets/impots/appletImpots.htm“ lautet, dann lautet die URL der Datei impots.txt „http://localhost:81/JApplets/impots/impots.txt“. Wir müssen den Namen dieses URL ermitteln. Die Methode getCodeBase() des Applets liefert den URL des Ordners, aus dem das Dokument HTML, das das Applet enthält, abgerufen wurde, also in unserem Beispiel http://localhost:81/JApplets/impots. Mit der folgenden Anweisung lässt sich somit der URL der Datendatei bilden:
In der Methode lireFichier(), die den Inhalt von URL und urlData liest, wird der Eingabestrom erstellt, der das Einlesen der Daten ermöglicht:
// Datei zum Lesen öffnen
BufferedReader IN=new BufferedReader(new InputStreamReader(new URL(urlDATA).openStream()));
Ab diesem Zeitpunkt lässt sich nicht mehr unterscheiden, ob die Daten aus einer entfernten oder einer lokalen Datei stammen. Hier ein Beispiel für die Ausführung des Applets:

5.8. Fazit
Dieses Kapitel hat
- eine Einführung in die Erstellung grafischer Benutzeroberflächen mit JBuilder
- die gängigsten Swing-Komponenten
- die Erstellung von Applets
Zusammenfassend lässt sich sagen, dass
- der von JBuilder generierte Code von Hand geschrieben werden kann. Sobald dieser Code auf die eine oder andere Weise vorliegt, reicht ein einfaches JDK aus, um ihn auszuführen, und JBuilder ist dann nicht mehr unbedingt erforderlich.
- Die Verwendung eines Tools wie JBuilder kann zu erheblichen Produktivitätssteigerungen führen:
- Zwar ist es möglich, den von JBuilder generierten Code von Hand zu schreiben, doch kann dies sehr zeitaufwendig sein und ist kaum sinnvoll, da die Logik der Anwendung in der Regel an anderer Stelle liegt.
- Der generierte Code kann aufschlussreich sein. Ihn zu lesen und zu studieren ist eine gute Möglichkeit, bestimmte Methoden und Eigenschaften von Komponenten zu entdecken, die man zum ersten Mal verwendet.
- JBuilder ist plattformübergreifend. Man behält also sein Wissen bei, wenn man von einer Plattform zur anderen wechselt. Die Möglichkeit, Programme zu schreiben, die sowohl unter Windows als auch unter Linux laufen, ist natürlich ein sehr wichtiger Produktivitätsfaktor. Dies ist jedoch Java selbst zu verdanken und nicht JBuilder.
5.9. JBuilder unter Linux
Alle vorangegangenen Beispiele wurden unter Windows 98 getestet. Man kann sich fragen, ob die geschriebenen Programme unverändert unter Linux lauffähig sind. Sofern der betreffende Linux-Rechner über die von den verschiedenen Programmen verwendeten Klassen verfügt, sind sie es. Wenn Sie beispielsweise JBuilder unter Linux installiert haben, befinden sich die erforderlichen Klassen bereits auf Ihrem Rechner. Hier sehen Sie beispielsweise, wie die Ausführung eines unserer Programme auf der Komponente JList mit JBuilder 4 unter Linux aussieht:
Im Folgenden beschreiben wir die Installation von JBuilder 4 Foundation auf einem Linux-Rechner. Die Installation auf einem Win9x-Rechner ist problemlos und entspricht dem nun beschriebenen Vorgang. Die Installation späterer Versionen unterscheidet sich wahrscheinlich davon, doch dieses Dokument kann dennoch einige nützliche Informationen enthalten.
JBuilder ist auf der Website von Inprise unter der URL http://www.inprise.com/jbuilder verfügbar

Auf dieser Seite finden sich unter anderem Links für Windows und Linux. Wir beschreiben nun die Installation von JBuilder auf einem Linux-Rechner mit der grafischen Benutzeroberfläche KDE.
Wenn man dem Link „JBuilder 4 für Linux“ folgt, wird ein Formular angezeigt. Dieses füllt man aus und erhält schließlich zwei Dateien:
jb4docs_fr.tar.gz: die Dokumentation und Beispiele zu JBuilder 4
jb4fndlinux_fr.tar.gz: JBuilder 4 Foundation. Dies ist eine eingeschränkte Version des kommerziellen JBuilder 4, die jedoch für Bildungszwecke ausreicht.
Ein Aktivierungsschlüssel für die Software wird Ihnen per E-Mail zugesandt. Mit diesem Schlüssel können Sie JBuilder 4 nutzen; er wird bei der ersten Verwendung abgefragt. Sollten Sie diesen Schlüssel verlieren, können Sie zur oben genannten URL zurückkehren und dem Link „get your activation key“ folgen. Wir gehen im Folgenden davon aus, dass Sie root sind und sich im Verzeichnis der beiden oben genannten Dateien tar.gz befinden. Entpacken Sie die beiden Dateien:
[ls -l]
drwxr-xr-x 3 nobody nobody 4096 oct 10 2000 docs
drwxr-xr-x 3 nobody nobody 4096 déc 5 13:00 foundation
[ls -l foundation]
-rw-r--r-- 1 nobody nobody 1128 déc 5 13:00 deploy.txt
-rwxr-xr-x 1 nobody nobody 69035365 déc 5 13:00 fnd_linux_install.bin
drwxr-xr-x 2 nobody nobody 4096 déc 5 13:00 images
-rw-r--r-- 1 nobody nobody 15114 déc 5 13:00 index.html
-rw-r--r-- 1 nobody nobody 23779 déc 5 13:00 license.txt
-rw-r--r-- 1 nobody nobody 75739 déc 5 13:00 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 déc 5 13:00 whatsnew.html
[ls -l docs]
-rw-r--r-- 1 nobody nobody 1128 oct 10 2000 deploy.txt
-rwxr-xr-x 1 nobody nobody 40497874 oct 10 2000 doc_install.bin
drwxr-xr-x 2 nobody nobody 4096 oct 10 2000 images
-rw-r--r-- 1 nobody nobody 9210 oct 10 2000 index.html
-rw-r--r-- 1 nobody nobody 23779 oct 10 2000 license.txt
-rw-r--r-- 1 nobody nobody 75739 oct 10 2000 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 oct 10 2000 whatsnew.html
In den beiden erstellten Verzeichnissen ist die Datei „.bin“ die Installationsdatei. Öffnen Sie außerdem mit einem Browser die Datei „index.html“ in jedem der Verzeichnisse. Dort finden Sie die Anleitung zur Installation der beiden Produkte. Beginnen wir mit der Installation von JBuilder Foundation:
Es erscheint der erste Bildschirm der Installation. Es folgen zahlreiche weitere:

Bestätigen Sie. Es folgt ein Bildschirm mit Erläuterungen:

Führen Sie [suivant] aus.

Akzeptieren Sie die Lizenzvereinbarung und führen Sie den Befehl [suivant] aus.

Akzeptieren Sie den vorgeschlagenen Speicherort für JBuilder (notieren Sie sich diesen, Sie werden ihn später benötigen) und führen Sie [suivant] aus. Die Installation ist schnell abgeschlossen.

Wir sind bereit für einen ersten Test. Starten Sie in KDE den Dateimanager, um zum Verzeichnis der JBuilder-Ausführungsdateien zu gelangen: /opt/jbuilder4/bin (sofern Sie JBuilder in /opt/jbuilder4 installiert haben):

Klicken Sie auf das Symbol jbuilder oben. Da Sie JBuilder zum ersten Mal verwenden, müssen Sie Ihren Aktivierungsschlüssel eingeben:

Füllen Sie die Felder Nom und Société aus. Klicken Sie auf „[Ajouter]“, um Ihren Aktivierungsschlüssel einzugeben. Wir weisen darauf hin, dass Ihnen dieser per E-Mail zugesandt worden sein sollte und dass Sie ihn, falls Sie ihn verloren haben, unter der URL abrufen können, unter der Sie JBuilder 4 heruntergeladen haben (siehe Beginn der Installation). Sobald Ihr Aktivierungsschlüssel akzeptiert wurde, werden Ihnen die Lizenzbedingungen angezeigt:

Mit dem Befehl OK kehren Sie zu dem bereits bekannten Fenster zur Eingabe der Informationen zurück:

Geben Sie OK ein, um diesen Schritt abzuschließen, der nur beim ersten Start ausgeführt wird. Anschließend erscheint die Entwicklungsumgebung von JBuilder:

Beenden Sie JBuilder, um nun die Dokumentation zu installieren. Dabei werden einige Dateien installiert, die in der JBuilder-Hilfe verwendet werden, die derzeit noch unvollständig ist. Kehren Sie in das Verzeichnis zurück, in das Sie die JBuilder-Dateien tar.gz entpackt haben. Das Installationsprogramm befindet sich im Verzeichnis docs. Wechseln Sie dorthin:
[cd docs]
[ls -l]
-rw-r--r-- 1 nobody nobody 1128 oct 10 2000 deploy.txt
-rwxr-xr-x 1 nobody nobody 40497874 oct 10 2000 doc_install.bin
drwxr-xr-x 2 nobody nobody 4096 oct 10 2000 images
-rw-r--r-- 1 nobody nobody 9210 oct 10 2000 index.html
-rw-r--r-- 1 nobody nobody 23779 oct 10 2000 license.txt
-rw-r--r-- 1 nobody nobody 75739 oct 10 2000 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 oct 10 2000 whatsnew.html
Die Installationsdatei lautet doc_install.bin, kann jedoch nicht sofort gestartet werden. Wenn man dies dennoch versucht, schlägt die Installation fehl, ohne dass man den Grund dafür versteht. Lesen Sie die Datei index.html mit einem Browser, um eine genaue Beschreibung des Installationsvorgangs zu erhalten. Das Installationsprogramm benötigt eine Java-Virtual-Machine, genauer gesagt ein Programm namens java, das sich im Verzeichnis PATH auf Ihrem Rechner befinden muss. Zur Erinnerung: PATH ist eine Unix-Variable, deren Wert in der Form rep1:rep2:...:repn die Verzeichnisse repi angibt, die bei der Suche nach einer ausführbaren Datei durchsucht werden müssen. In diesem Fall fordert das Installationsprogramm die Ausführung eines Programms mit dem Namen java an. Je nach Anzahl der virtuellen Java-Maschinen, die Sie hier und da installiert haben, können mehrere Versionen dieses Programms vorhanden sein. Logischerweise verwenden wir die von JBuilder 4 bereitgestellte Version, die sich in /opt/jbuilder4/jdk1.3/bin befindet. Um dieses Verzeichnis in die Variable PATH einzutragen:
[echo $PATH]
/usr/local/sbin:/usr/sbin:/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
[export PATH=/opt/jbuilder4/jdk1.3/bin/:$PATH]
[echo $PATH]
/opt/jbuilder4/jdk1.3/bin/:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
Wir können nun die Installation der Dokumentation starten:
Es handelt sich um eine grafische Installation:

Sie verläuft sehr ähnlich wie bei JBuilder Foundation. Daher werden wir hier nicht näher darauf eingehen. Es gibt jedoch einen Bildschirm, den Sie nicht übersehen sollten:

Das Installationsprogramm sollte normalerweise selbstständig erkennen, wo Sie JBuilder Foundation installiert haben. Ändern Sie daher die vorgeschlagene Einstellung nicht, es sei denn, sie ist falsch.
Sobald die Dokumentation installiert ist, können wir einen neuen Test mit JBuilder durchführen. Starten Sie die Anwendung wie oben beschrieben. Sobald JBuilder geöffnet ist, wählen Sie die Option „Hilfe/Hilfe-Thema“. Klicken Sie im linken Rahmen auf den Link Tutoriels:

JBuilder enthält eine Reihe von Tutorials, die Ihnen den Einstieg in die Java-Programmierung erleichtern. Im Folgenden haben wir das oben genannte Tutorial „Erstellen einer Anwendung“ durchlaufen.

Wählen Sie in JBuilder „Datei/Neues Projekt“. Ein Assistent zeigt Ihnen drei Bildschirme an:

Wir erstellen ein einfaches Fenster mit dem Titel „Hallo Welt“. Wir nennen dieses Projekt coucou. Das Beispiel wurde mit root ausgeführt. JBuilder schlägt daraufhin vor, alle Projekte in einem Verzeichnis jbproject im Verbindungsverzeichnis von root zusammenzufassen. Das Projekt coucou wird im Verzeichnis coucou (Feld „Name des Projektverzeichnisses“) von jbproject abgelegt. Erstellen Sie [suivant].

Dieser zweite Bildschirm enthält eine Übersicht über die verschiedenen Pfade Ihres Projekts. Es sind keine Änderungen erforderlich. Führen Sie [suivant] aus.

Auf dem dritten Bildschirm werden Sie aufgefordert, Ihr Projekt anzupassen. Füllen Sie die Angaben aus und führen Sie den Befehl [Terminer] aus.
Führen Sie nun Fichier/Nouveau aus:

Wählen Sie Application und führen Sie OK aus. Ein neuer Assistent zeigt Ihnen zwei Bildschirme an:

Das Feld paquet enthält den Namen des Projekts. Im Feld „Klasse“ wird nach dem Wert nom gefragt, der der Hauptklasse des Projekts zugewiesen wird. Übernehmen Sie den oben genannten Namen und geben Sie [suivant] ein:

Unsere Anwendung enthält eine zweite Java-Klasse für das Anwendungsfenster. Geben Sie dieser Klasse einen Namen. Das Feld „Titre“ ist der Titel, den Sie diesem Fenster geben möchten. Der Rahmen „options“ bietet Ihnen Optionen für Ihr Fenster. Wählen Sie alle aus und geben Sie [Terminer] ein. Sie kehren dann zur JBuilder-Umgebung zurück, die nun um die von Ihnen für Ihr Projekt eingegebenen Informationen erweitert wurde:

Im linken/oberen Fenster (1) sehen Sie die Liste der Dateien, aus denen Ihr Projekt besteht. Darunter befinden sich insbesondere die beiden Klassen .java, deren Namen wir gerade vergeben haben. Im rechten Fenster (2) sehen Sie den Java-Code der Klasse coucouCadre. Im linken/unteren Fenster sehen Sie die Struktur (Klassen, Methoden, Attribute) Ihres Projekts. Es ist bereit zur Ausführung. Klicken Sie oben auf die Schaltfläche 4 oder wählen Sie „Ausführen“/„Projekt ausführen“ oder geben Sie „F9“ ein. Sie sollten das folgende Fenster erhalten:

Wenn Sie auf die Option „Aide“ klicken, sollten Sie die Informationen wiederfinden, die Sie den Assistenten bei der Erstellung angegeben haben. Wir werden nicht weiter darauf eingehen. Es ist nun an der Zeit, sich in die Tutorials zu vertiefen.
Bevor wir zum Schluss kommen, wollen wir noch kurz zeigen, dass Sie nicht JBuilder und dessen grafische Benutzeroberfläche verwenden können, sondern das JDK, das JBuilder mitgebracht und unter /opt/jbuilder4/jdk1.3 abgelegt hat. Erstellen Sie die folgende Datei essai1.java:
import java.io.*;
public class essai1{
public static void main(String args[]){
System.out.println("coucou");
System.exit(0);
}
}
Kompilieren wir den Code und führen wir ihn mit dem JDK von JBuilder aus:






