# Graphics erstellt Componente scheinbar nicht richtig



## Onkel markus (12. Jul 2007)

Hallo,
Also...
Ich habe ein JPanel mit einer Methode paint(), auf der einige Sachen (ein KoordinatenSystem) gezeichent werden.
In der Methode paint() wird eine weitere Funktion aufgerufen, die neue JPanels added, die wiederum eine paint() Methode haben.
Das funktioniert soweit ganz gut (das ganze ist ein Graphenprogramm, die geaddeten panels sind die graphen); aber wenn ich das Fenster minimiere und wieder herstelle, wird nur das Koordinatensystem gezeichnet.
Sobald ich ein refresh mache, in dem ich die paint() methode neu aufrufe, erscheinen die graphen wieder. auch wenn das Fenster an einer stelle überlagert wurde, muss man ein refresh machen, um die graphen wiederherzustellen.

Die Paint methode wird doch aber eigentlich jedesmal von selber aufgerufen, wenn ich ein Fenster wiederherstelle, oder? Durch repaint().... und etwas anderes tue ich mit dem Programm auch nicht, wenn ich refreshe... Wo liegt also das Problem?

Auch wenn ich drucken will, und die PrintComponent-Methode nehme, wird nur das Koordinatensystem angezeigt...

Ich weiß nicht woran das liegt, da auch hierbei doch die Paintmethode verwendet wird, bei der die Graphen gezeichnet und geaddet werden müssten...
Weiß wer, was man da machen kann?
Mfg Markus

PS: hier der Code der paint-Methode (gekürzt);

```
public void paint(Graphics g){
		super.paintComponent(g);
		super.paintBorder(g);
		paintGraphs();    //Ruft Methode auf, die ein JPanel addet auf dessen graphic wieder gezeichnet wird
		super.paintComponents(g);
}
```


----------



## Marco13 (12. Jul 2007)

Onkel markus hat gesagt.:
			
		

> Hallo,
> In der Methode paint() wird eine weitere Funktion aufgerufen, die neue JPanels added, die wiederum eine paint() methode haben.


Das ist Unfug. "paint" heißt "paint", weil sie "paint"en soll. Andernfalls hieße sie ja "paintAndDoSomeOtherStuffThatHasToBeDoneSometimesWhenTheWindowIsRepainted". Naja. Selbst DA würde das Hinzufügen von Components nicht reingehören :wink: Die Componens sollten im Konstruktor hinzugefügt werden, oder in einer Methode, die genau dafür da ist (und auch nur genau dann aufgerufen wird, wenn es nötig ist). Übrigens sollte man bei Swing i.a. paint*Component* überschreiben.


----------



## SlaterB (12. Jul 2007)

wer immer das nicht automatisch weiß, wäre zum Ausprobieren über ein kurzes vollständiges Programm erfreut, in dem er Fehler auftritt

so kurz wie möglich, nur ganz simples Unterfenster mit anderer Hintergrundfarbe oder so


----------



## Onkel markus (12. Jul 2007)

Marco13 hat gesagt.:
			
		

> Onkel markus hat gesagt.:
> 
> 
> 
> ...




...Ich hatte es schon ausprobiert, die paintGraph() - Methode von außen aufzurufen, also nach dem normalen Paint; das ändert nix an der Sachen daran scheint es also nicht zu liegen....

Das heißt das Programm tutexakt das Selbe wenn ich es in die Paintmethode reinmache, und weil das immer aufgerufen werden muss, wenn ich painte, ist es so zeitsparend und schadet ja nix...


Ich glaube, dass der Fehler im Fenster liegt:
Was wird aufgerufen, wenn das Fenster neu geladen wird?
repaint, oder?
aber wenn ich das per Buttondruck repainte, geht alles....


----------



## SlaterB (12. Jul 2007)

> das ändert nix an der Sachen daran scheint es also nicht zu liegen.... 

> is es so zeitsparend und schadet ja nix... 

> Ich glaube, dass der fehler im Fentser liegt

dein Wort in Gottes Ohr..


----------



## Onkel markus (12. Jul 2007)

Ich hab dass jetzt so umgeschrieben wie du gesagt hast (1.) paintComponent, (2.) Methode paintGraphs() von außen aufgerufen...

