# Programm aufgrund von paint() zu langsam



## soFar (18. Sep 2007)

Hallo,

ich habe folgendes Problem mit meinem Java Programm:
Im unteren Bereich befindet sich eine Animation, die sich häufig verändert (und dabei auch ihre Größe verändert).
In meiner erste Implementierung hab ich dieser Animation den GlassPane zugewiesen,
bei einem zweiten Versuch hab ich es mit LayeredPane versucht,
aber .. das Problem bleibt.. mein Programm ist zu langsam.. 
was wohl daran liegt, dass alles zu oft neu gezeichnet wird.. alleine beim Start über 30 aufrufe der paintComponent() Methode der Objekte oberhalb der Animation ... und immer wenn sich an der Animation was tut (abhängig von der Maus) kommen wieder x aufrufe hinzu, was die animation schon deutlich langsamer macht (je nachdem, was ich sonst noch für objekte in meinem fenster habe)..

gibt es eine Methode, wie ich meinem Programm sagen kann, wann es was neuzeichnen soll.. also nicht immer alles.. 
z.b. ne Gruppierungsfunktion...
denn.. die Animation hat nur eine bestimmte maximale Größe.. erreicht garnicht alles.. Trotzdem wird das komplette Fenster neu gezeichnet...

hat jemand ne idee?

MfG


----------



## André Uhres (18. Sep 2007)

soFar hat gesagt.:
			
		

> ..und dabei auch ihre Größe verändert..


Ich denke mal, das hängt viel davon ab, wie du die die gesamte Oberfäche zusammengestrickt hast.
Wenn z.B. dabei eine Grössenanpassung von anderen Panels erforderlich wird, 
dann muss natürlich jedesmal ganz neu gezeichnet werden :wink:


----------



## soFar (18. Sep 2007)

nein.. die anderen Objekte bleiben unverändert....
es kann nur zu einer überlappung der animation mit den Objekten obendrüber kommen... aber auch wenn dies nicht geschieht wird alles neu gezeichnet.. 
aus testzwecken hab ich auch mal der animation den halben bildschirm gegeben und die anderen objekte in der anderen häfte angeordnet, so dass die sich auf keinen fall in die quere kommen können..  trotzdem wird alles statt nur die animation neu gezeichnet... und wenn diese sich bei der kleinsten mausbewegung (über der animation) verändert, kommen da ne menge aufrufe zusammen....


----------



## Michael... (18. Sep 2007)

wie ist den die Oberfläche aufgebaut? Welche paintComponent() wird überschrieben? Ein bisschen Code wäre auch nicht schlecht...


----------



## Guest (18. Sep 2007)

das mit dem Code ist schwierig, weil es sich um ein größeres Prog. handelt

ich arbeite hauptsächlich mit JPanels..

+---------+-----+
|.............|.......|
|......a.....|..b...|
|.............|.......|
+---------+-----+
|...........c.........|
+----------------+


a und b sind jeweils extends JPanel ..
und in der paintComponent Methode lasse ich (auf verschiedene Art und Weise) den Hintergrund berechnen...

in der ersten Variante ist c nur ein "leeres Feld" .. ein platzhalter.. weil ich das BorderLayout verwendet habe.. aber c glassPane sein muss (weil es seine größe z.b. verändert etc)

in der zweiten Variante arbeite ich auf LayeredPane Ebene..
dort ist C dann die Animation mit dem höchsten Integerwert...

wenn ich z.b. es folgendermassen anordne:
+---------+-----+
|......a.....|..b...|
+---------+-----+
|........nichts.....|
+----------------+
|...........c.........|
+----------------+

wird a und b jedes mal neugezeichnit... 

ich würde halt gerne sowas machen wie
if (c wird neu gezeichnet){
  zeichne nur das was ich dir sage neu
  }
else {
  nichts
  }


----------



## Wildcard (18. Sep 2007)

http://java.sun.com/javase/6/docs/api/java/awt/Component.html#repaint(int, int, int, int) !?



> und in der paintComponent Methode lasse ich (auf verschiedene Art und Weise) den Hintergrund berechnen...


