8 GUI und Ereignisbehandlung 8.1 JFrame-Vorlage Step by step |
|
Step by step | Wir
wollen Schritt für Schritt ein Programm aufbauen, das zur Ausgabe ein
Fenster benutzt, wie wir es z.B. von Windows gewohnt sind. Nach jedem
Schritt compiliere man den Quelltext und beobachte, was passiert, wenn man
das Programm startet. Wichtig ist: Wir beschreiben die Auswirkungen, die die Veränderungen bei jedem weiteren Schritt verursachen. Auf die Erklärung vieler Details müssen wir an dieser Stelle verzichten, sie werden im Laufe des Kurses immer deutlicher. |
Schritt 1 |
public class HalloWelt{ public static void main(String[] args){ } } |
Das Programm besteht fast nur aus seinen Rumpfbestandteilen, die main(..)
- Methode ist leer. |
|
Schritt 2 |
public class HalloWelt{ public HalloWelt(){ } public static void main(String[] args){ } } |
Ein so
genannter Konstruktor ist angelegt, besitzt aber noch keine besondere
Funktionalität. Wir erinnern uns, man erkennt ihn daran, dass er den gleichen Namen trägt,
wie die Klasse. Hinter dem Konstruktornamen steht immer eine
Parameterliste in runden Klammern; in unserem Fall ist die Liste leer.
Dieser Konstruktor wird vom Compiler auchangelegt, wenn wir ihn
nicht wie hier explizit implementieren. Insofern unterscheidet sich unser
Programm zu seinem Vorläufer nicht. |
|
Schritt 3 |
public class HalloWelt{
public HalloWelt(){
}
public static void main(String[] args){
new HalloWelt();
}
}
|
Der
Konstruktor wird aufgerufen, um beim Starten des Programms ein Objekt der
Klasse anzulegen. Das Programm 'tut noch immer nichts'. |
|
Schritt 4 |
import javax.swing.*; public class HalloWelt extends JFrame{ public HalloWelt(){ } public static void main(String[] args){ new HalloWelt(); } } |
Wir
lassen unsere Klasse von der Klasse JFrame erben. Das Erben von der Klasse
JFrame
wird durch
extends JFrame
kenntlich gemacht. Statt extends JFrame müssten wir eigentlich extends javax.swing.JFrame schreiben., denn die Klasse JFrame liegt in dem Paket jawax.swing. Die kürzere Schreibweise können wir benutzen, wenn wir das Paket mittels import javax.swing.*; einbinden. Dass die letzte Veränderung im Quelltext auch beim laufenden Programm sichtbar wird setzt eine weitere kleine Veränderung voraus: |
|
Schritt 5 |
import javax.swing.*;
public class HalloWelt extends JFrame{
public HalloWelt(){
setVisible(true);
}
public static void main(String[] args){
new HalloWelt();
}
}
|
Wir rufen die von
JFrame
geerbte Methode setVisible(boolean
b) auf. Durch das Vererben ist
diese Methode zu einer Methode von
HalloWelt
geworden und kann ohne Punktnotation aufgerufen werden. Man könnte
statt
setVisible(true) deshalb auch this.setVisible(true) schreiben können. Anmerkung:
|
|
Schritt 6 |
import javax.swing.*; public class HalloWelt extends JFrame{ public HalloWelt(String titel){ setVisible(true); } public static void main(String[] args){ new HalloWelt("Ich bin ein JFrame-Objekt"); } } |
Wir
ändern dazu den Konstruktor und entsprechend seinen Aufruf ab. Aber einen
Erfolg haben wir erst, wenn wir den Konstruktor von
JFrame
einsetzten. Dazu müssen wir folgendes wissen: Unser Programm ist nicht nur
eine Instanz (=Objekt) der Klasse
HalloWelt,
sondern auch der Klasse JFrame.
Es wir dazu automatisch der Standardkonstruktor der Vaterklasse, in
unserem Falle also JFrame()
aufgerufen. Wir können den Aufruf dieses Konstruktors auch mit
super()
'per Hand' machen, was offensichtlich wenig Sinn macht. Sinn macht es
aber, wenn man einen anderen Konstruktor als den Standardkonstruktor der
Vaterklasse aufrufen will. Da sich alle Kontruktoren einer Klasse allein
in der Signatur, also in der Parameterliste unterscheiden, können wir
diesen Aufruf ebenfalls mit
super(...) realisieren und die
Parameterliste entsprechend anpassen. So gibt es in der Klasse
JFrame
einen Konstruktor JFrame(String
name), mit ihm kann man ein
JFrame-Objekt
erzeugen und ihm dabei einem Namen geben. Wir rufen diesen Konstruktor vom
Konstruktor der Klasse HalloWelt
aus mit super(name)
auf. Jetzt verstehen wir auch, warum wir unseren Konstrukor der Klasse
HalloWelt
die Form HalloWelt(String
name) gegeben haben. Beim
Aufruf von
new HalloWelt("Ich bin ein JFrame-Objekt"); übergeben wir das
String-Objekt
"Ich bin ein JFrame-Objekt"
an den Konstruktor von HalloWelt
und mit super
wird es an den entsprechenden Konstruktor von
JFrame
weitergegeben. |
|
Schritt 7 |
import javax.swing.*;
public class HalloWelt extends JFrame{
public HalloWelt(String titel){
super(titel);
setVisible(true);
}
public static void main(String[] args){
new HalloWelt("Ich bin ein JFrame-Objekt");
}
}
|
Wir können noch immer
nicht zufrieden sein, denn wenn wir das Fenster durch Klicken auf das
Kreuz in der rechten oberen Ecke schließen, verschwindet
|
|
Schritt 8 |
import javax.swing.*;
import java.awt.event.*;
public class HalloWelt extends JFrame{
public HalloWelt(String titel){
super(titel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args){
new HalloWelt("Ich bin ein JFrame-Objekt");
}
}
|
Für den Aufruf der Methode setDefaultCloseOperation(EXIT_ON_CLOSE); wird wieder keine Punktnotation verwendet, da sie geerbt von JFrame Methode unserer Klasse selbst ist. |
|
Schritt 9 |
import javax.swing.*; import java.awt.event.*; public class HalloWelt extends JFrame{ public HalloWelt(String titel){ super(titel); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(300, 300); setVisible(true); } public static void main(String[] args){ new HalloWelt("Ich bin ein JFrame-Objekt"); } } |
|
|
Schritt 10 |
import javax.swing.*; import java.awt.event.*; import java.awt.*; public class HalloWelt extends JFrame{ public HalloWelt(String titel){ super(titel); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(300, 300); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); setVisible(true); } public static void main(String[] args){ new HalloWelt("Ich bin ein JFrame-Objekt"); } } |
Im
letzten Schritt schließlich sorgen wir dafür, dass das Fenster grafische
Objekte wie Labels, Buttons, Zeichenflächen und ähnliches aufnehmen kann.
Wir benutzen dazu einen Behälter (engl. container). Dieser Behälter
bekommt noch ein Layout, in unserem Fall ein Borderlayout. Wie wir den
Behälter benutzen werden wir bal erfahren.
Zunächst machen wir erst ein mal
halt. Es drängt sich die Frage auf, ob man das alles, was wir in den 10
Schritten gesehen haben zum einen lernen, und zum zweiten jedes Mal neu
eintippen müssen. Beides ist nicht nur unzumutbar sondern auch ineffizient.
|
|
Vorlagen | Der JavaEditor
stellt 4 verschieden Vorlagen zur Verfügung. Klicken wir auf die dritte
Vorlage (JFrame) im Register Programm, so öffnet sich, nachdem man einen
Namen für seine Anwendung ausgewählt hat ein Programmrumpf, der
gerade alle Elemente enthält, die wir in den Schritten 1 bis 10 kennen
gelernt haben. |
HalloWelt.java | Wir
wollen nun noch dafür sorgen, dass unser Programm den Namen "Hallo Welt"
mit Recht trägt. Es soll also im Fenster der Schriftzug "Hallo Welt"
erscheinen. Dazu legen wir ein Label an, Versehen es mit dem
entsprechenden Text und platzieren es in unserem Behälter. |
Download: HalloWelt.java |
import javax.swing.*; import java.awt.*; public class HalloWelt extends JFrame{ JLabel schriftZug; public HalloWelt(String titel){ super(titel); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(300, 300); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); schriftZug = new JLabel("HalloWelt"); cp.add(schriftZug,BorderLayout.NORTH); setVisible(true); } public static void main(String[] args){ new HalloWelt("Ich bin ein JFrame-Objekt"); } } |
zu | 8.2 Aktionsabhorcher |
zur Startseite | www.pohlig.de (C) MPohlig 2005 |