Wie gesagt, der Fehler ist immer noch da.
Es wird doch ein repaint durchgeführt, wenn ein Fentser aktiviert wird, oder?


----------



## Marco13 (12. Jul 2007)

*Kristallkugel rauskramt* Rufst du in deiner ominösen, geheimnisvollen "paintGraphs" Methode vielleicht irgendwo "getGraphics" auf? Selbst wenn nicht: In der paint-methode sollten keine Components erstellt werden. Wenn du das trotzdem tun willst, mußt du damit rechnen, dass bestimmte Dinge nicht funktionieren.


----------



## Onkel markus (12. Jul 2007)

Nein, getGraphics wird nicht aufgerufen...
Wie gesagt, Components werden nicht mehr erstellt, hab ich umgebaut. Aber das Problem ist weiterhin da...
Jetzt wird eben das JPanel mit Graphics als Koordinatensystem verwendet, wenn das gezeichnet ist werden die weiteren graphen als JPanel erstellt und auf das Koordinatensystem geaddet....
Wenn ich beim PrintJob sage printComponents... dann wird doch das komplette JPanel mit allem was drin, drauf und dran ist (so wie es sichtbar ist) gedruckt, oder?
Auch hier wird wie gesagt nur das Kordinatensystem gedruckt, der Rest (die Graphen) sind nicht sichtbar... Obwohl sie einfache JPanels sind, auf deren Graphic der Graph liegt....


----------



## SlaterB (12. Jul 2007)

SlaterB hat gesagt.:
			
		

> wer immer das nicht automatisch weiß, wäre zum Ausprobieren über ein kurzes vollständiges Programm erfreut, in dem er Fehler auftritt
> 
> so kurz wie möglich, nur ganz simples Unterfenster mit anderer Hintergrundfarbe oder so


----------



## Onkel markus (12. Jul 2007)

Hier der Link zum Programm soweit es gerade ist:
http://rapidshare.com/files/42557617/diagramm.jar.html
Einfach starten, auf "add new function", dann zum Beispiel x*x eingeben und refresh drücken. (Wenn man Zahlen eingibt muss man noch Y.0 eingeben, der Parser ist noch net ganz fertig...
Dann minimieren, wiederherstellen und der graph ist weg....


----------



## Marco13 (13. Jul 2007)

Hui. Naja. Dann stimmt an dem Programm wohl irgendwas nicht.


----------



## Onkel markus (13. Jul 2007)

Ja, das ist klar;-)
Nur: Woran liegt das?
Der Ablauf müsste doch stimmen?
Die JPanels werden doch auch repainted, wenn man das Fenster neu aktiviert, oder?


----------



## Onkel markus (13. Jul 2007)

Hat vielleicht wer ne andere Idee, wie man das Problem umgehen könnte?
Ich setze die ja nur auf andere JPanels, die Graphen, damit die Farbe von denen per setForeground() bestimmt werden kann. Kann man auch auf einem JPanel verschiedenfarbige Linien zeichnen?


----------



## SlaterB (13. Jul 2007)

da du eh ständig nachfragst wirst du es einmal noch ertragen können, dann bin ich auch still 



			
				SlaterB hat gesagt.:
			
		

> wer immer das nicht automatisch weiß, wäre zum Ausprobieren über ein kurzes vollständiges Programm erfreut, in dem er Fehler auftritt
> 
> so kurz wie möglich, nur ganz simples Unterfenster mit anderer Hintergrundfarbe oder so



(und nein: dein komplettes Program (gar ein jar!) zählt nicht  )


----------



## Onkel markus (13. Jul 2007)

ich habe doch das ganze Programm online gestellt... da ist der Fehler doch sehr ersichtlich, oder?
Aber wennn du willst kann ich dir auch nochmal nen eigenes Programm schreiben...
Aber wirklich nur wenn du den Fehler nicht aus dem Original ablesen kannst....


EDIT:
Ok, schreibe gleich nen anderes mit dem Problem...

EDIT2:
Immer wenn ich das Programm ganz genauso schreibe wie das erste, tritt das Problem nicht auf....
Ich kapier des net....


----------



## Onkel markus (13. Jul 2007)

