Grafische Benutzeroberfläche
Fenster
VorbemerkungFür die hier verwendeten Programme wurden aus didaktischen Gründen folgende Vereinbarungen getroffen;
1)Alle Klassen, in denen sich die Methode main befindet, beginnen mit Main...Bem:Die Programmdatei muss also den gleichen Namen haben und public sein.
2) Alle von uns frei wählbaren Bezeichnungen für Klassen, Variablen, Methoden usw. beginnen mit dem Bezeichner my...Ausnahme:Einfache Variablen wie z.B. i,j, usw.
import java.awt.*;import javax.swing.*;
public class MainFenster1 { public static void main(String[] args) { JFrame myF = new JFrame(); myF.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); myF.setLocation(200,200); myF.setSize(400,200); myF.setVisible(true); }}
Hier wird ein Objekt, also myF der Klasse JFrame, also ein Fenster erzeugt und später auf den Bildschirm gebracht. Deshalb muss
"dankenswerterweise" der Bauplan nicht von uns gebastelt werden.
import java.awt.*;import javax.swing.*;
public class MainFenster1 { public static void main(String[] args) { JFrame myF = new JFrame(); myF.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); myF.setLocation(200,200); myF.setSize(400,200); myF.setVisible(true); }}
Linke obere Ecke des Fensters
Grösse des Fensters festlegen, das auf den Bildschirm kommt
Programm wird beendet (aus dem Arbeitsspeicher entfernt), wenn Fenster weggeklickt wird. Nachprüfen mit Task-Manager
bringt das Fenster auf den Bildschirm
Aus Gründen der OOP soll zukünftig dieses Fenster in einer eigenen, selbst gebastelten Klasse entworfen werden. Welche Eigenschaft der OOP muss dabei verwendet werden?
Die Vererbung!
import java.awt.*;import javax.swing.*;
public class MainFenster1 { public static void main(String[] args) { JFrame myF = new JFrame(); myF.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); myF.setLocation(200,200); myF.setSize(400,200); myF.setVisible(true); }}
Deswegen ...
import java.awt.*;import javax.swing.*;
public class MainFenster1 { public static void main(String[] args) { MyFenster myF = new MyFenster(); myF.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
}}
Hier wird ein Objekt, also myF, der selbstgebastelten Klasse MyFenster
erzeugt, d.h. auf den Bildschirm gebracht
Programm wird beendet (aus dem Arbeitsspeicher entfernt), wenn Fenster weggeklickt wird. Nachprüfen mit Task-Manager
class MyFenster extends JFrame{ private JButton myB1, myB2; private JTextField myT1, myT2; private JLabel myL1, myL2; private Container myCont; private GridLayout myGL_2_3; public MyFenster(){
Buttons deklarieren
Textfelder deklarieren
Labels deklarieren
Layout deklarieren, es besteht aus 2 Zeilen und 3 Spalten
Ein Layout ist eine Vorgabe, wie die sichtbaren Komponenten innerhalb beim Einfügen (mit add) in das Fenster oder in ein Panel (siehe später) angeordnet werden
Liefert die Stelle, an der die sichtbaren Komponenten (Buttons, usw.) an das Fenster montiert werden.
class MyFenster extends JFrame{ private JButton myB1, myB2; private JTextField myT1, myT2; private JLabel myL1, myL2; private Container myCont; private GridLayout myGL_2_3; public MyFenster(){
1) Beim GridLayout werden die Elemente zeilenweise eingefügt, d.h. zuerst wird die 1. Zeile aufgefüllt, dann die 2. Zeile, usw.Mit myGL_2_3 = new GridLayout(2,3);wird ein Layout von 2 Zeilen und 3 Spalten angelegt.
2) Es müssen _ALLE_ Zeilen bis zur letzten Spalte befüllt werden
myB1=new JButton("Go"); myB2=new JButton("Ok"); myT1=new JTextField("hier eingeben",30); myT2=new JTextField("hier eingeben",30); myL1=new JLabel("Euro-->Dollar"); myL2=new JLabel("Dollar-->Euro"); myCont=getContentPane(); myGL_2_3=new GridLayout(2,3); myCont.setLayout(myGL_2_3);
Buttons anlegen
Textfelder anlegen
Labels anlegen
Stelle des Anmontierens
bestimmen
GridLayout mit 2 Zeilen und 3 Spalten anlegen.
Die Stelle, an der die Elemente angefügt werden, muss mit einem
Layout versehen werden.
myB1=new JButton("Go"); myB2=new JButton("Ok"); myT1=new JTextField("hier eingeben",30); myT2=new JTextField("hier eingeben",30); myL1=new JLabel("Euro-->Dollar"); myL2=new JLabel("Dollar-->Euro"); myCont=getContentPane(); myGL_2_3=new GridLayout(2,3); myCont.setLayout(myGL_2_3);
Die sichtbaren Komponenten müssen an unser Fenster “MyFenster“ an eine dafür vorgesehene, ganz bestimmte Stelle, montiert werden. Die Methode getContentPane() liefert die Stelle, an die das Panel an den Top-Level-Container JFrame montiert werden muß.
myCont.add(myL1); myCont.add(myT1); myCont.add(myB1); myCont.add(myL2); myCont.add(myT2); myCont.add(myB2);
setTitle("Meine Zeichnung"); setLocation(30,60); setSize(600,400); setVisible(true); }}
Lables, Textfelder und Buttons werden an das Fenster montiert unter der Regie des GridLayouts, das aus 2 Zeilen und 3 Spalten besteht.
bringt das Fenster auf den Bildschirm
Fensterüberschrift
Linke obere Ecke des Fensters
Grösse des Fensters festlegen
Man kann nicht nur direkt am Fenster sichtbare Komponenten (Buttons, ...)
anbringen, sondern Behälter (Container), in die man (wieder Untercontainer) oder sichtbare Komponenten anbringt. Diese Behälter haben die ähnliche Bedeutung
wie die Ordner im Explorer. Diese Behälter werden realisiert durch Objekte vom Typ JPanel. Sie werden hier auch
oft Zeichenflächen genannt.
Im Folgenden sollen hier 2 Zeichenflächen an das Fenster montiert werden, wobei in diese Zeichenflächen
vorher sichtbare Komponenten eingefügt wurden.
Wichtig: Auch diese Zeichenflächen müssen (genauso wie die Stelle, an der wiederum diese angebracht werden) ein Layout bekommen (müssen "formatiert"
werden).
In diesen 2 Zeichenflächen sollen jeweils 1 Button, 1 Label und 1 Textfeld angebracht werden. Damit diese
sichtbaren Komponenten nicht zu groß werden, sollen zusätzlich noch weitere "DummyLabels" angebracht werden.
Konkret: (siehe nächste Folie)
Konkret:
1. Zeichenfläche: Button | Label | Textfeld | Dummy
Dummy | Dummy | Dummy | Dummy
2. Zeichenfläche: Dummy | Dummy | Dummy | Dummy
Button | Label | Textfeld | Dummy
import java.awt.*;import javax.swing.*;
public class MainFenster1 { public static void main(String[] args) { MyFenster myF = new MyFenster(); myF.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
}}
Das gleiche wie vorher...Was neu hinzukommt wird rot gekennzeichnet.
class MyFenster extends JFrame{ private JButton myB1, myB2; private JTextField myT1, myT2; private JLabel myL1, myL2; // Zeichenflächen private JPanel myPan1; private JPanel myPan2; private Container myCont; private GridLayout myGL_2_1; private GridLayout myGL1_2_4; private GridLayout myGL2_2_4; public MyFenster(){
Zeichenflächen deklarieren
Für jede Zeichenfläche ein eigenes Layout (auch
wenn alle Layouts die gleiche Zeilen- und Spaltenzahl haben).
myB1=new JButton("Go"); myB2=new JButton("Ok"); myT1=new JTextField("hier eingeben",30); myT2=new JTextField("hier eingeben",30); myL1=new JLabel("Euro-->Dollar"); myL2=new JLabel("Dollar-->Euro"); myPan1=new JPanel(); myPan2=new JPanel(); myCont=getContentPane(); myGL_2_1=new GridLayout(2,1); myGL1_2_4=new GridLayout(2,4); myGL2_2_4=new GridLayout(2,4); myCont.setLayout(myGL_2_1); myPan1.setLayout(myGL1_2_4); myPan2.setLayout(myGL2_2_4);
Zeichenflächen anlegen
GridLayouts anlegen
GridLayouts an die entsprechenden Stellen anbringen
myPan1.add(myL1); myPan1.add(myT1); myPan1.add(myB1); myPan1.add(new JLabel()); myPan1.add(new JLabel()); myPan1.add(new JLabel()); myPan1.add(new JLabel()); myPan1.add(new JLabel());
Anbringen des Labels, Textfelds und Buttons an die 1. Zeichenfläche.
Label Textfeld Button DummyLabel
DummyLabel DummyLabel DummyLabel DummyLabel
Anbringen der DummyLabels
Beachte: Durch jedes new JLabel() wird ein neues Objekt angelegt. Man hat nachher also 5 verschiedene JLabels
myPan2.add(new JLabel()); myPan2.add(new JLabel()); myPan2.add(new JLabel()); myPan2.add(new JLabel()); myPan2.add(myL2); myPan2.add(myT2); myPan2.add(myB2); myPan2.add(new JLabel());
Anbringen des Labels, Textfelds und Buttons an die 2. Zeichenfläche.
Label Textfeld Button DummyLabel
Anbringen der DummyLabels
Beachte: Durch jedes new JLabel() wird ein neues Objekt angelegt. Man hat nachher also 5 verschiedene JLabels
DummyLabel DummyLabel DummyLabel DummyLabel
myCont.add(myPan1); myCont.add(myPan2);
setTitle("Meine Zeichnung"); setLocation(30,60); setSize(600,400); setVisible(true); }}
Anbringen der zwei Zeichenflächen an das Fenster
Zeichnen mit Java
Um in Java zu zeichnen, müssen alle Linien, Kreise, usw. in eine
Zeichenfläche (JPanel) gezeichnet werden.
Aus Demogründen soll hier neben der Zeichenfläche noch eine weitere
Zeichenfläche erstellt werden, in die nur sichtbare Elemente (1 Label, 1 Textfeld,
1 Button) montiert werden sollen.
Gezeichnet wird durch den Aufruf der Methode (hier müssen dann z.B. die Befehle zum Zeichnen von Ellipsen, Linien, Rechtecken, usw. stehen) paintComponent(Graphics g) Diese soll niemals direkt innerhalb des selbst geschriebenen Programms aufgerufen werden !Java (bzw. das Betriebssystem) entscheidet selbst, wenn es paintComponent(Graphics g)aufruft. Dies geschieht:
--> bei der ersten Anzeige des Fensters (setVisible(true))--> nachdem ein Fenster vergrößert (verkleinert) wurde,--> nach dem Wegziehen überlagernder Fenster (verdeckte Elemente werden aufgedeckt)--> nach dem Aufruf des Befehls repaint() im Programm
Bemerkung:1) Den Parameter Graphics g in paintComponent(Graphics g)kann man sich als den Teil des Bildspeicherbereichs vorstellen,der die zugehörige grafische Komponente (z.B. Ellipse) auf dem Bildschirm repräsentiert.
2) Die erste Anweisung in paintComponent(Graphics g) sollte super.paintComponent(g) sein, dasuper.paintComponent(g) die Methode paintComponent(g) der Vaterklasse aufruft.Die Standard-Implementation dieser Methode der Klasse JPanel löscht den komplettenInhalt des Panels. Ansonsten wird auch noch der alte Inhalt des Panels auf dem Bildschirm ausgegeben.
Wie kann der Programmierer eine Zeichenfläche (Panel) erzeugen und in diese Ellipsen, Linien, Rechtecke, usw. anbringen?Zusätzlich soll er außerdem noch die ganzen Möglichkeiten von JPanel (z.B. wird durch paintComponent automatisch die Zeichnung auf den Bildschirm gebracht) verwenden können!
Indem man eine Klasse bastelt, die von JPanel erbt !
import java.awt.*;import javax.swing.*;
public class MainZeichnen1 { public static void main(String[] args) { MyFenster myf = new MyFenster(); myf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); }}
Das gleiche wie vorher...
class MyFenster extends JFrame{ private JButton myB1; private JTextField myT1; private JLabel myL1; private JPanel myPan1; private MyZeichenflaeche myZf1; private Container myCont; private BorderLayout myBoLa; private GridLayout myGL_1_2;
public MyFenster(){Nur für myPan1 braucht man ein Layout: Da an myZf1 keine sichtbaren Komponenten (wie Buttons, usw.) angebracht werden.
Eine selbstgebastelte Zeichenflaeche deklarieren
Ein JPaneldeklarieren
class MyFenster extends JFrame{ private JButton myB1; private JTextField myT1; private JLabel myL1; private JPanel myPan1; private MyZeichenflaeche myZf1; private Container myCont; private BorderLayout myBoLa; private GridLayout myGL_1_2;
public MyFenster(){
Eine selbstgebastelte Zeichenflaeche deklarieren
Ein JPaneldeklarieren
Das BorderLayout unterteilt in 5 Bereiche: North, South, East, West, Center. Einem Bereich kann dabei immer nur eine Komponente (z.B. ein Button) zugeordnet werden. Will man einem Bereich mehrere Komponenten zuordnen, muß dieser Bereich auch mit einem Layout-Manager bestückt werden (siehe nächste Folien). Wird ein Bereich nicht gefüllt, wird diese Fläche von den anderen Bereichen genutzt.Ein Border-Layout, siehe wie folgt aus (wenn alle Bereiche gefüllt sind)...
NORTH
SOUTH
WEST
EAST
CENTER
Wichtige Bemerkung: Wenn kein Layout-Manager benutzt wird, gilt standardmäßig folgende Zuweisung (Vorbelegung):
JFrame-Objekt --> BorderLayoutJPanel-Objekt --> FlowLayout
myB1 = new JButton("Go"); myT1 = new JTextField("hier eingeben",30); myL1 = new JLabel("Rechts Text eingeben");
myPan1 = new JPanel(); myZf1 = new MyZeichenflaeche(); myCont = getContentPane(); myBoLa = new BorderLayout(); myGL_1_2 = new GridLayout(1,2); myCont.setLayout(myBoLa); myPan1.setLayout(myGL_1_2);
Zeichenflächen anlegen
Selbstgebasteltes Objekt der KLasse MyZeichenflaeche anlegen.
myPan1.add(myL1); myPan1.add(myT1); myPan1.add(myB1);
myCont.add(myZf1,BorderLayout.CENTER); myCont.add(myPan1,BorderLayout.SOUTH);
setTitle("Meine Zeichnung"); setLocation(30,60); setSize(600,800); setVisible(true); }}
Anbringen des Labels, Textfelds und Buttons an die 1. Zeichenfläche.
Anbringen der zwei Zeichenflächen an das Fenster
class MyZeichenflaeche extends JPanel{ public void paintComponent(Graphics myG){ Color myFarbe = new Color(100, 250, 200); myG.setColor(myFarbe); myG.drawOval(100, 50, 250, 300); myG.fillOval(100, 50, 250, 300);
myG.setColor(Color.red); myG.drawString("Das bin ich",200,20); myG.drawLine(150,160,180,160); myG.drawLine(270,160,300,160); myG.drawLine(230,200,230,230); myG.drawRect(200,280,50,30); }} Eigene Farbe basteln:
150, 180, 234 sind die Rot-, Grün- und Blauteile einer Farbe jeweils im Bereich zwischen 0 und 255
Diese Farbe setzen
class MyZeichenflaeche extends JPanel{ public void paintComponent(Graphics myG){ Color myFarbe = new Color(100, 250, 200); myG.setColor(myFarbe); myG.drawOval(100, 50, 250, 300); myG.fillOval(100, 50, 250, 300);
myG.setColor(Color.red); myG.drawString("Das bin ich",200,20); myG.drawLine(150,160,180,160); myG.drawLine(270,160,300,160); myG.drawLine(230,200,230,230); myG.drawRect(200,280,50,30); }}
Zeichnet die Randlinie einer Ellipse, die sich in einem gedachten Rechteck befindet. Der linke obere Punkt hat die Koordinaten Koordinate x = 100, Koordinate y = 50.Die Breite des Rechtecks in x-Richtung = 250Die Breite des Rechtecks in y-Richtung = 300
class MyZeichenflaeche extends JPanel{ public void paintComponent(Graphics myG){ Color myFarbe = new Color(100, 250, 200); myG.setColor(myFarbe); myG.drawOval(100, 50, 250, 300); myG.fillOval(100, 50, 250, 300);
myG.setColor(Color.red); myG.drawString("Das bin ich",200,20); myG.drawLine(150,160,180,160); myG.drawLine(270,160,300,160); myG.drawLine(230,200,230,230); myG.drawRect(200,280,50,30); }}
Füllt die Ellipse mit der vorher gesetzten Farbe
Die Farbe rot auswählen (setzen)
Text ausgeben
class MyZeichenflaeche extends JPanel{ public void paintComponent(Graphics myG){ Color myFarbe = new Color(100, 250, 200); myG.setColor(myFarbe); myG.drawOval(100, 50, 250, 300); myG.fillOval(100, 50, 250, 300);
myG.setColor(Color.red); myG.drawString("Das bin ich",200,20); myG.drawLine(150,160,180,160); myG.drawLine(270,160,300,160); myG.drawLine(230,200,230,230); myG.drawRect(200,280,50,30); }}
Linie zeichnen
Rechteck zeichnen
Hier nochmals das Border-Layout
kurz beschrieben:
Das Border-Layout besteht aus 5 Zonen, in denen jeweils eine Komponente eingefügt werden kann. Sollen z.B. mehrere Buttons in eine Zone eingefügt werden, fügt man diese zuerst in ein Panel ein und danach dieses Panel in die Zone! Nimmt man weniger als fünf Komponenten auf, so werden die nicht benutzten Zonen von den benutzten Zonen belegt.
NORTH
SOUTH
WEST
EAST
CENTER
NORTH und SOUTH nehmen die volle Breite ein. Die Höhe hängt von der einzufügenden Komponente ab. WEST und EAST nehmen die Breite der einzufügenden Komponente an und belegen in der Höhe den restlichen freien Raum. Den Rest bekommt CENTER.
NORTH
SOUTH
WEST
EAST
CENTER