Zu viele repaints()

Status
Nicht offen für weitere Antworten.

dvid85

Aktives Mitglied
Hallo,
ich habe eine GUI, die hauptsächlich aus png-bildern besteht. Ich habe eine Klasse ImagePanel, die ein JPanel erweitert und in der paintComponent() eben ein Image zeichnet. weiter nichts.
Auf ein JFrame habe ich dieses ImagePanel, so zu sagen als Hintergrundbild, geaddet.
Auf diesem ImagePanel habe ich nun diverse Komponenten (Drehregler) mit MouseListenern geaddet, die beim drehen ihre eigene repaint() aufrufen.

Nun das Problem:
Leider wird auch jedes Mal das gesamte Hintergrundbild, also dieses ImagePanel neu gezeichnet (ca 150mal pro Sekunde). Manchmal kommt es dabei Aussetzern.

Was ich versucht habe:
setIgnoreRepaint(true) auf dieses ImagePanel bring gar nichts. Kann es sein, dass der Befehl nur repaint-Befehle vom System blockt?
Dann habe ich die Klasse ImagePanel so gestaltet, dass nur 2 mal absolut die paintComponent aufgerufen werden kann. Das Ergebnis ist, dass die Flächen bei den Drehreglern grau geworden sind :(
Also braucht man anscheinend schon ein repaint()

Hat Jemand ne Idee, was ich noch machen könnte? Mein Ansatz wäre jetzt, das Hintergrundbild in mehrere Teile zu zerlegen, damit nicht alles repaintet werden muss. Aber vielleicht gehts ja auch noch eleganter.
Bin für jede Hilfe sehr dankbar, weil dieses Projekt sehr wichtig ist.

Gruß David
 

dvid85

Aktives Mitglied
Code:
	public ImagePanel(Image img){
		this.img = img;
		Dimension size = new Dimension(img.getWidth(this), img.getHeight(this));
		setSize(size);
		setMaximumSize(size);
		setMinimumSize(size);
		setPreferredSize(size);
		setOpaque(false);
	}

public void paintComponent(Graphics g){

		g.drawImage(img,0,0,(int)(img.getWidth(null)*factor, (int)(img.getHeight(null)*factor), null);
	}
 

dvid85

Aktives Mitglied
oh, ich seh grad ein getWidth() statt img.getWidth(null) reicht ja auch. ist aber nicht ausschlaggebend jetzt
 

diggaa1984

Top Contributor
hm daran wirds nu nich liegen, aber das opaque könnte doch raus sofern sich das image eh übers gesamte panel erstreckt!?

aso da spielt ja noch der Faktor rein .. hm .. aber opaque(false) soll nich grad schonend sein :D
 

dvid85

Aktives Mitglied
ich glaube opaque(false) ist eh defaultmäßig beim JPanel drin. Ich habe diese Klasse ja nicht nur für das Hintergrundbild. Es ist allgemein die Klasse mit der ich Bilder zeichne.
 

Marco13

Top Contributor
Hm. Ich gehe davon aus, dass der Drehregler eine JComponent ist, an der irgendein MouseMotionListener hängt - wenn man die Maus zieht, wird irgendein Winkel geändert, und dann NUR auf der Dreregler-Component "repaint()" aufgerufen.
Wen das so ist, sollte das eigentlich kein Problem sein: Ganz allgemein: Wenn man sowas machen würde wie
Code:
for (int i=0; i<100; i++)
{
    repaint();
    waitFor10ms();
}
sollte allein schon nicht 100 mal neu gezeichnet werden - und in deinem Fall schon garnicht "alles", sondern nur der Bereich, der auch wirklich neu gezeichnet werden muss.

Was veranlasst dich zu der Annahme, dass er das komplette Bild 150 mal pro Sekunde neuzeichnet?
 

dvid85

Aktives Mitglied
hey, aber danke für den tipp! bei 20ms sleep läufts immernoch flüssig, aber es spart sicher ein paar repaints()
:)
 

André Uhres

Top Contributor
Mein Ansatz wäre jetzt, das Hintergrundbild in mehrere Teile zu zerlegen, damit nicht alles repaintet werden muss.
David, in "paintComponent" können wir das Rechteck, das aktualisieren muß mit "getClipBounds" abfragen. Der drawImage(..)-Aufruf kann dann so gemacht werden, daß er nur den Teil des skalierten Hintergrundbildes neu zeichnet, der sich mit dem Cliprechteck überschneidet:
Code:
            scaledImage = scaleImage(img, factor);
...
@Override
protected void paintComponent(final Graphics g) {
    super.paintComponent(g);
    Rectangle r = g.getClipBounds();
    g.drawImage(scaledImage, r.x, r.y, r.width + r.x, r.height + r.y,
            r.x, r.y, r.width + r.x, r.height + r.y, this);
}
private Image scaleImage(final Image source, final double factor) {
    int w = (int) (source.getWidth(this) * factor);
    int h = (int) (source.getHeight(this) * factor);
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = (Graphics2D) img.getGraphics();
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.drawImage(source, 0, 0, w, h, null);
    return img;
}
Für den Hintergrund würde ich Clipping dringend empfehlen, zumal die paintComponent-Methode ziemlich einfach und schon fertig ist (siehe oben). Wenn eine Komponente neu gemalt werden muss, ruft das Toolkit für den Hintergrund automatisch repaint(..) mit den Argumenten auf, die nur das Rechteck definieren, das aktualisieren muß (und nicht die keine-Argumente-Version, die die gesamte Komponente veranlasst, neu gezeichnet zu werden).
 
Zuletzt bearbeitet:

dvid85

Aktives Mitglied
André,
wow, das ist sehr interessant! Weiterhin benutzt du ein BufferedImage. Ist das auch von Vorteil für mich, bzw sogar dringend empfehlenswert? Ich benutze immer ein normales Image, dass ich über die Media-Tracker-Methode lade.
 

Marco13

Top Contributor
Das BufferedImage bekommt man praktisch ganz "nebenbei", wenn man das Image (und mit dieser nicht wörtlich sondern als Code ausformulierten Empfehlung hat Andre ganz recht) nur EINmal skaliert, und dann nurnoch die skalierte Version zeichnet - das ist u.U. deutlich schneller, als bei jedem zeichnen zu saklieren.

Aber je nachdem, wie genau du das Bild lädst, HAST du vielleicht schon ein BufferedImage, und weißt es garnicht.... ein BufferedImage ist auch ein Image, d.h. jedes Image, das du verwendest, könnte schon ein BufferedImage sein.
 

dvid85

Aktives Mitglied
also irgendwie ist das problem noch nicht behoben. aber es liegt ganz sicher NICHT an der gui.

auf einem anderen rechner läuft es sehr stabil ohne jegilche aussetzer.

auf dem problemrechner ist es so:

es läuft eine zeit lang sehr flüssig, aber dann kommt es zum hacken und währenddessen höre ich immer festplattengeräusche, die sonst nicht da sind.

vielleicht heap space probleme? oder was kann es noch sein?
kann man im programm selbst, praktisch während der laufzeit den heapspace erhöhen?
 

dvid85

Aktives Mitglied
ach gott, ist mir ja fast peinlich. ich weiß jetzt endlich was das problem ist. ziemlich lächerlich:
ich bin an nem mac und habe eingestellt, dass er den desktophintergrund wechselt. immer genau beim wechsel kommt dieses hacken :oops:

wie auch immer, das dürfte trotzdem ncht so sein. hab da wohl grad nen bug bei apple entdeckt.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
B viele JPanels auf JLayeredPane -> to SVG? AWT, Swing, JavaFX & SWT 15
H Viele ActionListener (MouseListener) - Performance AWT, Swing, JavaFX & SWT 24
L Ein Actionlistener für ein Textfeld, anstatt viele Actionlistener für ein Textfeld AWT, Swing, JavaFX & SWT 7
A JavaFX Sehr viele Exceptions bei Taschenrechner mit JavaFx AWT, Swing, JavaFX & SWT 2
M If für viele TextFields AWT, Swing, JavaFX & SWT 7
kaoZ Swing JMenuBar, Preferences, Properties... und viele andere lustige Dinge (Best Practice) AWT, Swing, JavaFX & SWT 15
K Viele Textfield mit Hilfe eines MousListener leeren - möglich? AWT, Swing, JavaFX & SWT 8
M Swing Erste Schritte mit der GUI, viele Probleme AWT, Swing, JavaFX & SWT 36
propra 2D-Grafik Beliebig viele Objekte auf einer Zeichenfläche zeichnen AWT, Swing, JavaFX & SWT 15
L unbestimmt viele JComboBox und ItemListener dazu erstellen AWT, Swing, JavaFX & SWT 2
P 2D-Grafik Viele Bilder zu einem Video AWT, Swing, JavaFX & SWT 3
Dit_ Wenn viele NebenFenster zum Locationsetzen das HauptFenster brauchen AWT, Swing, JavaFX & SWT 2
P SWT Composite und viele Labels AWT, Swing, JavaFX & SWT 10
R JTable für sehr viele Daten sehr langsam AWT, Swing, JavaFX & SWT 20
G Viele Fehler beim zeichen AWT, Swing, JavaFX & SWT 5
Z zu viele prozesse AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
D Wie viele Pixel welches Icon? AWT, Swing, JavaFX & SWT 4
TheJavaKid Lösung für zu Viele JMenuItems. AWT, Swing, JavaFX & SWT 4
T viele Canvas auf einem Panel und das GUI schmiert ab AWT, Swing, JavaFX & SWT 6
Starchild Beliebig viele Knöpfe AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben