Informatik 2 – Teil 6 - Grafikmethoden Übersicht 6.1 Die Klasse Graphics 6.2 Das Koordinatensystem der Graphics-Methoden 6.3 Beispiel: ein „Zeichenbrett“ für Graphics-Methoden 6.4 Beispiel – Programmcode, Teil 1 6.5 Beispiel – Programmcode, Teil 2 6.6 Beispiel - Ausgabe 6.7 Methoden der Klasse Graphics - Übersicht 6.8 Beispiel für weitere Graphics-Methoden 6.9 Beispiel: grafische Darstellung einer Sinuskurve 6.10 Sinuskurve darstellen – Programmtext, Teil 1 6.11 Sinuskurve darstellen – Programmtext, Teil 2 6.12 Sinuskurve darstellen - Ergebnis Prof. Martin Trauth Folie 1 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.1 Die Klasse Graphics Bisher wurde mit Grafikelementen gearbeitet. Sie erscheinen auf dem Bildschirm als weitgehend „vorgefertigte“ Komponenten, deren genaues Aussehen (Größe, Farbe usw.) man noch beeinflussen kann. Manchmal möchte man aber Vorgänge ausführen, die eher denen des Zeichnens entsprechen: Linien ziehen, Kreise, Ellipsen oder Rechtecke darstellen. Dazu wird die Klasse Graphics benötigt. Man kann damit (u.a.): Linien ziehen Kreise, Ellipsen und Rechtecke zeichnen (auch ausgefüllte Figuren) Text an beliebiger Stelle platzieren Objekte der Klasse Graphics funktionieren ähnlich wie ein Zeichenstift dessen Farbe man einstellen kann. Sie werden aber nicht mit dem new-Operator erzeugt, sondern mit der Methode getGraphics( ). Diese Methode stellen u.a. Grafikelemente der JFrame-Klasse oder der JPanel-Klasse zur Verfügung. Beispiel: Graphics stift = drawPanel.getGraphics(); drawPanel ist in diesem Beispiel ein Objekt der Klasse JPanel. Die Methode getGraphics hat ein Objekt der Klasse Graphics als Rückgabewert. Es ist aber ein spezielles Graphics-Objekt: es „zeichnet“ hier mit seinen Methoden immer auf drawPanel. Allgemein: das Graphics-Objekt zeichnet immer auf das Objekt, durch dessen getGraphicsMethode es erzeugt wurde. Prof. Martin Trauth Folie 2 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.2 Das Koordinatensystem der Graphics-Methoden Viele Methoden der Klasse Graphics arbeiten mit Koordinaten. Sie haben die Einheit Pixel (Bildschirmpunkte). Das Koordinatensystem hat seinen Ursprung an der oberen, linken Ecke des Grafikbereichs (z.B. eines JPanel-Objekts). x-Koordinaten zählen von links nach rechts, y-Koordinaten von oben nach unten (Letzteres ist anders als man es normalerweise gewohnt ist). Sie sind immer positiv. x Grafikbereich y Prof. Martin Trauth Folie 3 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.3 Beispiel: ein „Zeichenbrett“ für Graphics-Methoden Der folgende Programmcode ähnelt in der Grundstruktur sehr stark an die Beispiele aus Teil 5. Auch hier wird wieder eine Klasse (wir nennen sie GraphicTest) von der Klasse JFrame abgeleitet, um deren Methoden und Eigenschaften zu erben. Es gibt auch wieder einen Button mit ActionListener und einige Unter-Panels zur besseren Einteilung der Fläche bzw. zum passenden Platzieren des Buttons (er soll nicht im Zeichenbereich liegen). Neu: ein Graphics-Objekt stift. Das Fenster sieht so aus: Der Button-Klick bewirkt dann, dass etwas gezeichnet wird. Die Zeichenfläche ist weiß dargestellt. Prof. Martin Trauth Folie 4/ 13 Informatik 2 – Teil 6 - Grafikmethoden 6.4 Beispiel – Programmcode Teil 1 (Deklarationen und Konstruktor) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GraphicTest extends JFrame implements ActionListener { private JPanel myPanel, buttonPanel, drawPanel; private JButton myButton; private Graphics stift; public GraphicTest(String str){ super(str); myPanel = new JPanel(); myPanel.setLayout(new FlowLayout()); myButton = new JButton("malen"); myButton.addActionListener(this); setContentPane(myPanel); this.setSize(500, 350); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); drawPanel = new JPanel(); buttonPanel = new JPanel(); drawPanel.setPreferredSize(new Dimension(500, 250)); drawPanel.setBackground(Color.WHITE); buttonPanel.setPreferredSize(new Dimension(500, 50)); myPanel.add(drawPanel); myPanel.add(buttonPanel); buttonPanel.add(myButton); this.setVisible(true); } Prof. Martin Trauth drawPanel ist das „Zeichenbrett“. Für‘s „Design“ Folie 5 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.5 Beispiel – Programmcode Teil 2 (Methoden actionPerformed() und main() ) In der main-Methode wird das GraphicTest-Objekt erzeugt. Dann wird mit der getGraphics()-Methode ein Graphics-Objekt erzeugt. In unserem Beispiel wird es stift genannt, weil es ähnlich wie ein Zeichenstift funktioniert. Falls man nicht erst auf das Anklicken des Buttons warten möchte um etwas zu zeichnen, kann man die hier auskommentierte Zeile myGraf.myButton.doClick() verwenden. Die doClick()-Methode des Buttons bewirkt, dass sich das Programm so verhält als sei er angeklickt worden (es wird also ein Event ausgelöst). Hinweis: weil myButton eine Eigenschaft der Klasse GraphicTest und damit des Objekts myGraf ist, erfordert der Zugriff auf die Methode zwei Punktoperatoren. Gleiches gilt hier für die Methode getGraphics(). public void actionPerformed(ActionEvent e){ stift.setColor(Color.BLUE); stift.drawOval(100, 50, 100, 50); stift.setColor(Color.GREEN); stift.drawLine(0, 0, 150, 80); } public static void main(String[] args) { GraphicTest myGraf = new GraphicTest("GraphicTest"); myGraf.stift = myGraf.drawPanel.getGraphics(); //myGraf.myButton.doClick(); } } // Ende Klasse Das eigentliche Zeichnen wird in der actionPerformed()-Methode gemacht. Die Graphics-Methode setColor()setzt die Zeichenfarbe (vgl. Teil 5.6). Mit den Methoden drawOval()und drawLine()(siehe Abschnitt 7) werden die entsprechenden Figuren gezeichnet. Prof. Martin Trauth Folie 6 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.6 Beispiel - Ausgabe Nach dem Button-Klick hat man dieses Fensterbild: Prof. Martin Trauth Folie 7/ 13 Informatik 2 – Teil 6 - Grafikmethoden 6.7 Methoden der Klasse Graphics (Übersicht) Hier sind einige Methoden der Graphics-Klasse dargestellt. In der Parameterliste sind die Parametertypen angegeben und dahinter, kursiv, eine Parameterbeschreibung. Weitere Beispiele siehe 6.8 . Linie zeichnen: drawLine(int x1-Position, int y1-Position, int x2-Position, int y2-Position) Ellipse (oder Kreis) zeichnen : drawOval(int x-Position, int y-Position, int Breite, int Höhe) Rechteck zeichnen : drawRect(int x-Position, int y-Position, int Breite, int Höhe) Schriftzug zeichnen : drawString(String Zeichenkette, int x-Position, int y-Position) Schrifttyp setzen (für drawString() ) : setFont(Font Schrifttyp) Font: Wie in 5.26 beschrieben. Alle Einheiten sind in Pixel. Positionsangaben beziehen sich bei Rechtecken auf die linke obere Ecke, bei Ellipsen auf die linke, obere Ecke des umhüllenden Rechtecks, bei Text auf die linke, untere Kante des Schriftzugs und bei Linien auf die Anfangs- (x1, y1) und Endkoordinaten (x2, y2). Ellipsen und Rechtecke kann man auch ausgefüllt zeichnen lassen. Dazu werden die Methoden fillOval() und fillRect() eingesetzt. fillOval(int x-Position, int y-Position, int Breite, int Höhe) fillRect(int x-Position, int y-Position, int Breite, int Höhe) Prof. Martin Trauth Folie 8 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.8 Beispiel für weitere Grafikmethoden Dieses Beispiel zeigt den Einsatz von „gezeichneter“ Schrift und ausgefüllten Figuren. Es wird nur die actionPerformed()-Methode beschrieben. Der Rest ist identisch mit dem vorangegangenen Beispiel. public void actionPerformed(ActionEvent e){ stift.setColor(Color.BLUE); stift.fillRect(100, 50, 100, 50); stift.setColor(Color.RED); stift.setFont(new Font("Arial", Font.BOLD, 48)); stift.drawString("der dicke Text", 150, 150); } Erscheinungsbild: Prof. Martin Trauth Folie 9 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.9 Beispiel: grafische Darstellung einer Sinuskurve Ein Anwendung von Grafikmethoden ist die Darstellung von mathematischen Funktionen. Ebenso können zeitliche Abfolgen von Messwerten dargestellt werden. Im Beispiel verwenden wir eine Sinusfunktion (y-Achse), deren Verlauf in Abhängigkeit vom Winkel (x-Achse) im Bereich 0 bis 4 Pi dargestellt werden soll: y = sin(x) . Es kann wieder das Grundgerüst des vorangegangenen Beispiels verwendet werden. Verändert wird die Methode actionPerformed(): sie ruft nun nacheinander die Methoden koordinatenZeichnen() und kurveZeichnen() auf. Diese beiden Methoden müssen neu geschrieben werden. Sie tun das, was ihre Namen andeuten: ein (einfaches) Koordinatensystem mit beschrifteten Achsen zeichnen und dann die Sinuskurve zeichnen. Die Kurve wird aus kleinen Linienstückchen zusammen gesetzt. Jedes dieser Stücke beginnt bei einem Winkel und dem dazugehörigen Sinuswert und endet beim nächsten berechneten Winkel und seinem Sinus. Es wird eine forSchleife über 100 Winkel zwischen 0 und 4 Pi eingesetzt. Prof. Martin Trauth Folie 10 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.10 Sinuskurve darstellen – Programmtext 1 Es werden nur die geänderten oder neu geschriebenen Methoden gezeigt: public void actionPerformed(ActionEvent e) { this.koordinatenZeichnen(stift); stift.setColor(Color.RED); this.kurveZeichnen(stift); } public void koordinatenZeichnen(Graphics stift1){ stift1.drawLine(10, 125, 470, 125); // x-Achse - 450 Pixel stift1.drawLine(20, 225, 20, 25); //y-Achse - 200 Pixel stift1.drawString("1", 10, 25); //y-Achsenbeschriftung oben stift1.drawString("-1", 10, 225); //y-Achsenbeschriftung unten stift1.drawString("4Pi", 470 , 140); //x-Achsenbeschriftung rechts } Bemerkenswert ist die Übergabe des Objekts stift als Parameter an die Methode koordinatenZeichnen(). Auf diese Weise braucht dort kein neues Graphics-Objekt erzeugt werden und man kann in der aufrufenden Methode (actionPerformed() ) Stifteigenschaften wie z.B. die Farbe festlegen. Die x-Achse beginnt bei 10 Pixeln und endet bei 470 Pixeln. Die x-Koordinate der y-Achse liegt bei 20 Pixeln. Dadurch kreuzt sie die x-Achse an deren linken Ende. Die x-Werte werden zwischen dem 0-Punkt (bei 20 Pixeln) und dem Ende der x-Achse (470 Pixel) aufgetragen. Es stehen also 450 Pixel für den Bereich von 0 bis 4 Pi zur Verfügung. In der Methode kurveZeichnen() (siehe 6.11) müssen die Werte entsprechend auf Pixel umgerechnet werden. Für die yAchse gilt ähnliches, wobei hier die Werteskala von -1 bis +1 reicht und die y-Achse mittig bei 125 Pixel von der xAchse gekreuzt wird. Prof. Martin Trauth Folie 11 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.11 Sinuskurve darstellen – Programmtext 2 Die Methode kurveZeichnen() : public void kurveZeichnen(Graphics stift1){ double yRatio = 100.; double xRatio = 450. / (4. * Math.PI); double letzterWinkel = 0.; double letzterSinus = Math.sin(letzterWinkel); for (int i = 1; i <= 100; i++) { double winkel = (i/100.) * Math.PI * 4.; double sinus = Math.sin(winkel); int x1 = (int) (xRatio * letzterWinkel) + 20; int y1 = (int) (yRatio * letzterSinus) + 125; int x2 = (int) (xRatio * winkel) + 20; int y2 = (int) (yRatio * sinus) + 125; stift1.drawLine(x1, y1, x2, y2); letzterWinkel = winkel; letzterSinus = sinus; } } Die Linienteilstücke der Sinuskurve beginnen beim Wertepaar letzterWinkel/letzterSinus (die vor der Schleife auf Anfangswerte gesetzt werden) und enden bei winkel/sinus, wobei diese Werte noch auf die Pixelwerte der x- und yAchse umgerechnet werden. Es entstehen dann Wertepaare x1/y1 und x2/y2 . Bitte beachten: beim Berechnen dieser Wertepaare wird ein cast auf Integer angewendet. Dieser ist notwendig, denn sonst würde der Ausdruck rechts vom Gleichheitszeichen den Typ double haben und könnte keiner Integervariablen zugewiesen werden. In C geht das, es erfolgt dann eine automatische Typwandlung. In Java geht das nicht. Prof. Martin Trauth Folie 12 / 13 Informatik 2 – Teil 6 - Grafikmethoden 6.12 Sinuskurve darstellen – Ergebnis Das Ergebnis sieht so aus: Kreuzung x-y-Achse: 20 Pixel in x-Richtung 125 Pixel in y-Richtung y-Bereich: Von 25 – 225 Pixel = 200 Pixel Bereich Bereichmitte bei 125 Pixel x-Bereich: Von 20 – 470 Pixel = 450 Pixel Bereich Rahmen und Button wurden sinngemäß beschriftet. Der geänderte Programmtext dafür ist nicht extra aufgeführt. Prof. Martin Trauth Folie 13 / 13