Zeichnen in Swing - Jede Menge Fragen!

Behnke

Mitglied
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:

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.
Kann man diese Vererbung in der API irgendwie nachvollziehen?
Das führt dazu das eine Anwendung die einen nur JFrame benutzt auch nur eine Grafikresource vom Betriebssystem braucht, der Rest wird intern erledigt.
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.
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?
Wenn wir uns die Klasse Graphics ansehen entdecken wir einige hilfreiche Methoden drawRect, drawOval, ... entdecken.
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
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.
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
 

SuperSeppel13

Bekanntes Mitglied
Also zuerstmal ein Grundsätzlicher Hinweis:
So lang Posts schrecken ab! (Auch wenn nur der geringste Teil des Textes von dir ist...)

Nun zu deinen Fragen:

1) Das Weitergeben des Graphics-Objektes hat nichts mit (Klassen-)Vererbung zu tun. Das bedeutet nur, dass nicht jede Komponente ein eigenes Graphics-Objekt vom Betriebsystem bezieht, sondern, dass die des Fensters an die Unterkomponenten weitergegeben wird. Dies nachzuvollzeihen dürfte kompliziert sein - wird wohl irgendwo in der Klasse Container stecken, in den "paint"- und "paintComponents"-Methoden, da von dort das Graphics-Objekt weitergegeben wird - ist aber auch nicht nötig.

2) Das ist für dich als Programmierer erstmal nachrangig, da die übergabe sowieso automatisch erfolgt. Du musst dich darum kümmern, was du mit dem Graphics-Objekt anfangen willst, weniger darum, wo es herkommt.

3) Es ist richtig, dass abstakte Methoden noch nicht implementiert sind (wobei es auch in abstrakten Klassen nicht-abstrakte Methoden geben kann). Die Subklasse, die diese Implementierungen vornimmt entsteht in diesem Fall (vermutlich - so genau weiß ich das auch nicht) irgendwo bei der Übergabe des Graphics-Objektes vom Betriebsystem, da ja die konkrete Implementierung plattformabhängig ist. Davon bekommst du aber überhaupt nichts mit und es braucht dich auch nicht interessieren, wie die Subklasse im einzelnen aussieht.
Für dich ist wichtig: Das Graphics-Objekt, das du erhältst ist irgendwo erstellt worden (offensichtlich). Dabei müssen alle abstrakten Methoden konkretisiert worden sein - anders lässt sich keine Instanz der Klasse Graphics (bzw einer Subklasse) erstellen. Du kannst nun also auf aller Methoden von Graphics zugreifen, weil du sicher sein kannst, dass sie alle implementiert sind.

4) siehe 3).
Abstrakte klassen können nicht instanziert werden. Wenn ich jetzt aber eine Klasse "MyGraphics" erstelle, die von Graphics erbt und alle abstrakte Methoden implementiert, kann ich eine Instanz von MyGraphics erstellen. Trotzdem ist aber doch dieses "MyGraphics"-Objekt immernoch auch ein "Graphics"-Objekt, also eine Instanz von Graphics.
Java:
Graphics g = new MyGraphics(); 
//funktioniert, da MyGraphics ja auf jeden Fall all das "kann", was in Graphics beschrieben ist

Ich hoffe das war für dich etwas ergellend.
Viel spaß noch beim Java lernen!

SuperSeppel13

PS: schnapp dir am besten ein Java Buch (z.B. Java ist auch eine Insel), lies ein bischen, und fang an herumzuprobieren. Dabei lernst du am schnellsten und einfachsten. Ich habe auch einige Zeit gebraucht, bis ich das Vererbungs-Konzept wirklich verstanden hatte, aber das kam dann ganz von selbst.

EDIT:
5) Auf jeden Fall solltest du weiterlesen, denn da wird erklärt, warum der bis hierhin gewählte Ansatz (mit getGraphics) falsch ist!
 
Zuletzt bearbeitet:

Behnke

Mitglied
Vielen lieben dank SuperSeppel13 :toll:,
nächstes mal gibt es ein kürzeres Posting von mir.

Und ja das war sehr erhellend. Ich dachte ich muss die Zusammenhänge verstehen um später eigenständig arbeiten zu können. Aber wenn ich also ein Graphic-objekt erwische, interessiert mich nicht wo und wie die Subklasse die Funktionen konkretisiert hat! Das reicht mir als verständnis!

Danke für das eBook ich werd dann jetzt erstmal
lesen :rtfm: lesen :rtfm: lesen :rtfm:

