Jetzt können wir endlich zum zeichnen anfangen.
Wir erstellen eine neue Klasse mit Namen „Tafel“ mit folgendem Inhalt:
package start; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Tafel extends JFrame { public static void main(String[] args) { Tafel zeichnen = new Tafel(); zeichnen.setDefaultCloseOperation( EXIT_ON_CLOSE ); zeichnen.setBounds( 0, 0, 500, 500 ); zeichnen.setLocationRelativeTo( null ); zeichnen.setAlwaysOnTop( true ); zeichnen.setTitle("Zeichnen in Java"); // wird definiert aber ohne super() in der paint() nicht gezeichnet zeichnen.getContentPane().setBackground(Color.BLUE); zeichnen.setVisible( true ); } public void paint(Graphics g) { super.paint(g) // ohne diesen Aufruf wird nur der Kreis gezeichnet, der Hintergrund nicht. g.setColor(Color.YELLOW); g.fillOval(50, 50, 100, 100); // fillOval(x, y, Breite, Höhe) } }
Wie wir schon gelernt haben wird unsere Klasse Tafel hier um die Klasse JFrame erweitert. JFrame ist ein Fenster, deswegen wird, sobald wir ein Objekt aus unserer Klasse bilden ein Fenster geöffnet.
Um auf unserer Tafel malen zu können müssen wir ihr eine paint-Methode geben (Zeile 26).
Der paint-Methode wird vom System eine Graphics-Klasse übergeben das Metadaten über den Bereich in dem gezeichnet werden soll enthält. Z.B. die Vordergrundfarbe sowie den Bildschirmausschnitt auf dem gezeichnet wird. Ausserdem enthält es verschiedene Methoden zum malen. Diese Methoden nutzen wir im Beispiel um zuerst die Vordergrundfarbe einzustellen und dann um einen Kreis zu zeichnen (Zeilen 28 und 29).
Die Hintergrundfarbe haben wir zwar in Zeile definiert, wird aber nicht angezeigt. Der Bildschirm bleibt weiss. Das hat mit einer Eigenheit von Java zu tun. Man kann nicht direkt auf einen JFrame schreiben, da Java automatisch eine sogenannte ContentPane erstellt. Das ist ein unsichtbarer Container der die einzelnen Grafiken ordnet. Um also den Hintergrund zu ändern muss man, wie in Zeile 20 zu sehen erst die ContentPane holen und dann dort den Hintergrund einstellen. Unsere Methode paint() bezieht sich jedoch auf unsere Klasse Tafel auch wenn diese einen JFrame enthält. Deswegen werden nur die Grafiken die wir in unserer paint-Methode definieren, gezeichnet. Um auch den Hintergrund zu zeichnen, müssen wir die paint-Methode der Elternklasse aufrufen. Also die von JFrame. Dies können wir gleich am Anfang unserer paint-Methode mit super.paint(g)
machen. Theoretisch könnte man auch stattdessen this.paintComponents(g)
aufrufen um explizit alle Komponenten auf der Tafel zu zeichnen, aber super.paint(g)
ist nicht nur der elegantere Weg, es ist auch der, den Oracle also der Hersteller von Java hier empfiehlt.
Da diese Problematik nicht nur background sondern auch andere, die ContentPane betreffende Einstellungen betrifft, wollen wir unseren Code generell anders aufbauen:
package start; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Tafel extends JFrame { public static void main(String[] args) { Tafel zeichnen = new Tafel(); zeichnen.setDefaultCloseOperation( EXIT_ON_CLOSE ); zeichnen.setBounds( 0, 0, 900, 500 ); zeichnen.setLocationRelativeTo( null ); zeichnen.setAlwaysOnTop( true ); zeichnen.setTitle("Zeichnen in Java"); zeichnen.setVisible( true ); JPanel panel = new JPanel() { public void paint( Graphics g ) { g.fillOval(100, 100, 10, 10); } }; panel.setBackground( new Color( 255, 255, 255 ) ); zeichnen.add(panel); } }
Hier bilden wir erst ein JPanel aus und überschreiben direkt die Methode paint() des JPanels. Ein JPanel ist ein einfacher leerer Container der Komponenten, z.B. Buttons oder Grafiken aufnehmen kann.
Danach setzen wir das panel auf unser Tafelobjekt das wir zeichnen genannt haben.
Nun können wir beliebige Objekte die uns unsere Graphics-Klasse bietet, in der paint-Methode des Panels. positionieren. Schreiben wir ‚g‘ und setzen einen ‚.‘ Punkt, dann sollte sich in Eclipse das Menü öffenen. Geben wir ‚Draw‘ ein, zeigt uns er alle Methoden die uns grafische Objekte malen lassen. Wenn wir solch eine Methode einmal anklicken, sagt uns Eclipse welche Werte diese Methode erwartet und was es zurückgibt. Mit Rückgabewerten und einigen dieser Methoden wollen wir uns nun näher beschäftigen.
Zusammenfassung
- Ein JFrame ist ein Fenster
- Jedes Objekt hat eine paint-Methode für die eigene Darstellung.
- Die paint-Methode kann überschrieben werden.
- super.paint(g) ruft die paint-Methode der übergeordneten Klasse, der Elternklasse, auf.
- Man sollte Grafikobjekte nicht direkt auf den JFrame, sondern immer in einen Container wie JPanel setzen.