# Canvas update() paint() Problem



## MaxK1990 (3. Juli 2010)

Hallo Leute,
zunächst mal bin ich neu hier und habe eben die SuFu verwendet aber nicht wirklich was zu meinem Thema gefunden.

Also ich entwickle derzeit ein kleines Programm zum Erstellen von ER-Diagrammen, es ist vom Prinzip her ziemlich an MS Paint angelegt. Ich habe ein Hauptfenster mit einer RadioButton Group bei der man die Form auswählt. (Entität = Rechteck, Attribut = Rechteck mit runden Enden etc.). Dann kann man per Drag'n'Drop die bestimmte Form an der Stelle auf die Canvas zeichnen, wo man will. Jetzt habe ich aber zwei Probleme.

Zunächst ist da das Problem, dass ich nur eine Form zeichnen kann, heißt sobald ich die erste gezeichnet habe und dann eine neue beginne, wird die letzte gelöscht.
Dafür habe ich aber eine Lösung beim googlen gefunden. Es wurde mir geraten die Methode "update()" zu überschreiben und in dieser einfach die paint-Methode erneut aufzurufen. Das habe ich gemacht, aber leider hab ich dabei ein Nebeneffekt. Beim Aufziehen einer Form zeigt er mir nun ALLE bisher gezeichneten, sodass beim Aufziehen ca. 100 Rechtecke zu sehen sind. (Ich hoffe das ist genau genug erklärt, falls nicht unten stehen die Codeabschnitte.
Lösche ich die update-Methode wieder sehe ich das Aufziehen richtig und auch korrekt (Wie in Paint zieht man eifnach die Form auf).

Ein weiteres Problem ist, dass bei der update-Methode zwar alle Rechtecke gezeichnet werden, aber sobald ich die Fenstergröße verändere sieht man nur die letzte gezeichnete Form. Was genau muss ich machen, ich suche schon Tage und finde nichts.

Vielen Dank im Voraus


MaxK


Anhang:

Klasse - Hauptfenster: http://nopaste.info/2903a70527.html (Paket: paketFK)
Klasse - Form: http://nopaste.info/4185aa9ad5.html (Paket: paketGUI)

Die weiteren Klassen sind nur eine Startklasse und eine Fensterklasse, die mein "Über..." zeigt. Sollten also ziemlich uninteressant sein.
Ich hoffe ihr könnt mir helfen.


----------



## Akeshihiro (3. Juli 2010)

Ohne deinen Code zu kennen würde ich dir einfach mal empfehlen deine Formen als Objekte zu verwalten. Soll heißen: Du speicherst zu jeder gezeichneten Form aus deiner Formsammlung die Position und Größe (oder wie auch immer du sie speichern willst). Diese sollten natürlich in einer Liste (welcher Art auch immer) abgelegt sein, auf die die paint()-Methode zugreifen kann und somit auch alle Formen immer wieder zeichnen kann.


----------



## MaxK1990 (4. Juli 2010)

Akeshihiro hat gesagt.:


> Ohne deinen Code zu kennen würde ich dir einfach mal empfehlen deine Formen als Objekte zu verwalten. Soll heißen: Du speicherst zu jeder gezeichneten Form aus deiner Formsammlung die Position und Größe (oder wie auch immer du sie speichern willst). Diese sollten natürlich in einer Liste (welcher Art auch immer) abgelegt sein, auf die die paint()-Methode zugreifen kann und somit auch alle Formen immer wieder zeichnen kann.



Ich hab jetzt mal Subklassen der Klasse Form erstellt für jede Art von Form, also beispielsweise Entitaet und dort die Methode "entitaetZeichnen()" reingepflanzt. Jetzt hab ich die paint-Methode in soweit abgeändert, dass ich bei Zeichnen eines neuen Rechtecks ein neues Objekt erstelle und dieses in eine ArrayList<Form> speichere.
Aber irgendwie klappt das nicht, wie ich das will. Könntest evtl. ma schauen wo mein fehler ist?

Hier der abgeänderte Code der Hauptfenster-Klasse und eine Subklasse der Klasse Form



Hauptfenster (abgeändert) : http://nopaste.info/f5031a5dca.html
Entitaet (Subklasse von Form) : http://nopaste.info/8c8c8b30f2.html




Edit:// Bitte die Bedinungsabfragen für Multiplizität und Connection nicht beachten, die sind noch nicht bearbeitet.


----------



## Akeshihiro (4. Juli 2010)

Ich schau mal drüber, aber ich hab jetzt beim Diagonalschauen schon die Vermutung, dass sich da paar Sachen ändern werden ^^

EDIT:
Also ...

Du programmierst noch nicht lange oder? Jedenfalls solltest du dir aussagekräftigere Bezeichner ausdenken, bei manchen musste ich erst den ganzen Code filzen, bis ich verstanden hatte, wofür die überhaupt da sind. Und obwohl ich den Code mehrmals angeschaut habe, habe ich nicht wirklich verstanden, was passiert, hatte nur eine ungefähre Idee. Letztendlich musste ich das Programm zum Starten bekommen und erst dadurch hab ich dann in etwa verstanden, was du vor hast.

Ist alles nicht böse gemeint, nur durch deine Codestruktur muss man erstmal durschteigen, vor allem weil du zwar OOP versucht hast zu benutzen, aber irgendwie auch nicht oder Sachen zusammengeklatscht hast, die gar nicht zusammen gehören, z.B. verschachtelte Klasse. Es gibt Ausnahmen, aber kannst dir eins merken: Klassen immer in eigenen Dateien und mit passenden Schnittstellen erstellen. Dass die bei dir verschachtelt waren, hat dir sicherlich etwas Arbeit abgenommen (ich musste da erst ein wenig rumpfuschen um das vernünftig in Gang zu bekommen), aber das ist nicht empfehlenswert und auch kein guter Stil und dann waren das auch noch so Sachen, die mit einander gar nix zu tun haben, also auslagern 

Naja egal, will dir keinen Vortrag halten, deswegen gibts erstmal die veränderten Codes. Bitte nicht über den Packagenamen wundern, hat Ordnungsgründe, müsstest du bei dir also ändern. Hab die Sources mal angehängt, is mir zu doof die jetzt alle hier einzufügen. Hab den Code halt soweit korrigiert und zum Laufen bekommen, aber das sage ich vorweg. Das ist dennoch kein idealer Code, also da müssen noch ein paar Sachen geändert werden, aber

1. ist das nicht mein Projekt, du musst damit klarkommen, was nicht viel bringt, wenn man den eigenen Stil "aufzwingt" (was auch damit zusammenhängt bzw. hinzukommt, dass keiner deine Gedankengänge und Ideen kennt)
2. geben wir hier nur Hilfestellung und machen Korrekturen und machen nicht die Arbeit für andere

Insofern hoffe ich, dass ich etwas helfen konnte ohne zu sehr einzugreifen ^^


----------



## MaxK1990 (4. Juli 2010)

Akeshihiro hat gesagt.:


> Du programmierst noch nicht lange oder?



Da hast du allerdings recht, ich habe bisher nur ein kleines Hangman-Spiel mit DB-Verbindung programmiert und sonst versuche ich mich immer mal wieder an neuen Dingen und studiere fleißig Java Bücher. Ich denke daran sieht man das recht gut.

Danke erstmal für deine Hilfe und die Arbeit, die du dir gemacht hast.

Ich steig zwar noch nicht ganz durch (bspw. die for-Schleife in der paintComponent-Methode ? Aber ich versuch mein bestes sie zu verstehen) aber es sieht doch alles um einiges geordneter aus. Was ich noch fragen wollte, was genau macht die Funktion @Override ist das nur ein Hinweis, dass man hier die Polymorphie anwendet oder macht das ganze wirklich was im Code aus?


----------



## Akeshihiro (4. Juli 2010)

@Override ist eine Annotation und hat für Java an sich erstmal keine Bedeutung. Eclipse fügt das einfach automatisch ein, aber ich persönlich finde es auch besser so, weil man sofort sieht, dass es eine überlagerte Methode ist.

paintComponent() statt paint() und JComponent statt Canvas hab ich genommen, weil man Swing und AWT nicht mischen soll und da bei dir ohnehin schon alles in Swing war, hab ich halt Canvas gegen JComponent getauscht. paintComponent() verwendet man halt bei Swing-Komponenten, bei AWT-Komponenten eben paint().

Ich kann dir gern den Code erklären und auch sonst Sachen, wenn du Fragen hast (und die wirst du sicherlich haben), aber speziell für den Code (in diesem Fall) würde ich da lieber ICQ oder so bevorzugen.


----------



## MaxK1990 (4. Juli 2010)

Akeshihiro hat gesagt.:


> Ich kann dir gern den Code erklären und auch sonst Sachen, wenn du Fragen hast



DAs wäre wirklich Klasse, da ich doch immer mal wieder ne Frage hab und mir brennt gerade eine auf der Zunge, dann hab ich zunächst keine mehr. 

Meine ICQ-Nr. schicke ich dir per PM

Danke, danke, danke für die nette Hilfe, war wirklich SEHR hilfreich.


----------



## timestamp (4. Juli 2010)

Alternativ kann auch das Forum befragt werden, damit andere Leute eine Lösung finden wenn sie ähnliche Probleme haben


----------



## Akeshihiro (4. Juli 2010)

timestamp hat gesagt.:


> Alternativ kann auch das Forum befragt werden, damit andere Leute eine Lösung finden wenn sie ähnliche Probleme haben


Ja, das sowieso ^^ Getreu "User helfen Usern"


----------



## MaxK1990 (4. Juli 2010)

Gut dann stelle ich sie hier:


Wie mach ich es, dass ich ein gezeichnetes Rectangle um 45° drehe, also dass es ein Karo wird.


g.drawRect(getXPos(), getYPos(), getXPos2(), getYPos2());


hab ich bisher!


----------



## timestamp (4. Juli 2010)

Hi

schaue dir mal diesen Artikel an  Das regt noch mal den Apparat da oben an 

Drehmatrix


----------



## Akeshihiro (4. Juli 2010)

Naja, deine Idee ist ja nicht schlecht, aber ich glaube ich kenne da einen doch etwas einfacheren Weg ^^

Mit Graphics2D hat man ein noch mächtigeres Werkzeug als mit dem normalen Graphics. Rotation ist damit z.B. kein Problem, die Methode rotate() hilft einem dabei 

Beispiel:

```
package tests.graphics.zeichnen;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class RotateTest extends JFrame {
	private static final long	serialVersionUID	= -3964681291270572680L;

	public RotateTest() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		getContentPane().add(new JPanel() {
			private static final long	serialVersionUID	= 3434582401591348666L;

			@Override
			public void paintComponent(Graphics g) {
				Graphics2D g2 = (Graphics2D)g;

				// Mit Kantenglättung gleich etwas schicker ;)
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
						RenderingHints.VALUE_ANTIALIAS_ON);

				// Das Ganze um 45° drehen und dann etwas zeichnen
				g2.rotate(Math.toRadians(45), 100, 100);
				g2.fillRect(50, 50, 100, 100);
			}
		}, BorderLayout.CENTER);

		
		
		setSize(500, 500);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	public static void main(String[] args) {
		new RotateTest();
	}
}
```


----------



## timestamp (4. Juli 2010)

Das ist ja langweilig


----------



## Akeshihiro (4. Juli 2010)

Stimmt, aber effektiver und schneller ^^

EDIT:
Achso, bevor ich es vergesse ... Die Rotation erfolgt bei positiven Zahlen im Uhrzeigersinn. Wenn man die Rotation gegen den Uhrzeigersinn haben will (so wie es in der Schule meist dargestellt wird), dann muss man negative Zahlen verwenden. Und naja, je nachdem wo man den Drehpunkt festlegt, ist dieser eben auch zu finden, ansonsten halt die linke obere Ecke.


----------