Gruß Behnke
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Graph mit Swing zeichnen AWT, Swing, JavaFX & SWT 8
F Java Swing Rechteck in JPanel zeichnen AWT, Swing, JavaFX & SWT 7
T Swing / Kreis zeichnen AWT, Swing, JavaFX & SWT 2
Helgon Swing Mit Swing zeichnen / NetBeans GUI AWT, Swing, JavaFX & SWT 11
M Swing Warum öffnen sich beim Zeichnen mit Swing plötzlich zwei Fenster? AWT, Swing, JavaFX & SWT 5
I swing fenster neu zeichnen, wenn überdeckt AWT, Swing, JavaFX & SWT 8
E Rauten per Swing zeichnen lassen AWT, Swing, JavaFX & SWT 5
P Zeichnen von Ovalen in Swing (4 Gewinnt) AWT, Swing, JavaFX & SWT 3
GUI-Programmer Zeichnen in Swing - Frage AWT, Swing, JavaFX & SWT 6
Psypsy Bewegtes zeichnen in Swing AWT, Swing, JavaFX & SWT 24
T Swing Component in Graphics zeichnen AWT, Swing, JavaFX & SWT 4
M Swing Zeichnen AWT, Swing, JavaFX & SWT 3
byte Swing: Ebenen zeichnen AWT, Swing, JavaFX & SWT 3
G Frage zu Zeichnen in Swing Tutorial AWT, Swing, JavaFX & SWT 4
R Swing + Zeichnen Problem AWT, Swing, JavaFX & SWT 7
I Swing-Komponenten skaliert zeichnen AWT, Swing, JavaFX & SWT 6
F Effizientes zeichnen mit Swing AWT, Swing, JavaFX & SWT 9
B Zeichnen in Swing AWT, Swing, JavaFX & SWT 17
S Thread.sleep() beim Zeichnen auf Swing Komponenten? AWT, Swing, JavaFX & SWT 6
V Zeichnen mit Swing AWT, Swing, JavaFX & SWT 3
W Zeichnen auf eine Swing-Komponente AWT, Swing, JavaFX & SWT 5
G Zeichnen mit Swing AWT, Swing, JavaFX & SWT 5
M Mandelbrot mit BigDecimal erstellen und in der UI zeichnen, funktionierte nicht. AWT, Swing, JavaFX & SWT 1
H JavaFX Canvas neu zeichnen anstoßen AWT, Swing, JavaFX & SWT 34
H Transparent zeichnen mit drawImage in paintComponent Methode AWT, Swing, JavaFX & SWT 3
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
G 2D-Grafik Grafik in zwei verschiedenen Fenstern gleichzeitig zeichnen AWT, Swing, JavaFX & SWT 9
S Event Handling Neu zeichnen nur wenn Berechnung fertig ist AWT, Swing, JavaFX & SWT 4
W JavaFX Ich kann keinen Kreis richtig zeichnen AWT, Swing, JavaFX & SWT 8
CptK Funktionsgraphen effizient zeichnen und nur Teile von JPanel erneuern AWT, Swing, JavaFX & SWT 2
G Dreieck aus Pixeln zeichnen AWT, Swing, JavaFX & SWT 8
N Mit KeyListener ein rechteck zeichnen AWT, Swing, JavaFX & SWT 9
B 2D-Grafik paintcomponent Probleme beim zeichnen AWT, Swing, JavaFX & SWT 10
Z Swing Graph zeichnen lassen AWT, Swing, JavaFX & SWT 16
O Kann kei neues Panel zum zeichnen aufrufen... AWT, Swing, JavaFX & SWT 4
L Swing zeichnen AWT, Swing, JavaFX & SWT 14
S GUI Kreuz zeichnen und Position ausgeben AWT, Swing, JavaFX & SWT 3
S GUI Kreis zeichnen AWT, Swing, JavaFX & SWT 13
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
L Swing Ein Rechteck in ein Grid Zeichnen AWT, Swing, JavaFX & SWT 5
L JavaFX Animation, erst zeichnen dann anzeigen AWT, Swing, JavaFX & SWT 4
K Mehrere Linien zeichnen AWT, Swing, JavaFX & SWT 8
E Transparent zeichnen AWT, Swing, JavaFX & SWT 2
S AWT Probleme beim Zeichnen AWT, Swing, JavaFX & SWT 3
T Tic Tac Toe - GUI Linien zeichnen AWT, Swing, JavaFX & SWT 14
C Applet Zeichnen über Button-Click AWT, Swing, JavaFX & SWT 13
Soloeco Graph zeichnen AWT, Swing, JavaFX & SWT 1
G Zeichnen Programm AWT, Swing, JavaFX & SWT 1
H Swing + Paint: Mehrere Objekte zeichnen lassen AWT, Swing, JavaFX & SWT 3
W Swing JPanel nur einmal nach mehreren Änderungen neu zeichnen AWT, Swing, JavaFX & SWT 1
D Quadrat, Rechteck zeichnen AWT, Swing, JavaFX & SWT 3
K Probleme beim zeichnen mit paintComponent() AWT, Swing, JavaFX & SWT 1
JG12111989 mehrere Polyline-Objekte zeichnen AWT, Swing, JavaFX & SWT 3
A Swing JRadioButton zeichnen nicht AWT, Swing, JavaFX & SWT 4
J Swing Vertikales Zeichnen eines Strings mit Java2D AWT, Swing, JavaFX & SWT 1
7 JavaFX Problem beim Zeichnen eines Dreiecks in einem GUI AWT, Swing, JavaFX & SWT 6
P 2D-Grafik Bogen(Arc) zwischen zwei Punkten zeichnen AWT, Swing, JavaFX & SWT 2
KilledByCheese Swing 2D JLabel Array Maze zeichnen AWT, Swing, JavaFX & SWT 2
S Parallele Linien zeichnen AWT, Swing, JavaFX & SWT 5
J Linien auf JPanel zeichnen AWT, Swing, JavaFX & SWT 3
P AWT Canvas freihändig zeichnen AWT, Swing, JavaFX & SWT 1
llabusch Linien in JPanel zeichnen AWT, Swing, JavaFX & SWT 6
S passende PaintComponent ? Zeichnen in TextArea mit Scrollpane ? AWT, Swing, JavaFX & SWT 2
I Applet BlueJ Applet - Bild mit if-Schleife zeichnen lassen AWT, Swing, JavaFX & SWT 16
L JavaFX JavafX Timelime zeichnen und schön stylen? AWT, Swing, JavaFX & SWT 2
I JFrame neu zeichnen, nicht überzeichnen! AWT, Swing, JavaFX & SWT 2
I Spielsteine zeichnen und entfernen AWT, Swing, JavaFX & SWT 3
H JavaFX Freezes beim Zeichnen mit Canvas AWT, Swing, JavaFX & SWT 3
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
M JFreeChart neu zeichnen sich Wenn Jtable sich ändert AWT, Swing, JavaFX & SWT 5
S 2D-Grafik MouseDragged Linien zeichnen AWT, Swing, JavaFX & SWT 4
M Zeichnen ohne vorherige Linien zu löschen AWT, Swing, JavaFX & SWT 2
T Problem beim Zeichnen von Rechteck AWT, Swing, JavaFX & SWT 3
I Text zur Linie zeichnen AWT, Swing, JavaFX & SWT 1
I Pfeil zeichnen am Ende einer Linie AWT, Swing, JavaFX & SWT 1
D 2D-Grafik Inhalt eines Graphics in anderes Graphics zeichnen.... AWT, Swing, JavaFX & SWT 3
F Zeichnen des Button AWT, Swing, JavaFX & SWT 4
B Zeichnen mit paintComponent? Oder anders? AWT, Swing, JavaFX & SWT 15
C Swing Aus verschiedenen Klassen zeichnen. AWT, Swing, JavaFX & SWT 2
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
M Kein Zeichnen der Figuren auf JPanel AWT, Swing, JavaFX & SWT 4
J JButton neu zeichnen lassen AWT, Swing, JavaFX & SWT 9
S Quadrat auf Frame zeichnen AWT, Swing, JavaFX & SWT 2
P Image oder Icon auf Tooltip zeichnen AWT, Swing, JavaFX & SWT 4
C Graphics Objekt in Zeitschleife zeichnen AWT, Swing, JavaFX & SWT 4
X Swing JPanel mehrere Ebenen zeichnen AWT, Swing, JavaFX & SWT 13
G Zeichnen auf eine schwergewichtige Komponente? AWT, Swing, JavaFX & SWT 0
G Mehrere Strings um Kreis zeichnen und positionieren AWT, Swing, JavaFX & SWT 0
P SWT Nebula Gallery - Bildbereiche zeichnen AWT, Swing, JavaFX & SWT 3
A Swing Paint mit Button Clear den Hintergrund säubern um wieder zeichnen zu können AWT, Swing, JavaFX & SWT 2
A 2D-Grafik Zeichnen einer sich bewegenden Box mit BufferStrategy zieht Spur AWT, Swing, JavaFX & SWT 2
T AWT Bild laden und transparent zeichnen AWT, Swing, JavaFX & SWT 2
M JLabel über JButtons zeichnen AWT, Swing, JavaFX & SWT 4
J JApplet und Zeichnen AWT, Swing, JavaFX & SWT 8
P 2D-Grafik NPE beim Zeichnen auf Graphics g AWT, Swing, JavaFX & SWT 8
4 Swing Graphen selber zeichnen AWT, Swing, JavaFX & SWT 2
T Über mehrere Panel zeichnen AWT, Swing, JavaFX & SWT 2
T Zeichnen von getSubimage funktioniert nicht AWT, Swing, JavaFX & SWT 7
M Bilder zeichnen, NullPointer Exception AWT, Swing, JavaFX & SWT 3
N JPanel neu zeichnen AWT, Swing, JavaFX & SWT 10

Ähnliche Java Themen

Neue Themen


Oben