Ich hab noch was neues rausgefunden: Der graph/die graphen werden immer exakt nach dem ersten repaint() angezeigt. d.h. wenn ich in der refresh methode in der die graphen gezeichnet werden, kein repaint mache, passiert nix (logisch). Wenn ich dann das fenster deaktiviere und neu aktiviere, erscheinen die graphen, wenn ich das wiederhole sind die graphen weg.


----------



## Marco13 (13. Jul 2007)

Onkel markus hat gesagt.:
			
		

> Immer wenn ich das Programm ganz genauso schreibe wie das erste, tritt das Problem nicht auf....
> Ich kapier des net....



Damit ist das Problem ja gelöst: Du schreibst ein "Programm2" das genauso aussieht, wie dein "Programm1", in dem das Problem aber nicht auftritt. Dann löschst du "Proramm1" und benennst "Programm2" um in "Programm1". Dann hast du dein Programm, und das Problem tritt dort nicht mehr auf. 

OK. Nachdem die bisherigen "Spitzen" und "Zaunpfahl-Winks" zu subtil für dich waren, war er der vermutlich auch.

Da das, was du beschrieben hast, aber nicht besonders kompliziert klingt, und hier im Forum immer wieder von unerklärlichen Problemen beim Zeichnen berichtet wird, die sich, nachdem ein Stück eigenständer, vollständiger, compilerbarer(!!!) Code gepostet wurde, meistens innerhalb von 1, 2 Antworten klären lassen, kann man nur sagen, DASS du etwas falsch machst, aber dir niemand sagen kann, WAS das ist, solange man nicht weiß, WAS du überhaupt machst (und das weiß man nur, wenn man den Code hat).


----------



## Onkel markus (13. Jul 2007)

Also;
Dieser Wink mit dem Zaunpfahl.. verstehen tu ich den schon.. nur dass das nicht sooo einfach ist.
In Programm 2 habbich genau einen Strich, der festgelegt ist, in Programm 1 werdenm da hunderte von berechnet.. und nochmal schreiben will ich den scheiß net...
Ok, wenn du willst kann ich dir hier das gesamte Programm reinstellen... oder Wenn du sagst dann Teile daon..


----------



## SlaterB (13. Jul 2007)

das mindeste, was du dann an Arbeit vorleisten könntest,
wäre dein Programm zu kopieren und soweit wie möglich zu vereinfachen (eh meist das geschickteste Vorgehen)

mit einem Strich ist der Fehler weg, mit 100 da, dann probier mal 50 oder 75 usw.,
normalerweise kann man doch jede Menge wegstreichen,
Layout, 
Menüs, 
Eingabemasken,
z. T. Kommentare (nicht die wichtigen, nur Autor, Datum, Copyright oder was sonst so den Bildschirm zuspammt)

Datei-Ladeoperation durch Test-Zahlen ersetzen usw,

wenn du da was schaffst und am Ende sogar sagen kannst
'wenn ich Zeile oder Block xy entferne ist der Fehler weg',
dann wäre das schon hilfreich


----------



## Marco13 (13. Jul 2007)

Ein Stück code, das man ohne Umschweife compilieren und starten kann, und bei dem der Fehler auftritt.


----------



## Onkel markus (13. Jul 2007)

Also;
ich habe jetzt beim Vereinfachen ne einfachere Methode gefunden, die Graphen im System zu zeichnen. Diese werden nun nicht mehr als JPanel geadded sondern gleich in das KoordinatenSystem eingetragen.
Aber daran scheint es auch nicht zu liegen.

Der Fehler besteht weiterhin... Er liegt auch nicht an irgendwelchen Linien, sondern scheinbar an einer anderen Klasse... Denn wenn ich diese Aufrufe (bei paint()), was allerdings mehr als umständlich ist, geht alles.
In dieser Klasse werden die Funktionen gespeichett und geparst;
ich werde das hinterher nochmal versuchen..
mfg


----------



## Onkel markus (13. Jul 2007)

Also scheinbar leigt der Fehler hier:
beim refresh werden alle Funktionen in Koordinaten umgerechnet und in einem Array gespeichert.
Dieses Array muss ich neu bestimmen, um die Graphen anzuzeigen.
Aber dieses Array ist eigentlich immer vorhanden, wird bei refresh nur aktuallisiert, dementsprechend hab ich keine Ahnung woran das liegt.

In der PaintComponent() methode liegt jetzt also ein Programmteil, der ein Array aus prog (pF[]) ausliest und dementsprechend die Graphen zeichnet.