Das hört sich übrigens nicht gesund an und könnte schon eher dein Performance Problem erklären.


----------



## Guest (19. Sep 2007)

natürlich ist es nicht gerade schnell, wenn ich dort ein Hintergrundbild laden lasse...
aber.. wenn mein programm begreifen würde, dass er das z.b. beim start nicht 30 mal.. sondern nur einmal berechnen muss, wäre das schonmal gut...


----------



## Marco13 (19. Sep 2007)

Wenn du es einfach bleiben lassen, und stattdessen woanders laden würdest, wäre das sogar noch besser  :roll: Aber kannst ja in der repaint ein boolean-flag setzen 'imageAlreadyLoaded'  :autsch:  :wink:


----------



## Guest (19. Sep 2007)

```
Wenn du es einfach bleiben lassen, und stattdessen woanders laden würdest, wäre das sogar noch besser
```
?


```
Aber kannst ja in der repaint ein boolean-flag setzen 'imageAlreadyLoaded'
```
 wenn ich sowas in die paintComponent methode einbauen, ist das Bild am Ende weiß .. weil es nur am anfang geladen wurde danach aber von "nichts" überschrieben wurde...


----------



## Gast (19. Sep 2007)

edit:
was macht z.b. dieser RepaintManager .. könnte er mir weiterhelfen?


----------



## soFar (19. Sep 2007)

.. 
wie mache ich das z.b. wenn ich nur ganz billig sagen will, dass er das bild bei jedem 32. aufruf neuzeichnen soll...


```
int n=32;
	
		@Override 
		protected void paintComponent( Graphics g ) { 

	    	Graphics2D g2 = (Graphics2D)g;	
			
	    	if(n==32){
	    		super.paintComponent( g );
                        //hier malt er mir nun was feines
		        n=0;
	    	}
		n++;
		System.out.println("Aufrufnr.: "+n);
		}
```


.. leider.. zeichnet er mir immer wenn n!=32 ist ne weisse fläche...
wie kann ich das umgehen?


----------



## Wildcard (19. Sep 2007)

Ich hab dir doch gesagt wie du den repaint Bereich einschränkst!
Und in paintComponent darfst du definitiv nichts laden. Das dauert viel zu lange.


----------



## soFar (19. Sep 2007)

das Bild wird natürlich nicht in der paint-Methode geladen..
ich hab es zu dem zeitpunkt schon.. aber alleine das Zeichnen reicht, um es zu bremsen.. nur mit einem einfarbigen Hintergrund ist die geschwindigkeit in ordnung..
und es liegt daran, dass alles zu oft neugezeichnet wird...

ich konnte mit deinem link leider nicht so viel anfangen..
es gibt kein repaint(), das ich einfach duch ein repaint(x,y,w,h) ersetzen könnte..
falls du es nicht so gemeint hast, erklär es bitte nochmal für dumme...


----------



## Wildcard (19. Sep 2007)

Wo kommen die repaints denn dann her?


----------



## soFar (20. Sep 2007)

indem java merkt, dass sie was an der animation verändert hat
und diese neugezeichnet werden muss..
und immer wenn dies geschieht, wird leider alles (das komplette Fenster) neu gezeichnet


----------



## Wildcard (20. Sep 2007)

Nein, eigentlich nicht.
Die produzierst du auf irgendeine Weise (direkt oder indirekt) selbst.


----------



## soFar (20. Sep 2007)

gibt es eine Methode (Tools, Plugins) mit denen man herrausbekommt, wann (von wem) die paintComponet von a und b (siehe Bild erste Seite) aufgerufen wird..
ich benutze Eclipse.. das liefert nicht reinzufällig sowas mit, oder?


----------



## Wildcard (20. Sep 2007)

Breakpoint setzen?


----------



## dandi (24. Sep 2007)

unter Eclipse 3.3 (Europa) gibt es das Plugin TPTP. mit dem läßt sich ein Laufzeit- oder Speicherbedarf-Profiling machen. 
gesetzt den Fall es schmiert nicht permanent ab...


----------

