Hallo ich bin neu hier im Forum und ein Java-Anfänger.
Hab die Grundlagen in der Vorlesung der Universität gehört.
Das wichtigste ist für mich, die Vererbungen zu verstehen und wie ich sowas eigenständig aus der API lesen kann.
Ich beziehe mich auf das Tutorial von Wildcard, ich poste es nochmal um meine Fragen dazwischen zu schreiben:
Dieses Tutorial wird sich mit dem generellen Vorgehen beim Zeichnen in Swing beschäftigen.
Zum Verständnis ist lediglich Java Grundwissen und erste Erfahrungen mit den Swing Komponenten (JFrame, JPanel,...) nötig.
Ziel des Tutorials ist die grundlegenden Mechanismen zu erläutern.
Erklärt werden diese an der beispielhaften Implementierung einer kleinen Applikation die geometrische Figuren in verschiedenen Farben zeichnet.
Während der Implementierung werden bewusst einige Fehler gemacht um auf die Fallen des Swing Toolkit hinzuweisen, es ist also sehr zu empfehlen das Tutorial zu ende zu lesen
Zuerst brauchen wir eine Klasse die von JComponent erbt auf der wir später zeichnen.
JComponent ist die Basisklasse aller Swing-Komponenten und hat nicht wesentlich mehr Funktionalität als dem Programmier eine Zeichenfläche zur Verfügung zu stellen.
Da dies unser erster Versuch ist, und wir naiv an die Sache herangehen nennen wir sie
NaivePaintingComponent
Wir möchten Geometrische Figuren (in Java Shapes) in verschiedenen Farben zeichnen, daher wird ein Member vom Typ Color und ein Member vom Typ Shape benötigt.
Um diese Member von aussen später elegant setzen zu können fügen wir setter ein.
Weiterhin sollte es eine Möglichkeit geben unserer Komponente zu sagen das sie jetzt zeichnen soll.
Nennen wir die Methode drawNow().
Sehen wir uns mal das Ergebnis an:
Was noch fehlt ist das wichtigste: drawNow()
In Swing (sowie auch in AWT) wird immer mit einem Graphics Objekt gezeichnet.
Dieses Graphics Objekt hält grob gesagt eine vom Betriebssystem erhaltene Grafikresource mit der gezeichnet werden kann. Man kann sich ein Graphics Objekt also wie einen Pinsel vorstellen.
Was Swing von AWT unterscheidet ist, das man bei Swing von einem Lightweight Toolkit spricht.
In AWT bekommt jede Komponente (Label, Panel, TextField) eine solche Betriebssystem Grafikresource mit der sie sich selbst zeichnen, dieses System nennt sich Heavyweight.
Swing geht einen flexibleren Weg und hat nur wenige Heavyweight-Komponenten (JFrame, JDialog, JWindow). Man spricht dabei von Heavyweight Containern.
Diese Heavyweight Containern geben dann ihre eigene Grafikresource (gekapselt in Graphics Objekten) an ihre Kinder weiter.
Somit ist nun klar das wir ein Graphics Objekt zum Zeichnen benötigen.
Der aufmerksame API Leser wird über eine getGraphics() Methode in jeder von JComponent abgeleiteten Klasse stolpern die uns ein Graphics Objekt liefert.
Zu beachten ist allerdings das diese Methode durch die Lightweight Architektur nur dann ein Objekt zurückliefern kann wenn die Komponente bereits in einem Heavyweight Container liegt der eine solche Resource erhalten hat.
Der Trick ist, das getGraphics in Swing Anwendungen eigentlich ein Graphics2D Objekt liefert (das deutlich mehr Möglichkeiten als ein einfaches Graphics Objekt bietet) welches Graphics erweitert.
In Graphics2D ist nun eine Methode draw zu finden der man ein Shape übergeben kann.
Der resultierende Code könnte nun so aussehen:
Java Code: Quelltext in neuem Fenster öffnen
Mit freundlichen Grüßen,
Behnke
Hab die Grundlagen in der Vorlesung der Universität gehört.
Das wichtigste ist für mich, die Vererbungen zu verstehen und wie ich sowas eigenständig aus der API lesen kann.
Ich beziehe mich auf das Tutorial von Wildcard, ich poste es nochmal um meine Fragen dazwischen zu schreiben:
Dieses Tutorial wird sich mit dem generellen Vorgehen beim Zeichnen in Swing beschäftigen.
Zum Verständnis ist lediglich Java Grundwissen und erste Erfahrungen mit den Swing Komponenten (JFrame, JPanel,...) nötig.
Ziel des Tutorials ist die grundlegenden Mechanismen zu erläutern.
Erklärt werden diese an der beispielhaften Implementierung einer kleinen Applikation die geometrische Figuren in verschiedenen Farben zeichnet.
Während der Implementierung werden bewusst einige Fehler gemacht um auf die Fallen des Swing Toolkit hinzuweisen, es ist also sehr zu empfehlen das Tutorial zu ende zu lesen
Zuerst brauchen wir eine Klasse die von JComponent erbt auf der wir später zeichnen.
JComponent ist die Basisklasse aller Swing-Komponenten und hat nicht wesentlich mehr Funktionalität als dem Programmier eine Zeichenfläche zur Verfügung zu stellen.
Da dies unser erster Versuch ist, und wir naiv an die Sache herangehen nennen wir sie
NaivePaintingComponent
Wir möchten Geometrische Figuren (in Java Shapes) in verschiedenen Farben zeichnen, daher wird ein Member vom Typ Color und ein Member vom Typ Shape benötigt.
Um diese Member von aussen später elegant setzen zu können fügen wir setter ein.
Weiterhin sollte es eine Möglichkeit geben unserer Komponente zu sagen das sie jetzt zeichnen soll.
Nennen wir die Methode drawNow().
Sehen wir uns mal das Ergebnis an:
Java:
class NaivePaintingComponent extends JComponent
{
private Shape shape;
private Color c;
public void drawNow() {
}
public void setColor(Color c) {
this.c = c;
}
public void setShape(Shape shape) {
this.shape = shape;
}
}
Was noch fehlt ist das wichtigste: drawNow()
In Swing (sowie auch in AWT) wird immer mit einem Graphics Objekt gezeichnet.
Dieses Graphics Objekt hält grob gesagt eine vom Betriebssystem erhaltene Grafikresource mit der gezeichnet werden kann. Man kann sich ein Graphics Objekt also wie einen Pinsel vorstellen.
Was Swing von AWT unterscheidet ist, das man bei Swing von einem Lightweight Toolkit spricht.
In AWT bekommt jede Komponente (Label, Panel, TextField) eine solche Betriebssystem Grafikresource mit der sie sich selbst zeichnen, dieses System nennt sich Heavyweight.
Swing geht einen flexibleren Weg und hat nur wenige Heavyweight-Komponenten (JFrame, JDialog, JWindow). Man spricht dabei von Heavyweight Containern.
Diese Heavyweight Containern geben dann ihre eigene Grafikresource (gekapselt in Graphics Objekten) an ihre Kinder weiter.
Das führt dazu das eine Anwendung die einen nur JFrame benutzt auch nur eine Grafikresource vom Betriebssystem braucht, der Rest wird intern erledigt.Kann man diese Vererbung in der API irgendwie nachvollziehen?
Somit ist nun klar das wir ein Graphics Objekt zum Zeichnen benötigen.
Der aufmerksame API Leser wird über eine getGraphics() Methode in jeder von JComponent abgeleiteten Klasse stolpern die uns ein Graphics Objekt liefert.
Zu beachten ist allerdings das diese Methode durch die Lightweight Architektur nur dann ein Objekt zurückliefern kann wenn die Komponente bereits in einem Heavyweight Container liegt der eine solche Resource erhalten hat.
Wenn wir uns die Klasse Graphics ansehen entdecken wir einige hilfreiche Methoden drawRect, drawOval, ... entdecken.Ok verstanden. Woran kann man erkennen ob es sich bei Klassen in der API um heavyweight oder lightweight handelt?
Um also in einem JPanel(lightweight) zu zeichnen, muss ich das Graphic-objekt aus z.b.: JFrame oder JComponent übergeben, korrekt?
Für dieses Beispiel wurde allerdings mit den Shapes ein stärker Objekt orientierter Ansatz gewählt, daher nützen uns diese Methoden nicht viel.Das versteh ich garnicht. Wenn ich mir die Graphics-Klasse in der Api anschaue, sehe ich doch das diese abstrakt ist. In der Vorlesung hab ich gelernt das abstrakte Klassen mit abstrakten Methoden noch nicht konkret definiert sind. Die müssen doch noch von einer Subklasse konkretisiert werden, oder? Ich könnte die Funktionen ja nicht nutzen
Der Trick ist, das getGraphics in Swing Anwendungen eigentlich ein Graphics2D Objekt liefert (das deutlich mehr Möglichkeiten als ein einfaches Graphics Objekt bietet) welches Graphics erweitert.
In Graphics2D ist nun eine Methode draw zu finden der man ein Shape übergeben kann.
Der resultierende Code könnte nun so aussehen:
Java Code: Quelltext in neuem Fenster öffnen
Java:
//das Graphics Objekt in ein Graphics2D Objekt casten
Graphics2D g2d = (Graphics2D) getGraphics();
//die gewünschte Farbe setzen
g2d.setColor(c);
//die gewählte Figur zeichnen
g2d.draw(shape);
Graphics2D g2d = (Graphics2D) getGraphics(); das ist mir logisch, da ja jede Subklasse ein Objekt der Basisklasse sein kann, richtig? Nur ich versteh nicht warum man jetzt auf die Funktionen setColor und draw zugreifen kann, die sind doch abstrakt?
Und darf eine abstrakte Klasse eigentlich nicht auch keine Instanz erstellen, also können wir doch eigentlich auch kein Objekt übergeben?
Vielleicht sollte ich das Tutorial direkt weiterlesen und das klärt sich, was meint ihr? Mag mir einer helfen? Übrigens find ich das Tutorial von Wildcard spitze :applaus:
Ich versuch nur irgendwie das große ganze in der grooooßen API zu sehen
Mit freundlichen Grüßen,
Behnke