```
try{
			//Die Graphen
			for(int h = 0;h<prog.pF.length-1;h++){
				coord[] c = prog.pF[h].graph;
				g.setColor(prog.pF[h].getColor());
				coord alt = anpassen(c[0]);
				for(int e = 1;e<c.length;e=e+1){
					coord neu = anpassen(c[e]);
					g.drawLine((int)alt.x, (int)alt.y, (int)neu.x, (int)neu.y);
					alt = neu;
				}
			}
		}
		catch(NullPointerException e){
			System.out.println("null");
		}
```

Dieses Array pF[] wird in der FDunktion getEingaben() aktuallisiert:

```
public static void getEingaben(){ //Speichert alle angegebenen Funktionen in pF[] ab
		Component[] c = Gui.eingabe.getComponents();
		int stelle = 0;
		pF = new pointedFunction[c.length+1];
		for(int i = 0; i<c.length;i++){
			try{ //Function
				function f = (function)c[i];
				if(f.active()){
					pF[stelle]=new pointedFunction(f);
					stelle ++;
				}
			}
			catch(ClassCastException e){ //Points
				points p = (points)c[i];
				if(p.active()){
					pF[stelle]=new pointedFunction(p);
					stelle ++;
				}
			}
		}
	}
```


Eigentlich müsste das Array pF[] doch nach getEingabe() immer zugriffsbereit sein, oder?
Scheint es aber nicht zu sein, denn nur wenn ich getEingaben() bei der paintComponent Methode aufrufe, wird der graph bei jeder aktuallisierung geladen. Auch bei speichern als JPG und drucken wird er nur dann angezeigt.

pF[] wird aber unter keinen Umständen verändert, außer durch getEingaben(); aber wieso reift die paint(() Methode dann scheinbar immer auf ein leeres Objekt zu?
Wenn ich das einmal bestimmt hab, ist das Objekt doch da (ich meine pF[]). Das heißt der Zugriff sollte ohne Schwierigkeiten möglich sein. Trotzdem wird der GFraph nicht ordentlich gezeichnet.
Wenn ich aber jedesmal in der paint() methode die getEingaben Funktion aufrufe, ist das Programm überlastet (Kein Wunder).
Also muss ich das irgendwie umgehen... wobei ich immer noch nicht weiß warum der Zugriff auf dieses nicht aktuallisierte Objekt schwierig oder unmöglich sein soll....


----------



## Marco13 (13. Jul 2007)

Wenn ich das jetzt so sehe, bin ich schon fast froh, dass du nicht mehr Code gepostet hast  :autsch:  :bae: 

Klassennamen schreibt man Groß. 
Eine get-Methode sollte etwas zurückliefern.
Man sollte keine statischen Fields verwenden (wie pF)
Die NullPointerException solltest du durch eine Abfrage wie "if (sonstwas == null) return;" vermeiden.
Und das wichtigste: Man verwendet keine Exceptions, um Logik zu bauen!!! (das mit dem "catch ClassCastException" ist ... :autsch: )

Auf der verzweifelten Suche nach Code, der sich für eine Antwort verwerten läßt, bin ich nochmal über dein Eingangsposting gestolpert - dazu nur eine Frage nebenbei (weil ich, wenn du endlich mal was compilierbares posten würdest, das jetzt sowieso nicht testen könnte) ...

```
public void paint(Graphics g){
      super.paintComponent(g);
      super.paintBorder(g);
      paintGraphs();    //Ruft Methode auf, die ein JPanel addet auf dessen graphic wieder gezeichnet wird
      super.paintComponents(g);
}
```
Warum rufst du dort nach dem "paintGraphs" eigetlich _nochmal_ paintComponent auf?


----------



## Onkel markus (13. Jul 2007)

super.paintComponent(g); 
super.paintComponents(g);
Soviel zum Thema _nochmal_...
Das üproblem is gelöst.. ich weiß aber immer noch nicht woran es lag...

Außerdem:


> Eine get-Methode sollte etwas zurückliefern.


Muss ja nicht... das getEingabe() drückt aus, dass prog die Eingaben erhalten soll.. man könnte auch sagen callEingaben.. aber get ist in diesem Fall doch etwas außdrucksvoller.... :bae:


----------

