Grafikprogrammierung in Java
Grafikprogrammierung in Java
Grafikprogrammierung in Java
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Grundlagen<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.1 Grundlagen 11-1
Schnittstellen für Anwenderprogramme<br />
• E<strong>in</strong>e Schnittstelle für Anwenderprogramme (application programm<strong>in</strong>g <strong>in</strong>terface,<br />
API) stellt wohldef<strong>in</strong>ierte und standardisierte Klassen und Methoden zur<br />
Verfügung, die von Anwenderprogrammen genutzt werden können.<br />
• APIs ermöglichen es, vorhandene Software um weitere Funktionen zu ergänzen.<br />
• <strong>Java</strong> stellt beispielsweise APIs für die folgenden Zwecke zur Verfügung:<br />
◦ <strong>Grafikprogrammierung</strong><br />
◦ Datenbankmanagement<br />
◦ Netzwerkprogrammierung<br />
◦ Verarbeitung, Auswertung und Transformation von XML-Dokumenten<br />
◦ Verschlüsselung von Daten<br />
11.1 Grundlagen 11-2
<strong>Grafikprogrammierung</strong><br />
<strong>Java</strong> bietet den Programmierern zwei Bibliotheken zur Programmierung von<br />
grafischen Benutzeroberflächen (graphical user <strong>in</strong>terface, GUI) an:<br />
• Abstract W<strong>in</strong>dow Toolkit (AWT)<br />
Das AWT ermöglicht die Ausführung grundlegender grafischer Operationen. Die<br />
Klassen und Methoden des AWTs s<strong>in</strong>d im Standardpaket java.awt enthalten.<br />
• Sw<strong>in</strong>g<br />
Seit der Version 1.1 gibt es e<strong>in</strong>e zweite Grafikbibliothek im <strong>Java</strong> Development Kit.<br />
Sie heißt Sw<strong>in</strong>g und ist Bestandteil des Erweiterungspakets javax.sw<strong>in</strong>g. Diese<br />
Bibliothek beseitigt etliche Schwächen des AWTs und bietet e<strong>in</strong>e weitgehend<br />
plattformunabhängige Schnittstelle. Die Möglichkeiten, die Sw<strong>in</strong>g bietet,<br />
übersteigen die des AWTs.<br />
11.1 Grundlagen 11-3
<strong>Grafikprogrammierung</strong><br />
Neben AWT und Sw<strong>in</strong>g gibt es e<strong>in</strong>e weitere verbreitete Bibliothek zur<br />
Programmierung grafischer Benutzeroberflächen:<br />
• Standard W<strong>in</strong>dow Toolkit (SWT)<br />
SWT ist e<strong>in</strong>e Bibliothek für die Erstellung grafischer Oberflächen mit <strong>Java</strong>. Sie<br />
wurde im Jahr 2001 von IBM für die Entwicklungsumgebung Eclipse entwickelt<br />
und kommt <strong>in</strong> e<strong>in</strong>er ganzen Reihe von Anwendungen zum E<strong>in</strong>satz, beispielsweise<br />
Eclipse selbst. SWT leidet auf e<strong>in</strong>igen Nicht-W<strong>in</strong>dows-Plattformen unter<br />
Effizienzproblemen. SWT gehört nicht zum JDK.<br />
Wir gehen hier (aus Zeitgründen) nicht auf SWT e<strong>in</strong>.<br />
11.1 Grundlagen 11-4
Das Abstract W<strong>in</strong>dow Toolkit<br />
Die Fähigkeiten des AWTs lassen sich <strong>in</strong> vier Gruppen e<strong>in</strong>teilen:<br />
• Grundoperationen zum Zeichnen von L<strong>in</strong>ien und Flächen und zur Ausgabe von Text<br />
• Methoden zur Programmsteuerung durch die Behandlung von Maus-, Tastaturund<br />
Fensterereignissen<br />
• Dialogelemente zur Kommunikation mit dem Anwender<br />
• Fortgeschrittene Operationen zur Ausgabe von Bitmaps und Tönen<br />
11.1 Grundlagen 11-5
E<strong>in</strong> e<strong>in</strong>führendes Beispiel<br />
import java.awt.*;<br />
public class Fenster extends Frame {<br />
}<br />
Fenster() {<br />
setBackground(Color.yellow);<br />
setSize(200,150);<br />
setLocation(500,500);<br />
setVisible(true);<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
new Fenster();<br />
}<br />
11.1 Grundlagen 11-6
Das Abstract W<strong>in</strong>dow Toolkit<br />
• Zum Ableiten e<strong>in</strong>er eigenen Fensterklasse wird <strong>in</strong> der Regel entweder die Klasse<br />
Frame oder die Klasse Dialog verwendet.<br />
• Um e<strong>in</strong> neues Fenster zu erhalten, muss e<strong>in</strong> Objekt der Klasse Frame erzeugt, auf<br />
die gewünschte Größe gebracht und durch Aufruf der Methode setVisible<br />
sichtbar gemacht werden.<br />
• Die Ausgabe <strong>in</strong> e<strong>in</strong> Fenster erfolgt durch Überlagern der Methode pa<strong>in</strong>t. Diese<br />
Methode wird immer dann aufgerufen, wenn das Fenster neu gezeichnet werden<br />
muss, z. B. beim Programmstart oder beim Verändern der Größe.<br />
• Die Methode void pa<strong>in</strong>t(Graphics g) erhält als Parameter e<strong>in</strong>en grafischen<br />
Kontext. Hierunter versteht man allgeme<strong>in</strong>e E<strong>in</strong>stellungen für Schrift und Grafik,<br />
beispielsweise den aktuellen Font und die aktuelle Farbe.<br />
11.1 Grundlagen 11-7
E<strong>in</strong> e<strong>in</strong>führendes Beispiel<br />
import java.awt.*;<br />
class Rechteck extends Canvas {<br />
}<br />
public void pa<strong>in</strong>t(Graphics g) {<br />
g.setColor(Color.red);<br />
g.fillRect(20,20,100,40);<br />
g.setColor(Color.black);<br />
g.drawStr<strong>in</strong>g("E<strong>in</strong> rotes Rechteck",20,80);<br />
}<br />
11.1 Grundlagen 11-8
class E<strong>in</strong>fachesFenster extends Frame {<br />
E<strong>in</strong>fachesFenster() {<br />
add(new Rechteck());<br />
setBackground(Color.yellow);<br />
setSize(200,150);<br />
setVisible(true);<br />
}<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
new E<strong>in</strong>fachesFenster();<br />
}<br />
11.1 Grundlagen 11-9
Ereignisgesteuerte Programmierung<br />
• Die Programme, die wir bisher betrachtet haben, arbeiten nach dem Pr<strong>in</strong>zip der<br />
E<strong>in</strong>-Ausgabe-Programmierung.<br />
• Dieses Modell wird jetzt zur ereignisgesteuerten Programmierung erweitert.<br />
Ereignisse s<strong>in</strong>d beispielsweise das Drücken e<strong>in</strong>er Taste, die Betätigung des<br />
Rollbalkens oder die Bewegung der Maus.<br />
• Es gibt viele Varianten der ereignisgesteuerten Programmierung. In <strong>Java</strong> wird das<br />
sogenannte Delegation Based Event Handl<strong>in</strong>g verwendet. Es bietet die Möglichkeit,<br />
GUI-Ereignisse an beliebige Objekte weiterzuleiten und dort zu behandeln. Auf<br />
diese Weise können die Oberfläche und die eigentliche Anwendung klar<br />
vone<strong>in</strong>ander getrennt werden.<br />
11.1 Grundlagen 11-10
Ereignisgesteuerte Programmierung<br />
• Jedes Ereignis besitzt e<strong>in</strong>e Quelle (Source). E<strong>in</strong> Ereignis kann von Beobachtern<br />
(Listener) wahrgenommen werden. Die Anmeldung von Beobachtern zur<br />
Benachrichtigung vom E<strong>in</strong>treten e<strong>in</strong>es Ereignisses ist frei programmierbar und muss<br />
immer explizit erfolgen.<br />
• Es ist nicht festgelegt, <strong>in</strong> welcher Reihenfolge die Beobachter vom E<strong>in</strong>treten e<strong>in</strong>es<br />
Ereignisses <strong>in</strong>formiert werden. Sichergestellt ist lediglich, dass jeder Beobachter<br />
e<strong>in</strong>e Kopie des ursprünglichen Ereignisses erhält.<br />
• Bei der Verbreitung von Ereignissen ist zwischen den Modi s<strong>in</strong>gle-cast und<br />
multi-cast zu unterscheiden. Für S<strong>in</strong>gle-Cast-Ereignisse wird der Beobachter mit<br />
e<strong>in</strong>er setxxListener-Methode gesetzt, für Multi-Cast-Ereignisse wird e<strong>in</strong><br />
Beobachter mit e<strong>in</strong>er addxxListener-Methode der Menge der Beobachter<br />
h<strong>in</strong>zugefügt.<br />
11.1 Grundlagen 11-11
Beispiel: Schließen e<strong>in</strong>es Fensters<br />
• Um e<strong>in</strong> Fenster zu schließen, muss e<strong>in</strong> W<strong>in</strong>dowListener registriert werden.<br />
• Hierbei handelt es sich um e<strong>in</strong>en Beobachter, dessen Methode w<strong>in</strong>dowClos<strong>in</strong>g<br />
aufgerufen wird, wenn der Anwender das Fenster über e<strong>in</strong> System-Menü oder e<strong>in</strong>en<br />
Button schließen möchte.<br />
• Das Fenster wird durch setVisible(false) unsichtbar gemacht, se<strong>in</strong>e<br />
Ressourcen durch dispose() wieder freigegeben.<br />
11.1 Grundlagen 11-12
Beispiel: Schließen e<strong>in</strong>es Fensters<br />
import java.awt.*;<br />
import java.awt.event.*;<br />
public class W<strong>in</strong>dowClos<strong>in</strong>gAdapter extends W<strong>in</strong>dowAdapter {<br />
public void w<strong>in</strong>dowClos<strong>in</strong>g(W<strong>in</strong>dowEvent event) {<br />
event.getW<strong>in</strong>dow().setVisible(false);<br />
event.getW<strong>in</strong>dow().dispose();<br />
System.out.pr<strong>in</strong>tln("Das Fenster wurde geschlossen!");<br />
}<br />
}<br />
Frame wnd = new Frame();<br />
wnd.addW<strong>in</strong>dowListener(new W<strong>in</strong>dowClos<strong>in</strong>gAdapter());<br />
wnd.setSize(400,300);<br />
wnd.setVisible(true);<br />
11.1 Grundlagen 11-13
Adapter-Klassen<br />
• E<strong>in</strong>e Adapter-Klasse ist e<strong>in</strong>e Klasse, die e<strong>in</strong>e gegebene Schnittstelle implementiert,<br />
<strong>in</strong>dem sie jede abstrakte Methode durch e<strong>in</strong>en leeren Rumpf realisiert.<br />
• Adapter-Klassen werden verwendet, wenn von e<strong>in</strong>er Schnittstelle lediglich e<strong>in</strong> Teil<br />
der Methoden benötigt wird, der Rest aber un<strong>in</strong>teressant ist. In diesem Fall leitet<br />
man e<strong>in</strong>e neue Klasse aus der Adapter-Klasse ab und überlagert nur die<br />
erforderlichen Methoden.<br />
• Beispiel: Die Klasse W<strong>in</strong>dowAdapter implementiert die Schnittstellen<br />
W<strong>in</strong>dowListener, W<strong>in</strong>dowStateListener und W<strong>in</strong>dowFocusListener durch<br />
leere Rümpfe. Hierbei handelt es sich um die folgenden Methoden:<br />
11.1 Grundlagen 11-14
Die Klasse W<strong>in</strong>dowAdapter<br />
void w<strong>in</strong>dowActivated(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowClosed(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowClos<strong>in</strong>g(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowDeactivated(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowDeiconified(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowGa<strong>in</strong>edFocus(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowIconified(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowLostFocus(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowOpened(W<strong>in</strong>dowEvent e)<br />
void w<strong>in</strong>dowStateChanged(W<strong>in</strong>dowEvent e)<br />
11.1 Grundlagen 11-15
E<strong>in</strong> e<strong>in</strong>führendes Beispiel<br />
Wir fassen zusammen:<br />
import java.awt.*;<br />
import java.awt.event.*;<br />
class W<strong>in</strong>dowClos<strong>in</strong>gAdapter extends W<strong>in</strong>dowAdapter {<br />
public void w<strong>in</strong>dowClos<strong>in</strong>g(W<strong>in</strong>dowEvent event) {<br />
event.getW<strong>in</strong>dow().setVisible(false);<br />
event.getW<strong>in</strong>dow().dispose();<br />
System.out.pr<strong>in</strong>tln("Das Fenster wurde geschlossen!");<br />
}<br />
}<br />
11.1 Grundlagen 11-16
class Rechteck extends Canvas {<br />
}<br />
public void pa<strong>in</strong>t(Graphics g) {<br />
g.setColor(Color.red);<br />
g.fillRect(20,20,100,40);<br />
g.setColor(Color.black);<br />
g.drawStr<strong>in</strong>g("E<strong>in</strong> rotes Rechteck",20,80);<br />
}<br />
11.1 Grundlagen 11-17
public class E<strong>in</strong>fachesFenster extends Frame {<br />
}<br />
E<strong>in</strong>fachesFenster(Str<strong>in</strong>g title) {<br />
super(title);<br />
addW<strong>in</strong>dowListener(new W<strong>in</strong>dowClos<strong>in</strong>gAdapter());<br />
setBackground(Color.yellow);<br />
setSize(400,200);<br />
add(new Rechteck());<br />
setVisible(true);<br />
}<br />
11.1 Grundlagen 11-18
E<strong>in</strong>fachesFenster e1 = new E<strong>in</strong>fachesFenster("Erstes Fenster"),<br />
e2 = new E<strong>in</strong>fachesFenster("Zweites Fenster"),<br />
e3 = new E<strong>in</strong>fachesFenster("Drittes Fenster");<br />
e1.setLocation(200,200);<br />
e2.setLocation(400,300);<br />
e3.setLocation(600,400);<br />
11.1 Grundlagen 11-19
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Grafische Grundelemente<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.2 Grafische Grundelemente 11-20
Das grafische Koord<strong>in</strong>atensystem<br />
• Die Ausgabe von grafischen Objekten basiert auf e<strong>in</strong>em zweidimensionalen<br />
Koord<strong>in</strong>atensystem, dessen Ursprung (0,0) <strong>in</strong> der l<strong>in</strong>ken oberen Ecke liegt.<br />
✲<br />
x<br />
y<br />
❄<br />
• Positive x-Werte erstrecken sich nach rechts, positive y-Werte nach unten. Die<br />
Maße<strong>in</strong>heit entspricht e<strong>in</strong>em Bildschirmpixel und ist somit geräteabhängig.<br />
11.2 Grafische Grundelemente 11-21
Der Benutzerbereich<br />
• Es steht nicht das gesamte Fenster für Ausgaben zur Verfügung. Oben, unten,<br />
l<strong>in</strong>ks und rechts wird Platz zur Ausgabe von Rahmen und Titelzeile benötigt.<br />
• Mit<br />
◦ getSize().width() und getSize().height()<br />
kann die Gesamtbreite bzw. -höhe e<strong>in</strong>es Fensters ermittelt werden. Durch<br />
◦ getInsets().left(), getInsets().right(), getInsets().top() und<br />
getInsets().bottom()<br />
lässt sich die Abmessung des Rahmens und durch Differenzbildung die des<br />
Benutzerbereichs (client area) bestimmen.<br />
11.2 Grafische Grundelemente 11-22
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
• void drawStr<strong>in</strong>g(Str<strong>in</strong>g s, <strong>in</strong>t x, <strong>in</strong>t y)<br />
drawStr<strong>in</strong>g schreibt den Str<strong>in</strong>g s an die Position (x,y). Diese Koord<strong>in</strong>aten stellen<br />
das l<strong>in</strong>ke Ende der Basisl<strong>in</strong>ie von s dar.<br />
• void drawChars(char[] c, <strong>in</strong>t offset, <strong>in</strong>t length, <strong>in</strong>t x, <strong>in</strong>t y)<br />
Diese Methode schreibt e<strong>in</strong> Zeichenfeld. Die Parameter offset und length<br />
können zur Angabe des ersten Zeichens und der Anzahl der auszugebenden<br />
Zeichen verwendet werden.<br />
11.2 Grafische Grundelemente 11-23
Beispiel: Die Anweisungen<br />
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
char[] c = {’a’,’b’,’c’,’d’,’e’,’f’};<br />
g.drawStr<strong>in</strong>g("Zeichenkette",50,50);<br />
g.drawChars(c,1,4,50,150);<br />
schreiben den Str<strong>in</strong>g "Zeichenkette" an die Position (50,50) und darunter die Zeichen<br />
"bcde" an die Position (50,150).<br />
11.2 Grafische Grundelemente 11-24
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
• void drawL<strong>in</strong>e(<strong>in</strong>t x1, <strong>in</strong>t y1, <strong>in</strong>t x2, <strong>in</strong>t y2)<br />
Diese Methode zieht e<strong>in</strong>e L<strong>in</strong>ie von der Position (x1,y1) zur Position (x2,y2).<br />
• void drawRect(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height)<br />
drawRect zeichnet e<strong>in</strong> Rechteck der Breite width und der Höhe height, dessen<br />
l<strong>in</strong>ke obere Ecke an der Position (x,y) liegt.<br />
• void drawRoundRect(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height, <strong>in</strong>t<br />
arcWidth, <strong>in</strong>t arcHeight)<br />
Es wird e<strong>in</strong> Rechteck mit abgerundeten Ecken gezeichnet. arcWidth und<br />
arcHeight bestimmen die Halbachsen der Ellipse, die zur Darstellung der Ecken<br />
verwendet wird.<br />
11.2 Grafische Grundelemente 11-25
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
• void drawPolygon(<strong>in</strong>t[] x, <strong>in</strong>t[] y, <strong>in</strong>t anzahl)<br />
Diese Methode zeichnet e<strong>in</strong>en L<strong>in</strong>ienzug. Die x-Koord<strong>in</strong>aten der Punkte werden<br />
dem ersten Parameter, die y-Koord<strong>in</strong>aten dem zweiten Parameter entnommen. Die<br />
Anzahl der Koord<strong>in</strong>atenpaare wird durch den dritten Parameter festgelegt. Der<br />
Polygonzug wird geschlossen. Durch drawPolyl<strong>in</strong>e kann e<strong>in</strong> nichtgeschlossener<br />
L<strong>in</strong>ienzug dargestellt werden.<br />
E<strong>in</strong>e andere Möglichkeit, e<strong>in</strong> Polygon zu erzeugen, besteht dar<strong>in</strong>, e<strong>in</strong>en Konstruktor<br />
der Klasse Polygon aufzurufen:<br />
• Polygon(<strong>in</strong>t[] x, <strong>in</strong>t[] y, <strong>in</strong>t anzahl)<br />
Polygon()<br />
Durch addPo<strong>in</strong>t kann e<strong>in</strong> Polygon erweitert werden.<br />
11.2 Grafische Grundelemente 11-26
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
• void drawOval(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height)<br />
Mit dieser Methode können Kreise und Ellipsen gezeichnet werden. Die Parameter<br />
spezifizieren e<strong>in</strong> Rechteck wie <strong>in</strong> der Methode drawRect. Es wird die größte<br />
Ellipse gezeichnet, die <strong>in</strong> dieses Rechteck h<strong>in</strong>e<strong>in</strong>passt.<br />
• void drawArc(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height, <strong>in</strong>t<br />
startAngle, <strong>in</strong>t arcAngle)<br />
Mit drawArc kann e<strong>in</strong> Kreisbogen dargestellt werden. Die ersten vier Parameter<br />
geben den Kreis, startAngle den Anfangspunkt und arcAngle den W<strong>in</strong>kel an.<br />
11.2 Grafische Grundelemente 11-27
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
Die folgenden Funktionen stellen die gleichen geometrischen Objekte dar wie die<br />
obigen, zeichnen aber nicht nur deren Umrisse, sondern füllen auch ihre Fläche aus.<br />
• void fillRect( ... )<br />
• void fillRoundRect( ... )<br />
• void fillPolygon( ... )<br />
• void fillOval( ... )<br />
• void fillArc( ... )<br />
11.2 Grafische Grundelemente 11-28
Elementare Grafikrout<strong>in</strong>en (Auswahl)<br />
• void clearRect(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height)<br />
Die Methode clearRect überschreibt das angegebene Rechteck mit der aktuellen<br />
H<strong>in</strong>tergrundfarbe.<br />
• void copyArea(<strong>in</strong>t x, <strong>in</strong>t y, <strong>in</strong>t width, <strong>in</strong>t height, <strong>in</strong>t dx, <strong>in</strong>t<br />
dy)<br />
copyArea kopiert das ausgewählte Rechteck an die Position (x + dx, y + dy).<br />
• Mit e<strong>in</strong>er Clipp<strong>in</strong>g-Region kann die Ausgabe auf e<strong>in</strong>en bestimmten Bereich<br />
e<strong>in</strong>geschränkt werden.<br />
11.2 Grafische Grundelemente 11-29
Schriftarten<br />
• Ohne zusätzliche Anweisungen wird Text <strong>in</strong> e<strong>in</strong>em systemabhängigen<br />
Standard-Font ausgegeben. Um e<strong>in</strong>en anderen Font zur Textausgabe zu<br />
verwenden, muss zuerst e<strong>in</strong> Font-Objekt erzeugt und dann <strong>in</strong> den Grafik-Kontext<br />
e<strong>in</strong>getragen werden.<br />
• E<strong>in</strong> Font-Objekt kann mit e<strong>in</strong>em Konstruktor der Klasse Font erzeugt werden:<br />
Font(Str<strong>in</strong>g name, <strong>in</strong>t style, <strong>in</strong>t size)<br />
• Mit<br />
void setFont(Font font) und<br />
Font getFont()<br />
kann der Font gesetzt bzw. abgefragt werden.<br />
11.2 Grafische Grundelemente 11-30
Schriftarten<br />
• Der Parameter name gibt den Namen der gewünschten Schrift an. Font-Namen<br />
s<strong>in</strong>d beispielsweise Times New Roman, Helvetica oder Courier.<br />
• Schriften können Serifen besitzen oder auch serifenlos se<strong>in</strong>.<br />
• E<strong>in</strong> weiteres Kennzeichen e<strong>in</strong>er Schrift ist die Zeichenbreite. Diese kann variabel<br />
oder konstant se<strong>in</strong>. Bei konstanter Zeichenbreite bezeichnet man e<strong>in</strong>e Schrift als<br />
monospaced.<br />
• Beispiel: Der Font, <strong>in</strong> dem diese Folien geschrieben wurden, ist die serifenlose<br />
Variante der „Lat<strong>in</strong> Computer Modern“.<br />
• Es können auch die Font-Namen Serif, SansSerif und Monospaced verwendet<br />
werden. Sie werden auf entsprechende Fonts abgebildet.<br />
11.2 Grafische Grundelemente 11-31
Schriftarten<br />
• Der Parameter size gibt die Schriftgröße an. Übliche Schriftgrößen für Text liegen<br />
zwischen 10 pt und 12 pt.<br />
• Die Schriftart wird durch den Parameter style beschrieben:<br />
Name Wert Bedeutung<br />
Font.PLAIN 0 Standard-Font<br />
Font.BOLD 1 Fettdruck<br />
Font.ITALIC 2 Kursivdruck<br />
3 fetter Kursivdruck<br />
11.2 Grafische Grundelemente 11-32
Schriftarten<br />
Beispiel: Die folgenden Anweisungen bewirken, dass der Str<strong>in</strong>g "Zeichenkette" <strong>in</strong> e<strong>in</strong>er<br />
Schrift mit konstanter Zeichenbreite <strong>in</strong> fettem Kursivdruck <strong>in</strong> 12-Punkt-Schrift an die<br />
Position (50,350) geschrieben wird:<br />
Font f = new Font("Monospaced",3,12);<br />
g.setFont(f);<br />
g.drawStr<strong>in</strong>g("Zeichenkette",50,350);<br />
11.2 Grafische Grundelemente 11-33
Schriftarten<br />
Das folgende Beispiel gibt die drei Standardschriften <strong>in</strong> 36 Punkt aus:<br />
public void pa<strong>in</strong>t(Graphics g) {<br />
}<br />
Font font;<br />
Str<strong>in</strong>g[] arfonts = {"Serif","SansSerif","Monospaced"};<br />
for (<strong>in</strong>t i = 0; i < arfonts.length; ++i) {<br />
font = new Font(arfonts[i],Font.PLAIN,36);<br />
g.setFont(font);<br />
g.drawStr<strong>in</strong>g(arfonts[i],10,30 + (i + 1) * (36 + 5));<br />
}<br />
11.2 Grafische Grundelemente 11-34
Schriftarten<br />
• Die Klasse Font besitzt Methoden, um Informationen über den aktuellen Font zu<br />
gew<strong>in</strong>nen:<br />
◦ Str<strong>in</strong>g getFamily()<br />
◦ <strong>in</strong>t getStyle()<br />
◦ <strong>in</strong>t getSize()<br />
• Die Klasse FontMetrics stellt Methoden zur Verfügung, mit denen die<br />
Größenmaßzahlen e<strong>in</strong>zelner Zeichen – wie Oberlänge, Unterlänge oder Breite –,<br />
Größen wie der Zeilenabstand oder die Länge e<strong>in</strong>es Str<strong>in</strong>gs ermittelt werden<br />
können.<br />
◦ <strong>in</strong>t charWidth(char ch)<br />
◦ <strong>in</strong>t str<strong>in</strong>gWidth(Str<strong>in</strong>g str)<br />
11.2 Grafische Grundelemente 11-35
Farbmodell<br />
E<strong>in</strong>e Möglichkeit, <strong>in</strong> <strong>Java</strong> Farben zu<br />
benutzen, basiert auf dem RGB-Farbmodell<br />
(Rot-Grün-Blau-Farbmodell). Jede dieser<br />
drei Grundfarben wird durch 8 Bits<br />
dargestellt. Der Anteil e<strong>in</strong>er Grundfarbe<br />
kann also durch e<strong>in</strong>e Dezimalzahl zwischen<br />
0 und 255 beschrieben werden. Für die<br />
gesamte Farbtiefe ergeben sich somit 24<br />
Bits.<br />
Farbe Rot Grün Blau<br />
Weiß 255 255 255<br />
Grau 127 127 127<br />
Schwarz 0 0 0<br />
Rot 255 0 0<br />
Grün 0 255 0<br />
Blau 0 0 255<br />
Gelb 255 255 0<br />
Magenta 255 0 255<br />
Cyan 0 255 255<br />
<strong>Java</strong> unterstützt weitere Farbmodelle, <strong>in</strong> denen Farben z. B. durch Farbton, Intensität<br />
und Helligkeit dargestellt werden.<br />
11.2 Grafische Grundelemente 11-36
Erzeugung von Farben<br />
• Farben werden durch die Klasse Color dargestellt. Jedes Objekt repräsentiert e<strong>in</strong>e<br />
Farbe, die durch ihren RGB-Wert e<strong>in</strong>deutig gekennzeichnet ist.<br />
• Konstruktoren:<br />
◦ Color(<strong>in</strong>t r, <strong>in</strong>t g, <strong>in</strong>t b)<br />
◦ Color(float r, float g, float b)<br />
Der erste Konstruktor erwartet ganzzahlige Werte im Bereich von 0 bis 255, der<br />
zweite Fließkommazahlen zwischen 0.0 und 1.0. Der Wert 0.0 entspricht der<br />
ganzzahligen 0, der Wert 1.0 der ganzzahligen 255.<br />
11.2 Grafische Grundelemente 11-37
Erzeugung von Farben<br />
• Die Klasse Color stellt etliche Farben als statische Objekte zur Verfügung:<br />
◦ static Color black<br />
◦ static Color red<br />
◦ static Color green<br />
◦ static Color blue<br />
◦ . . .<br />
• Von e<strong>in</strong>em bestehenden Farbobjekt kann der RGB-Wert mit den Methoden<br />
◦ <strong>in</strong>t getRed(),<br />
◦ <strong>in</strong>t getGreen() und<br />
◦ <strong>in</strong>t getBlue()<br />
ermittelt werden.<br />
11.2 Grafische Grundelemente 11-38
Verwendung von Farben<br />
• Um Farben bei der Ausgabe von Schrift oder Grafik zu verwenden, muss e<strong>in</strong> Objekt<br />
der Klasse Color erzeugt und mithilfe der Methode<br />
void setColor(Color c)<br />
dem grafischen Kontext zugewiesen werden.<br />
• Die Ausgabe erfolgt solange <strong>in</strong> der neuen Farbe, bis dem Kontext e<strong>in</strong>e neue Farbe<br />
zugeordnet wird.<br />
• Mit Color getColor() wird die aktuelle Farbe abgefragt.<br />
11.2 Grafische Grundelemente 11-39
Verwendung von Farben<br />
Beispiel:<br />
public void pa<strong>in</strong>t(Graphics g) {<br />
g.setColor(Color.red);<br />
g.drawStr<strong>in</strong>g("Zeichenkette",200,500);<br />
g.setColor(new Color(200,200,0));<br />
g.drawOval(50,400,60,160);<br />
...<br />
}<br />
11.2 Grafische Grundelemente 11-40
Die Klasse SystemColor<br />
• Die Klasse SystemColor stellt e<strong>in</strong>e Reihe von Farben zur Verfügung, die den<br />
Farben des Desktops entsprechen. Damit können Anwendungen entwickelt werden,<br />
die im Aussehen an die Betriebssystemumgebung angepasst s<strong>in</strong>d.<br />
• Beispiele:<br />
◦ SystemColor.desktop<br />
H<strong>in</strong>tergrundfarbe des Desktops<br />
◦ SystemColor.w<strong>in</strong>dow<br />
H<strong>in</strong>tergrundfarbe für Fenster<br />
◦ SystemColor.text<br />
H<strong>in</strong>tergrundfarbe für Text<br />
11.2 Grafische Grundelemente 11-41
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Fensterklassen<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.3 Fensterklassen 11-42
Fensterklassen<br />
Das AWT enthält e<strong>in</strong>e Reihe von Fensterklassen, die über e<strong>in</strong>e Vererbungsl<strong>in</strong>ie<br />
mite<strong>in</strong>ander verbunden s<strong>in</strong>d. An der Spitze steht die Klasse Component:<br />
• Component<br />
◦ Conta<strong>in</strong>er<br />
∗ Panel<br />
- Applet<br />
∗ W<strong>in</strong>dow<br />
- Frame<br />
- Dialog<br />
· FileDialog<br />
◦ Button<br />
◦ Canvas<br />
◦ Checkbox<br />
11.3 Fensterklassen 11-43
Fensterklassen<br />
• Component ist e<strong>in</strong>e abstrakte Klasse, deren Objekte Programmelemente darstellen,<br />
die e<strong>in</strong>e Größe und e<strong>in</strong>e Position besitzen und die Ereignisse senden und auf<br />
Ereignisse reagieren können.<br />
• Conta<strong>in</strong>er ist ebenfalls e<strong>in</strong>e abstrakte Klasse. Sie erlaubt es, <strong>in</strong>nerhalb e<strong>in</strong>er<br />
Komponente weitere Komponenten aufzunehmen. Conta<strong>in</strong>er stellt Methoden,<br />
um Komponenten h<strong>in</strong>zuzufügen oder zu entfernen, bereit. Mit den<br />
LayoutManager-Klassen werden die Komponenten positioniert.<br />
11.3 Fensterklassen 11-44
Fensterklassen<br />
• Panel ist die e<strong>in</strong>fachste konkrete Klasse mit den Eigenschaften von Component<br />
und Conta<strong>in</strong>er.<br />
• Applet ist e<strong>in</strong>e direkte Unterklasse von Panel. E<strong>in</strong> Applet besitzt also die<br />
Fähigkeiten der Klassen Component und Conta<strong>in</strong>er. Diese Klasse spielt e<strong>in</strong>e<br />
entscheidende Rolle <strong>in</strong> der Entwicklung von Applets.<br />
• Die Klasse W<strong>in</strong>dow abstrahiert e<strong>in</strong> Top-Level-W<strong>in</strong>dow ohne Rahmen, Titelleiste<br />
und Menü. Sie ist für Anwendungen geeignet, die die Kontrolle über das gesamte<br />
Fenster benötigen.<br />
• Frame repräsentiert e<strong>in</strong> Top-Level-W<strong>in</strong>dow mit Rahmen, Titelleiste und<br />
optionalem Menü. E<strong>in</strong>em Frame kann e<strong>in</strong> Icon zugeordnet werden, das angezeigt<br />
wird, wenn e<strong>in</strong> Fenster m<strong>in</strong>imiert wird.<br />
11.3 Fensterklassen 11-45
Aufrufen und Schließen e<strong>in</strong>es Fensters<br />
• Um e<strong>in</strong> Fenster auf dem Bildschirm anzuzeigen, muss zunächst e<strong>in</strong>e geeignete<br />
Fensterklasse <strong>in</strong>stanziiert werden. Dafür kommen Klassen wie W<strong>in</strong>dow, Frame,<br />
Dialog, Applet und FileDialog <strong>in</strong> Frage. Die Klassen haben unterschiedliche<br />
Konstruktoren.<br />
• Nach der Instanziierung wird die Methode<br />
setVisible(boolean visible)<br />
aufgerufen, um das Fenster anzuzeigen. Wird true übergeben, wird das Fenster<br />
angezeigt, andernfalls geschlossen.<br />
• Um e<strong>in</strong> Fenster zu schließen, s<strong>in</strong>d die Methoden setVisible(false) und<br />
dispose() aufzurufen.<br />
11.3 Fensterklassen 11-46
Eigenschaften e<strong>in</strong>es Fensters<br />
• Größe und Position, geerbt von Component<br />
• Aktivierungskomponente, geerbt von Component<br />
• Fensterelemente<br />
◦ Titelleiste, Menü, Icon, Mauscursor, Standardfont, Vorder- und H<strong>in</strong>tergrundfarbe<br />
• Die Eigenschaften e<strong>in</strong>es Fensters können mithilfe spezieller Methoden gesetzt und<br />
abgefragt werden.<br />
• Beispiel: Objekte der Klasse Frame besitzen e<strong>in</strong>en Rahmen, e<strong>in</strong>e Titelleiste und<br />
optional e<strong>in</strong> Menü, Objekte der Klasse W<strong>in</strong>dow h<strong>in</strong>gegen nicht.<br />
11.3 Fensterklassen 11-47
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Ereignisse und Widgets<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.4 Ereignisse und Widgets 11-48
Ereignisgesteuerte Programmierung<br />
• Ereignisse s<strong>in</strong>d beispielsweise das Drücken e<strong>in</strong>er Taste, die Betätigung des<br />
Rollbalkens oder die Bewegung der Maus.<br />
• Jedes Ereignis besitzt e<strong>in</strong>e Quelle (Source).<br />
• E<strong>in</strong> Ereignis kann von Beobachtern (Listener) wahrgenommen werden. Die<br />
Anmeldung von Beobachtern zur Benachrichtigung vom E<strong>in</strong>treten e<strong>in</strong>es Ereignisses<br />
ist frei programmierbar und muss immer explizit erfolgen.<br />
• Es ist nicht festgelegt, <strong>in</strong> welcher Reihenfolge die Beobachter vom E<strong>in</strong>treten e<strong>in</strong>es<br />
Ereignisses <strong>in</strong>formiert werden. Sichergestellt ist lediglich, dass jeder Beobachter<br />
e<strong>in</strong>e Kopie des ursprünglichen Ereignisses erhält.<br />
11.4 Ereignisse und Widgets 11-49
Ereignisgesteuerte Programmierung<br />
• Bei der Verbreitung von Ereignissen ist zwischen den Modi s<strong>in</strong>gle-cast und<br />
multi-cast zu unterscheiden. Für S<strong>in</strong>gle-Cast-Ereignisse wird der Beobachter mit<br />
e<strong>in</strong>er setxxListener-Methode gesetzt, für Multi-Cast-Ereignisse wird e<strong>in</strong><br />
Beobachter mit e<strong>in</strong>er addxxListener-Methode der Menge der Beobachter<br />
h<strong>in</strong>zugefügt.<br />
• E<strong>in</strong>e Adapter-Klasse ist e<strong>in</strong>e Klasse, die e<strong>in</strong>e gegebene Schnittstelle implementiert,<br />
<strong>in</strong>dem sie jede abstrakte Methode durch e<strong>in</strong>en leeren Rumpf realisiert.<br />
Adapter-Klassen werden verwendet, wenn von e<strong>in</strong>er Schnittstelle lediglich e<strong>in</strong> Teil<br />
der Methoden benötigt wird, der Rest aber un<strong>in</strong>teressant ist. In diesem Fall leitet<br />
man e<strong>in</strong>e neue Klasse aus der Adapter-Klasse ab und überlagert nur die<br />
erforderlichen Methoden.<br />
11.4 Ereignisse und Widgets 11-50
Ereignisklassen<br />
• EventObject<br />
◦ AWTEvent<br />
∗ ComponentEvent<br />
- FocusEvent<br />
- InputEvent<br />
- KeyEvent<br />
- MouseEvent<br />
- Conta<strong>in</strong>erEvent<br />
- W<strong>in</strong>dowEvent<br />
∗ ActionEvent<br />
∗ AdjustmentEvent<br />
∗ ItemEvent<br />
∗ TextEvent<br />
11.4 Ereignisse und Widgets 11-51
EventListener-Schnittstellen<br />
• EventListener<br />
◦ FocusListener<br />
◦ ActionListener<br />
◦ AdjustmentListener<br />
◦ ItemListener<br />
◦ TextListener<br />
◦ KeyListener<br />
◦ MouseListener<br />
◦ MouseMotionListener<br />
◦ W<strong>in</strong>dowListener<br />
◦ Conta<strong>in</strong>erListener<br />
◦ ComponentListener<br />
11.4 Ereignisse und Widgets 11-52
Low-Level-Events<br />
Beispiel: W<strong>in</strong>dow-Events<br />
• w<strong>in</strong>dowOpened<br />
• w<strong>in</strong>dowActivated, w<strong>in</strong>dowDeactivated<br />
• w<strong>in</strong>dowClosed<br />
• w<strong>in</strong>dowClos<strong>in</strong>g<br />
• w<strong>in</strong>dowIconified, w<strong>in</strong>dowDeiconified<br />
11.4 Ereignisse und Widgets 11-53
Widgets<br />
Fensterelemente mit E<strong>in</strong>- und/oder Ausgabefunktionalität werden als Widgets<br />
(w<strong>in</strong>dow gadgets) bezeichnet. Die Anordnung der Widgets <strong>in</strong> e<strong>in</strong>em Fenster wird<br />
durch den Layout-Manager durchgeführt. Widgets s<strong>in</strong>d beispielsweise:<br />
• Label<br />
• Rollbalken<br />
• Schaltflächen (buttons)<br />
• Checkboxen und Checkboxgruppen (radio buttons)<br />
11.4 Ereignisse und Widgets 11-54
Widgets<br />
• Textfelder und Textbereiche<br />
• Auswahlboxen<br />
• Listen<br />
• Canvas<br />
• Panels<br />
• Dateidialogboxen (nicht für Applets)<br />
• Menüs (nicht für Applets)<br />
11.4 Ereignisse und Widgets 11-55
Schritte zur Realisierung e<strong>in</strong>es Widgets<br />
• Schnittstelle angeben<br />
• Widget deklarieren und <strong>in</strong>itialisieren<br />
• Widget dem Layout h<strong>in</strong>zufügen<br />
• Beobachter registrieren<br />
• Ereignis behandeln<br />
Man beachte, dass mehrere Widgettypen dieselbe Ereignisklasse verwenden, z. B.<br />
benutzen Schaltflächen und Textfelder die Klasse ActionListener.<br />
11.4 Ereignisse und Widgets 11-56
Beispiel: Rollbalken<br />
Als erstes Beispiel betrachten wir jetzt die Programmierung e<strong>in</strong>es Rollbalkens.<br />
import java.awt.*;<br />
import java.awt.event.*;<br />
public class W<strong>in</strong>dowBl<strong>in</strong>d extends Frame<br />
implements AdjustmentListener {<br />
private Scrollbar schieber;<br />
private <strong>in</strong>t schieberWert;<br />
11.4 Ereignisse und Widgets 11-57
public W<strong>in</strong>dowBl<strong>in</strong>d() {<br />
setLayout(new FlowLayout());<br />
setBackground(Color.white);<br />
schieber = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,101);<br />
add(schieber);<br />
addW<strong>in</strong>dowListener(new W<strong>in</strong>dowClos<strong>in</strong>gAdapter());<br />
schieber.addAdjustmentListener(this);<br />
}<br />
11.4 Ereignisse und Widgets 11-58
public void pa<strong>in</strong>t(Graphics g) {<br />
g.drawStr<strong>in</strong>g("Rollbalkenwert ist " + schieberWert,120,200);<br />
g.setColor(Color.red);<br />
g.drawRect(40,80,60,100);<br />
g.fillRect(40,80,60,schieberWert);<br />
g.setColor(Color.blue);<br />
g.drawRect(120,80,60,100);<br />
g.fillRect(120,80 + schieberWert,60,100 - schieberWert);<br />
g.setColor(Color.green);<br />
g.drawRect(200,80,60,100);<br />
g.fillRect(200,80,60,100 - schieberWert);<br />
}<br />
11.4 Ereignisse und Widgets 11-59
public void adjustmentValueChanged(AdjustmentEvent e) {<br />
schieberWert = schieber.getValue();<br />
repa<strong>in</strong>t();<br />
}<br />
11.4 Ereignisse und Widgets 11-60
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
W<strong>in</strong>dowBl<strong>in</strong>d f = new W<strong>in</strong>dowBl<strong>in</strong>d();<br />
f.setSize(400,300);<br />
f.setVisible(true);<br />
}<br />
}<br />
11.4 Ereignisse und Widgets 11-61
Beispiel: Label und Button<br />
... implements ActionListener {<br />
private Label title;<br />
private Button knopf;<br />
private <strong>in</strong>t anzahl = 0;<br />
public Konstruktor() {<br />
setLayout(new FlowLayout());<br />
title = new Label("Zählknopf:");<br />
knopf = new Button("Drück mich!");<br />
add(title);<br />
add(knopf);<br />
knopf.addActionListener(this);<br />
}<br />
11.4 Ereignisse und Widgets 11-62
public void pa<strong>in</strong>t(Graphics g) {<br />
g.drawStr<strong>in</strong>g("Der Knopf wurde " + anzahl +<br />
" mal gedrückt.",10,80);<br />
}<br />
public void actionPerformed(ActionEvent event) {<br />
anzahl++;<br />
repa<strong>in</strong>t();<br />
}<br />
}<br />
11.4 Ereignisse und Widgets 11-63
Weitere Widgets<br />
• Textfield:<br />
ActionListener, addActionListener<br />
void actionPerformed(ActionEvent event)<br />
• Checkbox, Checkboxgroup:<br />
ItemListener, addItemListener<br />
void itemStateChanged(ItemEvent event)<br />
• Choice:<br />
ItemListener, addItem, addItemListener<br />
void itemStateChanged(ItemEvent event)<br />
11.4 Ereignisse und Widgets 11-64
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Applets<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.5 Applets 11-65
• Anwendungen (Applikationen)<br />
Anwendungen und Applets<br />
◦ Anwendungen bilden eigenständige Programme. Zur Ausführung benötigen sie<br />
nur den <strong>Java</strong>-Interpreter und die .class-Dateien der beteiligten Klassen.<br />
◦ Jede Klasse, die die Methode public static void ma<strong>in</strong> enthält, kann als<br />
Anwendung benutzt werden.<br />
• Applets (little applications)<br />
◦ Applets s<strong>in</strong>d kle<strong>in</strong>e Programme, die <strong>in</strong> e<strong>in</strong>e Html-Seite e<strong>in</strong>gebettet s<strong>in</strong>d und nur<br />
<strong>in</strong>nerhalb e<strong>in</strong>es Web-Browsers oder e<strong>in</strong>es Applet-Viewers ausgeführt werden<br />
können.<br />
◦ Applets werden nicht durch die Methode ma<strong>in</strong> gestartet, sondern müssen aus<br />
der Klasse Applet abgeleitet und entsprechend konstruiert werden.<br />
11.5 Applets 11-66
import java.awt.*;<br />
import java.applet.*;<br />
E<strong>in</strong> kle<strong>in</strong>es Applet: <strong>Java</strong>-Datei<br />
public class M<strong>in</strong>imalApplet extends Applet {<br />
}<br />
public void pa<strong>in</strong>t(Graphics g) {<br />
g.drawStr<strong>in</strong>g("Test-Ausgabe",0,20);<br />
}<br />
11.5 Applets 11-67
E<strong>in</strong> kle<strong>in</strong>es Applet: Html-Seite<br />
<br />
<br />
Applet-Test<br />
<br />
<br />
<br />
Hier steht das Applet.<br />
<br />
<br />
11.5 Applets 11-68
Anwendungen und Applets<br />
• E<strong>in</strong> Applet wird immer aus der Klasse Applet abgeleitet. Bei e<strong>in</strong>er Anwendung ist<br />
es dagegen gleichgültig, woraus die Hauptklasse abgeleitet wird.<br />
• E<strong>in</strong>e Anwendung wird gestartet, <strong>in</strong>dem vom <strong>Java</strong>-Interpreter die Methode ma<strong>in</strong><br />
aufgerufen wird. Das Starten e<strong>in</strong>es Applets wird dadurch erreicht, dass der Browser<br />
oder der Applet-Viewer die Applet-Klasse <strong>in</strong>stanziiert und die Methoden <strong>in</strong>it und<br />
start aufruft.<br />
• Aus Gründen der Sicherheit darf e<strong>in</strong> Applet <strong>in</strong> der Regel weder auf Dateien des<br />
lokalen Rechners zugreifen noch externe Programme auf dem Rechner starten.<br />
11.5 Applets 11-69
Anwendungen und Applets<br />
• E<strong>in</strong> Applet arbeitet immer ereignisorientiert. Im Gegensatz dazu kann e<strong>in</strong>e<br />
Anwendung auf die Behandlung von Ereignissen verzichten und alle E<strong>in</strong>- und<br />
Ausgaben textbasiert durchführen.<br />
• Im Vergleich zu Anwendungen bieten Applets e<strong>in</strong>ige zusätzliche Möglichkeiten.<br />
11.5 Applets 11-70
Die Klasse Applet<br />
Die Klasse Applet steht <strong>in</strong> der Vererbungshierarchie unter der Klasse Component<br />
und Conta<strong>in</strong>er. Sie besitzt damit deren Eigenschaften.<br />
• Component<br />
◦ Conta<strong>in</strong>er<br />
∗ Panel<br />
- Applet<br />
Bezüglich der Reaktion auf Ereignisse und die Registrierung und Programmierung von<br />
Listener-Klassen verhält sich e<strong>in</strong> Applet wie jedes andere Fenster.<br />
11.5 Applets 11-71
• <strong>in</strong>it(): Initialisierung e<strong>in</strong>es Applets<br />
• start(): Start e<strong>in</strong>es Applets<br />
• stop(): Stopp e<strong>in</strong>es Applets,<br />
z. B. beim Laden e<strong>in</strong>er anderen Seite.<br />
Methoden<br />
start und stop können mehrfach während der Lebensdauer e<strong>in</strong>es Applets<br />
aufgerufen werden.<br />
• pa<strong>in</strong>t(Graphics g): Methode zum Zeichnen<br />
• destroy(): Beenden e<strong>in</strong>es Applets<br />
11.5 Applets 11-72
Beispiel: Rollbalken<br />
Als Beispiel schreiben wir das Rollbalkenprogramm als Applet.<br />
import java.awt.*;<br />
import java.awt.event.*;<br />
import java.applet.Applet;<br />
public class W<strong>in</strong>dowBl<strong>in</strong>d extends Applet<br />
implements AdjustmentListener {<br />
private Scrollbar schieber;<br />
private <strong>in</strong>t schieberWert;<br />
11.5 Applets 11-73
public void <strong>in</strong>it () {<br />
setBackground(Color.white);<br />
schieber = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,101);<br />
add(schieber);<br />
schieber.addAdjustmentListener(this);<br />
}<br />
11.5 Applets 11-74
public void pa<strong>in</strong>t(Graphics g) {<br />
showStatus("Rollbalkenwert ist " + schieberWert);<br />
g.setColor(Color.red);<br />
g.drawRect(40,80,60,100);<br />
g.fillRect(40,80,60,schieberWert);<br />
g.setColor(Color.blue);<br />
g.drawRect(120,80,60,100);<br />
g.fillRect(120,80 + schieberWert,60,100 - schieberWert);<br />
g.setColor(Color.green);<br />
g.drawRect(200,80,60,100);<br />
g.fillRect(200,80,60,100 - schieberWert);<br />
}<br />
11.5 Applets 11-75
public void adjustmentValueChanged(AdjustmentEvent e) {<br />
schieberWert = schieber.getValue();<br />
repa<strong>in</strong>t();<br />
}<br />
}<br />
11.5 Applets 11-76
Anwendungen und Applets<br />
Dies s<strong>in</strong>d die wesentlichen Schritte, um e<strong>in</strong>e Anwendung <strong>in</strong> e<strong>in</strong> Applet zu konvertieren.<br />
Die Anwendung darf nur Elemente benutzen, die auch für Applets erlaubt s<strong>in</strong>d.<br />
• Html-Seite erzeugen<br />
• ma<strong>in</strong>-Methode löschen<br />
• Aus dem Paket java.applet importieren, JApplet statt JFrame erweitern<br />
• Konstruktor <strong>in</strong> <strong>in</strong>it umbenennen, ggf. start, stop, destroy schreiben<br />
• Layout festlegen<br />
• Bei mehreren Klassen: jar-Datei erzeugen<br />
11.5 Applets 11-77
Anwendungen und Applets<br />
Dies s<strong>in</strong>d die wesentlichen Schritte, um e<strong>in</strong> Applet <strong>in</strong> e<strong>in</strong>e Anwendung zu konvertieren.<br />
Das Applet darf ke<strong>in</strong>e speziellen Methoden der applet-Klasse verwenden.<br />
• import applet löschen<br />
• frame statt applet erweitern<br />
• <strong>in</strong>it als Konstruktor schreiben<br />
• ma<strong>in</strong>-Methode erzeugen<br />
• Methode zum Fenster schließen h<strong>in</strong>zufügen<br />
• Layout festlegen<br />
11.5 Applets 11-78
<strong>Grafikprogrammierung</strong> <strong>in</strong> <strong>Java</strong>:<br />
Die Sw<strong>in</strong>g-Klassen<br />
11.1 Grundlagen<br />
11.2 Grafische Grundelemente<br />
11.3 Fensterklassen<br />
11.4 Ereignisse und Widgets<br />
11.5 Applets<br />
11.6 Die Sw<strong>in</strong>g-Klassen<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-79
Die <strong>Java</strong> Foundation Classes<br />
Seit der Version 1.2 des JDK werden die grafischen Fähigkeiten von <strong>Java</strong> unter dem<br />
Begriff <strong>Java</strong> Foundation Classes (JFC) zusammengefasst. Die drei wichtigsten<br />
Bestandteile s<strong>in</strong>d:<br />
• Das Abstract W<strong>in</strong>dow Toolkit (AWT) stellt elementare Grafik- und<br />
Fensterfunktionen auf der Basis der jeweiligen Zielmasch<strong>in</strong>e zur Verfügung.<br />
• Das Sw<strong>in</strong>g Toolset bietet darüber h<strong>in</strong>ausgehende Möglichkeiten zur Konstruktion<br />
komplexer grafischer Oberflächen. Insbesondere wird e<strong>in</strong> „pluggable look and feel“<br />
ermöglicht.<br />
• Die dritte wichtige Komponente ist die <strong>Java</strong> 2D API (Klassen für zweidimensionale<br />
Grafikverarbeitung) mit diversen Grafikoperationen und Bildbearbeitungsrout<strong>in</strong>en.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-80
Die <strong>Java</strong> Foundation Classes<br />
Die Klassen lassen sich <strong>in</strong> vier Gruppen e<strong>in</strong>teilen:<br />
• Komponenten enthalten die Bestandteile der Fenster. Komponenten s<strong>in</strong>d<br />
beispielsweise Beschriftungen (label), Auswahlfelder und Knöpfe (buttons).<br />
• Behälter (conta<strong>in</strong>er) bestehen aus Komponenten, die auch selbst Komponenten<br />
enthalten können. Beispielsweise s<strong>in</strong>d die Objekte der Klassen JFrame und<br />
JW<strong>in</strong>dow Behälter.<br />
• Layout-Manager, Fonts und Farben bestimmen die Anordnung und das Aussehen<br />
der Komponenten <strong>in</strong> e<strong>in</strong>em Behälter.<br />
• Mit den Ereignisklassen werden mögliche Ereignisse, Beobachter und Reaktionen<br />
festgelegt.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-81
Die <strong>Java</strong> Foundation Classes<br />
• Die Sw<strong>in</strong>g-Bibliothek ersetzt und erweitert die Komponenten- und Behälterklassen<br />
des AWTs.<br />
• Die AWT-Klassen zu Schrift, Farbe und Layout-Manager sowie die Ereignisklassen<br />
werden weiterverwendet.<br />
• Die AWT-Klassen bef<strong>in</strong>den sich im Paket java.awt, die Sw<strong>in</strong>gklassen <strong>in</strong><br />
javax.sw<strong>in</strong>g.<br />
• Die Klassen der Sw<strong>in</strong>g-Bibliothek beg<strong>in</strong>nen <strong>in</strong> der Regel mit dem Buchstaben J.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-82
AWT und Sw<strong>in</strong>g im Vergleich<br />
• Im AWT wird der Peer-Ansatz verfolgt: Alle AWT-Komponenten reichen die<br />
auszuführenden Aktionen an plattformspezifische GUI-Objekte, sogenannte Peers,<br />
weiter. Komponenten, die solche Peer-Objekte benötigen, werden als<br />
schwergewichtig bezeichnet. Diese Komponenten sehen auf unterschiedlichen<br />
Betriebssystemen unterschiedlich aus. Es können nur die Funktionalitäten<br />
bereitgestellt werden, die auf dem jeweiligen Betriebssystem zur Verfügung stehen.<br />
• Fast alle Sw<strong>in</strong>g-Komponenten s<strong>in</strong>d vollständig <strong>in</strong> <strong>Java</strong> geschrieben und werden<br />
deshalb leichtgewichtig genannt. Form und Funktion s<strong>in</strong>d daher weitgehend<br />
unabhängig vom Betriebssystem. Die Oberfläche kann plattformunabhängig<br />
gestaltet werden und ist noch zur Laufzeit veränderbar (pluggable look and feel).<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-83
Wiederholung: E<strong>in</strong> e<strong>in</strong>faches AWT-Beispiel<br />
import java.awt.*;<br />
public class FrameOhneInhaltAWT {<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
Frame fenster = new Frame();<br />
fenster.setTitle("E<strong>in</strong> AWT-Fenster");<br />
fenster.setLocation(500,400);<br />
fenster.setSize(300,150);<br />
fenster.setVisible(true);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-84
import javax.sw<strong>in</strong>g.*;<br />
E<strong>in</strong> e<strong>in</strong>faches Sw<strong>in</strong>g-Beispiel<br />
public class FrameOhneInhaltSw<strong>in</strong>g {<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
JFrame fenster = new JFrame();<br />
fenster.setTitle("E<strong>in</strong> Sw<strong>in</strong>g-Fenster");<br />
fenster.setLocation(500,400);<br />
fenster.setSize(300,150);<br />
fenster.setVisible(true);<br />
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-85
AWT und Sw<strong>in</strong>g im Vergleich<br />
• Es wird aus unterschiedlichen Paketen importiert:<br />
import java.awt.* bzw. import javax.sw<strong>in</strong>g.*.<br />
• Die Behälterklassen s<strong>in</strong>d verschieden: Frame bzw. JFrame.<br />
• In der Sw<strong>in</strong>g-Variante gibt es e<strong>in</strong>e e<strong>in</strong>fache Möglichkeit zum Schließen e<strong>in</strong>es<br />
Fensters: setDefaultCloseOperation.<br />
• Beim Lauf erzeugt die Sw<strong>in</strong>gklasse e<strong>in</strong>en grauen H<strong>in</strong>tergrund.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-86
E<strong>in</strong>e abgeleitete Sw<strong>in</strong>g-Klasse<br />
import javax.sw<strong>in</strong>g.*;<br />
public class FrameOhneInhalt extends JFrame {<br />
}<br />
public FrameOhneInhalt () { }<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
FrameOhneInhalt fenster = new FrameOhneInhalt();<br />
fenster.setTitle("Frame ohne Inhalt");<br />
fenster.setSize(300,150);<br />
fenster.setVisible(true);<br />
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-87
E<strong>in</strong> Fenster mit Text<br />
public class FrameMitText extends JFrame {<br />
Conta<strong>in</strong>er c;<br />
// Conta<strong>in</strong>er dieses Frames<br />
JLabel beschriftung; // Label, das im Frame ersche<strong>in</strong>en soll<br />
public FrameMitText() {<br />
c = getContentPane();<br />
c.setLayout(new FlowLayout());<br />
beschriftung = new JLabel("Label-Text im Frame");<br />
c.add(beschriftung);<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
FrameMitText fenster = new FrameMitText();<br />
fenster.setTitle("Frame mit Text im Label");<br />
fenster.setSize(300,150); fenster.setVisible(true);<br />
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
}}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-88
E<strong>in</strong>ordnung der Sw<strong>in</strong>gklassen<br />
• Component<br />
◦ Conta<strong>in</strong>er<br />
∗ Panel<br />
- Applet<br />
· JApplet<br />
∗ W<strong>in</strong>dow<br />
- JW<strong>in</strong>dow<br />
- Frame<br />
· JFrame<br />
- Dialog<br />
· JDialog<br />
∗ JComponent<br />
◦ Button, Label, weitere AWT-Komponenten<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-89
E<strong>in</strong>ordnung der Sw<strong>in</strong>gklassen<br />
• JComponent<br />
◦ JLabel<br />
◦ AbstractButton<br />
◦ JComboBox<br />
◦ JMenuBar<br />
◦ JList<br />
◦ JScrollbar<br />
◦ JProgressbar<br />
◦ JTextComponent<br />
◦ JPanel<br />
◦ JTable<br />
◦ ...<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-90
E<strong>in</strong>ordnung der Sw<strong>in</strong>gklassen<br />
• Die Sw<strong>in</strong>g-Behälter-Klassen JFrame, JW<strong>in</strong>dow, . . . s<strong>in</strong>d Erweiterungen der<br />
entsprechenden AWT-Klassen.<br />
• Die Sw<strong>in</strong>g-Komponenten-Klassen bilden e<strong>in</strong>e eigene Hierarchie unterhalb von<br />
Conta<strong>in</strong>er.<br />
• Alle Sw<strong>in</strong>g-Klassen stehen unterhalb von Conta<strong>in</strong>er und erben somit von<br />
Component und Conta<strong>in</strong>er.<br />
Die gleichzeitige Verwendung von<br />
AWT- und Sw<strong>in</strong>g-Komponenten ist zu vermeiden.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-91
Wiederholung: Die Klasse Component<br />
Die abstrakte Klasse Component steht an oberster Stelle der JFC-Hierachie. Sie stellt<br />
Basismethoden zur Verfügung, die alle AWT- und Sw<strong>in</strong>gkomponenten geme<strong>in</strong>sam<br />
nutzen können. Die wichtigsten s<strong>in</strong>d:<br />
• Color getBackground(), Color getForeground()<br />
• void setBackground(Color c), void setForeground(Color c)<br />
• Font getFont, void setFont(Font c)<br />
• <strong>in</strong>t getHeight(), <strong>in</strong>t getWidth()<br />
• void setSize(<strong>in</strong>t width, <strong>in</strong>t height)<br />
• setLocation(<strong>in</strong>t x, <strong>in</strong>t y)<br />
• boolean isEnabled(), void setEnabled(boolean b)<br />
• boolean isVisible(), void setVisible(boolean b)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-92
Wiederholung: Die Klasse Conta<strong>in</strong>er<br />
Behälter s<strong>in</strong>d spezielle Komponenten, die andere Komponenten enthalten können. Die<br />
Klasse Conta<strong>in</strong>er stellt demzufolge Methoden zum E<strong>in</strong>fügen, Verwalten und<br />
Entfernen von Komponenten zu Verfügung. Die Komponenten werden <strong>in</strong> e<strong>in</strong>er Liste<br />
geführt, wobei die Reihenfolge sich durch die Reihenfolge der E<strong>in</strong>fügungen ergibt oder<br />
durch e<strong>in</strong>en Listen<strong>in</strong>dex bestimmt werden kann. Die Liste wird zur Anordnung der<br />
Komponenten <strong>in</strong> dem Behälterobjekt benötigt.<br />
• Component add(Component comp)<br />
• Component add(Component comp, <strong>in</strong>t <strong>in</strong>dex)<br />
• Component[] getComponents()<br />
• void remove(Component comp)<br />
• void setLayout(LayoutManager mgr)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-93
Die Klasse JComponent<br />
Die abstrakte Klasse JComponent dient als Basisklasse für sämtliche<br />
Sw<strong>in</strong>gkomponenten mit Ausnahme der Klassen Component und Conta<strong>in</strong>er. Von<br />
diesen beiden Klassen erbt JComponent und überschreibt dabei e<strong>in</strong>ige Methoden.<br />
Komponenten können durchsichtig oder opaque (undurchsichtig) se<strong>in</strong> und mit e<strong>in</strong>em<br />
erläuternden Text, dem sog. Tooltip, versehen werden. Der Text ersche<strong>in</strong>t, wenn der<br />
Mauszeiger e<strong>in</strong>ige Sekunden auf der Komponente ruht.<br />
• boolean isOpaque()<br />
• void setOpaque(boolean b)<br />
• Str<strong>in</strong>g getToolTipText()<br />
• void setToolTipText(Str<strong>in</strong>g text)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-94
Die Klasse JComponent<br />
All Implemented Interfaces:<br />
ImageObserver, MenuConta<strong>in</strong>er, Serializable<br />
Direct Known Subclasses:<br />
AbstractButton, BasicInternalFrameTitlePane, Box, Box.Filler,<br />
JColorChooser, JComboBox, JFileChooser, JInternalFrame,<br />
JInternalFrame.JDesktopIcon, JLabel, JLayeredPane, JList,<br />
JMenuBar, JOptionPane, JPanel, JPopupMenu, JProgressBar,<br />
JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider,<br />
JSp<strong>in</strong>ner, JSplitPane, JTabbedPane, JTable, JTableHeader,<br />
JTextComponent, JToolBar, JToolTip, JTree, JViewport<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-95
Komponenten: Inhalt und Anordnung<br />
E<strong>in</strong> Behälterobjekt enthält <strong>in</strong> der Regel e<strong>in</strong>e oder mehrere Komponenten. Die<br />
Komponenten können Texte, Bilder, Zeichnungen, . . . enthalten. Mithilfe e<strong>in</strong>es<br />
Layoutmanagers werden die Komponenten <strong>in</strong>nerhalb des Behälters angeordnet.<br />
• Mit der Klasse Font können Schriften ausgewählt werden.<br />
• Die Klasse Color stellt Farben zur Verfügung.<br />
• Die abstrakte Klasse Graphics bietet Möglichkeiten zur Erstellung von<br />
Zeichnungen.<br />
• Die Schnittstelle LayoutManager offeriert Methoden zur Anordnung der<br />
Komponenten. Die Schnittstelle Border und die Klasse BorderFactory bieten<br />
Möglichkeiten zur Gestaltung der Grenzen zwischen Komponenten.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-96
Die Klasse FlowLayout<br />
Bei Verwendung der Klasse FlowLayout werden die Komponenten fließend, d. h.<br />
zeilenweise von l<strong>in</strong>ks nach rechts, angeordnet. Innerhalb e<strong>in</strong>er Zeile werden die<br />
Komponenten zentriert. Zwischen den Zeilen bef<strong>in</strong>det sich e<strong>in</strong> Standardabstand von<br />
5 Pixeln, der aber geändert werden kann. Mit dem Parameter align kann bestimmt<br />
werden, ob die Komponenten l<strong>in</strong>ks- oder rechtsbündig bzw. zentriert dargestellt<br />
werden. hp und vp bestimmen die Abstände zwischen den Komponenten und Zeilen.<br />
• FlowLayout()<br />
• FlowLayout(<strong>in</strong>t align)<br />
• FlowLayout(<strong>in</strong>t align, <strong>in</strong>t hp, <strong>in</strong>t vp)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-97
Die Klasse BorderLayout<br />
Bei diesem Layout wird die Behälterfläche <strong>in</strong> die fünf Bereiche Nord, Ost, Süd, West<br />
und Zentrum aufgeteilt. In jedes dieser Gebiete kann e<strong>in</strong>e Komponente e<strong>in</strong>gefügt<br />
werden. Die Größe von Nord, Ost, Süd und West ergibt sich aus dem jeweiligen<br />
Objekt, während die Größe des Zentrums an die Gesamtgröße des Behälters angepasst<br />
wird. Beispielsweise wird durch add(...,BorderLayout.NORTH) e<strong>in</strong> Objekt im<br />
oberen Bereich h<strong>in</strong>zugefügt.<br />
• BorderLayout()<br />
• BorderLayout(<strong>in</strong>t hp, <strong>in</strong>t vp)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-98
Die Klasse GridLayout<br />
Die Behälterfläche wird gitterartig <strong>in</strong> z Zeilen und s Spalten aufgeteilt. Die Werte z<br />
und s werden bereits dem Konstruktor übergeben.<br />
• GridLayout()<br />
• GridLayout(<strong>in</strong>t z, <strong>in</strong>t s)<br />
• GridLayout(<strong>in</strong>t z, <strong>in</strong>t s, <strong>in</strong>t hp, <strong>in</strong>t vp)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-99
Die Klasse Graphics<br />
• Die abstrakte Klasse Graphics stellt zahlreiche Methoden bereit, die es<br />
ermöglichen, <strong>in</strong>nerhalb des Koord<strong>in</strong>atensystems e<strong>in</strong>er Komponente zu zeichnen.<br />
Hierzu zählen die Methoden, die wir bereits kennengelernt haben: drawL<strong>in</strong>e,<br />
drawRect, . . . . In e<strong>in</strong>em grafischen Kontext s<strong>in</strong>d die gegenwärtigen E<strong>in</strong>stellungen<br />
zu Schrift und Farbe sowie die zu bearbeitende Komponente gespeichert.<br />
• Die Klasse Graphics2D ist aus Graphics abgeleitet und erweitert diese um viele<br />
Aspekte, <strong>in</strong>sbesondere um solche zur Darstellung von zweidimensionalen<br />
Zeichnungen.<br />
• Für die Darstellung e<strong>in</strong>er e<strong>in</strong>zelnen Sw<strong>in</strong>g-Komponente ist der Repa<strong>in</strong>t-Manager<br />
zuständig. Er sorgt dafür, dass beim erstmaligen Ersche<strong>in</strong>en und bei Veränderungen<br />
die Methode public void pa<strong>in</strong>t(Graphics g) aufgerufen wird.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-100
Die Komponentenklasse JLabel<br />
Die Klasse JLabel dient zur Darstellung von Texten und Bildern.<br />
public class MyFrame extends JFrame {<br />
Conta<strong>in</strong>er c; // Conta<strong>in</strong>er dieses Frames<br />
JLabel lab; // Label, das im Frame ersche<strong>in</strong>en soll<br />
public MyFrame() {<br />
c = getContentPane();<br />
c.setLayout(new FlowLayout());<br />
Icon bild = new ImageIcon("xxx.jpg");<br />
lab = new JLabel("Text", bild, JLabel.CENTER);<br />
lab.setHorizontalTextPosition(JLabel.CENTER);<br />
lab.setVerticalTextPosition(JLabel.BOTTOM);<br />
c.add(lab);<br />
}<br />
...<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-101
Die Komponentenklasse AbstractButton<br />
Die abstrakte Klasse bietet verschiedene Arten von Schaltflächen und Knöpfen. Die<br />
wichtigsten Implementierungen s<strong>in</strong>d:<br />
• JButton<br />
• JToggleButton<br />
◦ JCheckBox<br />
◦ JRadioButton<br />
• JMenuItem<br />
◦ JMenu<br />
◦ JCheckBoxMenuItem<br />
◦ JRadioButtonMenuItem<br />
(e<strong>in</strong>fache Schaltfläche zum Auslösen von Aktionen)<br />
(Schalter mit zwei Zuständen)<br />
(Kennzeichnung durch Häkchen)<br />
(sich ausschließende Schalter)<br />
(Schaltflächen <strong>in</strong> e<strong>in</strong>em Menü)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-102
Beispiel: JRadioButton<br />
Conta<strong>in</strong>er c;<br />
JRadioButton rb[] = new JRadioButton[4];<br />
...<br />
public Konstruktor() {<br />
c = getContentPane();<br />
c.setLayout(new FlowLayout());<br />
ButtonGroup bg = new ButtonGroup();<br />
for (<strong>in</strong>t i = 0; i < 4; i++) {<br />
rb[i] = new JRadioButton("Box " + (i+1));<br />
bg.add(rb[i]);<br />
c.add(rb[i]);<br />
}<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-103
Die Komponentenklasse JComboBox<br />
• E<strong>in</strong> Objekt der Klasse JComboBox ist e<strong>in</strong>e aufklappbare Auswahlliste, die man<br />
mithilfe der Maus oder der Tastatur aufklappen und <strong>in</strong> der man e<strong>in</strong>en E<strong>in</strong>trag<br />
auswählen kann.<br />
• Angezeigt wird dabei jeweils der ausgewählte E<strong>in</strong>trag und e<strong>in</strong> Pfeil nach unten, der<br />
anzeigt, dass es sich um e<strong>in</strong>e aufklappbare Liste handelt.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-104
Beispiel: JComboBox<br />
Conta<strong>in</strong>er c;<br />
JComboBox vornamen, nachnamen;<br />
public Konstruktor() {<br />
c = getContentPane();<br />
c.setLayout(new FlowLayout());<br />
Str<strong>in</strong>g[] namen = {"Hans", "Klaus", "Sab<strong>in</strong>e", "Erika"};<br />
vornamen = new JComboBox(namen);<br />
nachnamen = new JComboBox();<br />
nachnamen.addItem("Meyer"); nachnamen.addItem("Müller");<br />
nachnamen.addItem("Schulze"); nachnamen.addItem("Lehmann");<br />
nachnamen.setSelectedIndex(2);<br />
c.add(vornamen);<br />
c.add(nachnamen);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-105
Die Komponentenklasse JList<br />
• Im Unterschied zur JComboBox-Objekt stellt e<strong>in</strong> Objekt der Klasse JList e<strong>in</strong>e<br />
Auswahlliste dar, die bereits aufgeklappt ist und daher komplett angezeigt wird.<br />
• In e<strong>in</strong>em JComboBox-Objekt kann man nicht nur e<strong>in</strong>en e<strong>in</strong>zelnen, sondern auch<br />
mehrere E<strong>in</strong>träge auswählen.<br />
• Die ausgewählten E<strong>in</strong>träge werden markiert.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-106
Die Komponentenklasse JTextComponent<br />
Die abstrakte Klasse bietet verschiedene Möglichkeiten zur E<strong>in</strong>gabe von Text. Die<br />
wichtigsten Implementierungen s<strong>in</strong>d:<br />
• JTextArea<br />
• JTextField<br />
◦ JPasswordField<br />
• JTextPane<br />
◦ JHTMLPane<br />
(E<strong>in</strong>gabe mehrzeiliger Texte)<br />
(E<strong>in</strong>gabe e<strong>in</strong>zeiliger Texte)<br />
(E<strong>in</strong>gabe e<strong>in</strong>zeiliger geschützter Texte)<br />
(E<strong>in</strong>gabe von formatierten Texten)<br />
(z. B. HTML-Texte)<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-107
Die Komponentenklasse JScrollPane<br />
• Objekte der Klasse JScrollPane s<strong>in</strong>d <strong>in</strong> der Lage, andere Komponenten<br />
aufzunehmen und <strong>in</strong> e<strong>in</strong>en Darstellungsbereich e<strong>in</strong>zubetten, der mit horizontalen<br />
und vertikalen Bildlaufleisten ausgestattet ist.<br />
• Hierdurch wird e<strong>in</strong>e ausschnittsweise Sicht auf die Komponenten ermöglicht.<br />
• Der jeweilige Ausschnitt wird mit Schiebereglern (scrollbars), die sich am Bildrand<br />
bef<strong>in</strong>den, festgelegt.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-108
Die Komponentenklasse JPanel<br />
• Objekte der Klasse JPanel können andere Komponenten enthalten. Sie s<strong>in</strong>d daher<br />
eigentlich ke<strong>in</strong>e Komponenten, sondern Behälter.<br />
• JPanel ist die Basisklasse für Conta<strong>in</strong>er, die nicht Hauptfenster s<strong>in</strong>d.<br />
Standardmäßig verwendet JPanel das FlowLayout.<br />
• Objekte der Klasse JPanel werden zum Strukturieren von Behältern<br />
verwendet – und s<strong>in</strong>d aus dieser Sicht Komponenten anderer Behälter.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-109
Die Behälterklasse JFrame<br />
• Die Klasse JFrame ist die wichtigste Top-Level-Behälterklasse.<br />
• Sie erbt von Frame, ihre Objekte s<strong>in</strong>d daher Fenster mit Rahmen.<br />
• In der Titelleiste des Rahmens bef<strong>in</strong>den sich die üblichen System-Menü-E<strong>in</strong>träge.<br />
• Zusätzlich zu den Methoden von Frame stellt JFrame weitere zur Verfügung,<br />
z. B. zum Schließen von Fenstern.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-110
Die Behälterklasse JW<strong>in</strong>dow<br />
• Wie JFrame ist auch JW<strong>in</strong>dow e<strong>in</strong>e Top-Level-Behälterklasse.<br />
• Sie erbt von W<strong>in</strong>dow, die Objekte s<strong>in</strong>d daher rahmenlose Fenster.<br />
• E<strong>in</strong> JW<strong>in</strong>dow-Objekt kann e<strong>in</strong>em JFrame-Objekt oder e<strong>in</strong>em anderem<br />
JW<strong>in</strong>dow-Objekt gehören. In diesem Fall wird das JW<strong>in</strong>dow-Objekt mit se<strong>in</strong>em<br />
Besitzer geme<strong>in</strong>sam m<strong>in</strong>imiert und maximiert.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-111
Die Behälterklasse JDialog<br />
• Die Klasse JDialog wird dazu benutzt, um Dialogfenster darzustellen.<br />
• Dies s<strong>in</strong>d Fenster, die nur solange ersche<strong>in</strong>en, bis e<strong>in</strong> Dialog mit dem Benutzer/der<br />
Benutzer<strong>in</strong> abgewickelt wurde.<br />
• E<strong>in</strong> JDialog-Fenster kann e<strong>in</strong>em übergeordneten Fenster gehören. Dieses<br />
übergeordnete kann solange für Benutzere<strong>in</strong>gaben gesperrt werden, bis der Dialog<br />
im Dialogfenster beendet ist.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-112
Die Klassen JMenuBar und JToolBar<br />
• E<strong>in</strong>em JFrame-Objekt kann e<strong>in</strong>e Menüleiste h<strong>in</strong>zugefügt werden. Dies erfolgt mit<br />
Objekten der Klasse JMenuBar.<br />
• E<strong>in</strong>e Menüleiste verwaltet e<strong>in</strong>e Liste von Menüs vom Typ JMenu.<br />
• Neben Menüleisten sieht man häufig Werkzeugleisten (toolbars). Hierbei handelt es<br />
sich um spezielle Behälter, die meistens Button-Objekte enthalten, die häufig<br />
verwendete Funktionalitäten auslösen können.<br />
• E<strong>in</strong>e Werkzeugleiste kann als Objekt der Klasse JToolBar erzeugt werden.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-113
Die Klasse JApplet<br />
• Zur Programmierung von Applets stellt die Sw<strong>in</strong>g-Bibliothek die Klasse JApplet<br />
zur Verfügung.<br />
• JApplet ist direkt aus Applet abgeleitet.<br />
• Die Klasse JApplet steht also <strong>in</strong> der Hierachie unter Component, Conta<strong>in</strong>er<br />
und Applet und erbt daher die Methoden dieser Klassen.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-114
Pr<strong>in</strong>zipielle Vorgehensweise<br />
• Durch Instanziieren e<strong>in</strong>er (eigenen) Fensterklasse wird e<strong>in</strong> Fensterobjekt erzeugt.<br />
Für das Objekt werden Größe und Titel festgelegt, es wird sichtbar gemacht, ...<br />
Die Klasse geht <strong>in</strong> der Regel aus der Ableitung e<strong>in</strong>er Behälterklasse (zum Beispiel<br />
JFrame, JW<strong>in</strong>dow, ...) hervor.<br />
• Das Layout und der grafische Kontext werden festgelegt.<br />
• Die Komponenten werden dem Fensterobjekt h<strong>in</strong>zugefügt (zum Beispiel im<br />
Konstruktor der Fensterklasse).<br />
• Für jede Ereignisquelle werden e<strong>in</strong> oder mehrere Ereignisempfänger (Beobachter)<br />
sowie die Aktionen zur Ereignisbehandlung def<strong>in</strong>iert. Die Ereignisempfänger werden<br />
bei der zuständigen Ereignisquelle registriert.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-115
Wiederholung: Adapterklassen<br />
• E<strong>in</strong>e Adapterklasse implementiert e<strong>in</strong>e Schnittstelle durch leere Rümpfe.<br />
• Zu jeder Low-Level-Listener-Schnittstelle mit mehr als e<strong>in</strong>er Methode existiert e<strong>in</strong>e<br />
Adapterklasse. Ist XxxListener der Name der Schnittstelle, so heißt die<br />
Adapterklasse XxxAdapter. Man schreibt also<br />
statt<br />
class Me<strong>in</strong>Listener extends XxxAdapter<br />
class Me<strong>in</strong>Listener implements XxxListener.<br />
• Beispielsweise enthält die Schnittstelle ActionListener nur e<strong>in</strong>e Methode,<br />
W<strong>in</strong>dowListener jedoch – wie bereits gesehen – mehrere.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-116
Strukturierung von Behälter- und Beobachterklasse<br />
• Die Beobachterklasse wird als <strong>in</strong>nere Klasse realisiert.<br />
• Die Beobachterklasse wird als anonyme Klasse realisiert.<br />
• Die Fensterklasse wird selbst zur Beobachterklasse.<br />
• Die Beobachterklasse ist e<strong>in</strong>e selbstständige Klasse. Ihr muss der Behälter als<br />
Parameter übergeben werden.<br />
Wir erläutern die Möglichkeiten an e<strong>in</strong>em Beispiel zur Wechsel der H<strong>in</strong>tergrundfarbe.<br />
Die folgenden Programme wurden D. Ratz, J. Scheffler, D. Seese, J. Wiesenberger:<br />
Grundkurs Programmieren <strong>in</strong> <strong>Java</strong> entnommen.<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-117
Realisierung als <strong>in</strong>nere Klasse<br />
public class Farbwechsel1 extends JFrame {<br />
Conta<strong>in</strong>er c;<br />
JButton button;<br />
public Farbwechsel1() {<br />
c = getContentPane();<br />
button = new JButton("H<strong>in</strong>tergrundfarbe wechseln");<br />
c.add(button, BorderLayout.NORTH);<br />
ButtonListener bL = new ButtonListener();<br />
button.addActionListener(bL);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-118
}<br />
class ButtonListener implements ActionListener {<br />
public void actionPerformed(ActionEvent e) {<br />
float zufall = (float) Math.random();<br />
Color grauton = new Color(zufall,zufall,zufall);<br />
c.setBackground(grauton);<br />
}<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
Farbwechsel1 fenster = new Farbwechsel1();<br />
fenster.setTitle("Farbwechsel");<br />
fenster.setSize(200,100);<br />
fenster.setVisible(true);<br />
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-119
Realisierung als anonyme Klasse<br />
public class Farbwechsel2 extends JFrame {<br />
Conta<strong>in</strong>er c;<br />
JButton button;<br />
public Farbwechsel2() {<br />
c = getContentPane();<br />
button = new JButton("H<strong>in</strong>tergrundfarbe wechseln");<br />
c.add(button, BorderLayout.NORTH);<br />
ActionListener bL = new ActionListener() {<br />
public void actionPerformed(ActionEvent e) { ... }<br />
};<br />
button.addActionListener(bL);<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) { ... }<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-120
Fensterklasse als Beobachterklasse<br />
public class Farbwechsel3 extends JFrame implements ActionListener {<br />
Conta<strong>in</strong>er c;<br />
JButton button;<br />
public Farbwechsel3() {<br />
c = getContentPane();<br />
button = new JButton("H<strong>in</strong>tergrundfarbe wechseln");<br />
c.add(button, BorderLayout.NORTH);<br />
button.addActionListener(this);<br />
}<br />
public void actionPerformed(ActionEvent e) { ... }<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) { ... }<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-121
Beobachterklasse als selbstständige Klasse<br />
public class Farbwechsel4 extends JFrame {<br />
Conta<strong>in</strong>er c;<br />
JButton button;<br />
public Farbwechsel4() {<br />
c = getContentPane();<br />
button = new JButton("H<strong>in</strong>tergrundfarbe wechseln");<br />
c.add(button, BorderLayout.NORTH);<br />
ButtonListener bL = new ButtonListener(c);<br />
button.addActionListener(bL);<br />
}<br />
}<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) { ... }<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-122
Beispiel: Fenster mit Menü- und Werkzeugleiste<br />
import java.awt.*;<br />
import java.awt.event.*;<br />
import javax.sw<strong>in</strong>g.*;<br />
public class Bilderrahmen extends JFrame {<br />
Conta<strong>in</strong>er c;<br />
JMenuBar menuBar;<br />
JMenu menu;<br />
JMenuItem menuItem;<br />
JToolBar toolBar;<br />
JButton button;<br />
JLabel bildLabel;<br />
// Conta<strong>in</strong>er dieses Frames<br />
// Menueleiste<br />
// Menue<br />
// Menue-E<strong>in</strong>trag<br />
// Werkzeugleiste<br />
// Knoepfe der Werkzeugleiste<br />
// Label das im Frame ersche<strong>in</strong>en soll<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-124
public Bilderrahmen() {<br />
c = getContentPane();<br />
MenuListener mL = new MenuListener();<br />
menuBar = new JMenuBar();<br />
menu = new JMenu("Bilder");<br />
menu.setMnemonic(KeyEvent.VK_B);<br />
menuItem = new JMenuItem("Hund");<br />
menuItem.setMnemonic(KeyEvent.VK_H);<br />
menuItem.addActionListener(mL);<br />
menuItem.setActionCommand("dog");<br />
menu.add(menuItem);<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-125
menuItem = new JMenuItem("Katze");<br />
menuItem.setMnemonic(KeyEvent.VK_K);<br />
menuItem.addActionListener(mL);<br />
menuItem.setActionCommand("cat");<br />
menu.add(menuItem);<br />
menuItem = new JMenuItem("Maus");<br />
menuItem.setMnemonic(KeyEvent.VK_M);<br />
menuItem.addActionListener(mL);<br />
menuItem.setActionCommand("mouse");<br />
menu.add(menuItem);<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-126
menuBar.add(menu);<br />
setJMenuBar(menuBar);<br />
ToolBarListener tL = new ToolBarListener();<br />
toolBar = new JToolBar("Rahmenfarbe");<br />
button = new JButton(new ImageIcon("images/rot.gif"));<br />
button.setToolTipText("roter Rahmen");<br />
button.addActionListener(tL);<br />
button.setActionCommand("rot");<br />
toolBar.add(button);<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-127
utton = new JButton(new ImageIcon("images/gruen.gif"));<br />
button.setToolTipText("gruener Rahmen");<br />
button.addActionListener(tL);<br />
button.setActionCommand("gruen");<br />
toolBar.add(button);<br />
button = new JButton(new ImageIcon("images/blau.gif"));<br />
button.setToolTipText("blauer Rahmen");<br />
button.addActionListener(tL);<br />
button.setActionCommand("blau");<br />
toolBar.add(button);<br />
bildLabel = new JLabel(new ImageIcon("images/dog.gif"));<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-128
}<br />
c.setBackground(Color.red);<br />
c.add(bildLabel, BorderLayout.CENTER);<br />
c.add(toolBar, BorderLayout.NORTH);<br />
class MenuListener implements ActionListener {<br />
public void actionPerformed(ActionEvent e) {<br />
bildLabel.setIcon(new ImageIcon("images/"+e.getActionCommand()+".gif"));<br />
}<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-129
class ToolBarListener implements ActionListener {<br />
public void actionPerformed(ActionEvent e) {<br />
if (e.getActionCommand() == "rot")<br />
c.setBackground(Color.red);<br />
else if (e.getActionCommand() == "gruen")<br />
c.setBackground(Color.green);<br />
else if (e.getActionCommand() == "blau")<br />
c.setBackground(Color.blue);<br />
}<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-130
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
Bilderrahmen fenster = new Bilderrahmen();<br />
fenster.setTitle("Bilderrahmen");<br />
fenster.setSize(180,280);<br />
fenster.setVisible(true);<br />
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
}<br />
}<br />
11.6 Die Sw<strong>in</strong>g-Klassen 11-131