6 Stimmen

Warum führt mein jscrollpane zu seltsamen Paint-Aufrufen in Java Swing?

Ich habe eine Routine, die ein wahnsinnig großes Diagramm innerhalb eines Bildlauffensters malt. Es ist zu groß, um es vor dem Hinzufügen zum Rollfenster zu malen - die Speicheranforderungen würden mehrere Gigabyte betragen.

Aufgrund der Größe des Diagramms rendere ich das Diagramm innerhalb der Paint-Methode des Scrollpane's Kind. Was gut funktioniert, aber ich bemerke, dass jedes Mal, wenn eine Bildlaufleiste bewegt wird, meine Malroutine zweimal aufgerufen wird - einmal mit einem Clipping Rect gleich dem unbedeckten Bereich gescrollt, und ein zweites Mal mit dem Clipping Rect gleich den Dimensionen des Viewports.

Zum Beispiel, wenn mein Viewport 245x195 ist und ich um 3 Pixel nach unten scrolle, wird meine Malroutine aufgerufen mit g.getClipBounds() wie folgt eingestellt:

java.awt.Rectangle[x=0,y=195,width=245,height=3]
java.awt.Rectangle[x=0,y=3,width=245,height=195]

... weil ich innerhalb der Malroutine rendere, verursacht dies ein Flimmern (ich mache meine Berechnungen so schnell wie möglich, aber es gibt eine kleine Verzögerung, denke ich). Fragen:

  1. Weiß jemand, wie man den 2. Farbaufruf verhindern kann? Das ist ganz normales JScrollPane-Zeug, das ich hier mache - ich habe eine Komponente, ich füge sie zum Scrollpane hinzu, ich füge das Scrollpane zu einer übergeordneten Komponente hinzu. Sie können dieses Verhalten sogar in der ersten Demo zum Scrollen von Bildern sehen @ die Schaukel-Anleitung .

  2. Wenn die Antwort auf Frage 1 "nein" lautet: Fällt jemandem ein guter Weg ein, damit umzugehen? Sollte ich malen, um eine Art von Bild-Puffer, verfolgen die letzten Paint-Aufrufe und kopieren Sie das Bild, wo möglich? Ich kann mir nicht vorstellen, dass dies viel schneller ist als ein erneutes Rendern, aber ich bin für jeden Einblick dankbar :-)

4voto

colithium Punkte 10159

Ich habe in dieses Problem in der .NET-Welt lief. Doppelte Pufferung sollte Ihr Problem lösen.

Wenn Sie direkt auf eine Oberfläche rendern, die auf dem Bildschirm angezeigt wird, haben Sie keine Kontrolle darüber, wann die "Anzeige" tatsächlich erfolgt. Normalerweise geschieht Folgendes: Sie beginnen mit dem Rendering, das noch nicht fertige Bild wird auf dem Bildschirm angezeigt, Sie beenden das Rendering, und dann wird es schließlich auf dem Bildschirm angezeigt.

Wenn Sie Ihre Rendering-Logik mit dem Löschen einer Hintergrundfarbe beginnen, erscheint diese wie ein Blitz. Durch die doppelte Pufferung wird dies verhindert, da immer ein abgeschlossenes Rendering angezeigt wird. Das Schlimmste, was passieren kann, ist ein leichtes "Tearing", aber das ist nur bei schnell wechselnden Animationen zu beobachten.

Auch wenn Sie nur einen Teil eines riesigen Bildes rendern wollen, können Sie diese Technik anwenden. Rendern Sie einfach das, was Sie brauchen, auf eine Fläche außerhalb des Bildschirms (die der Größe des gewünschten sichtbaren Teils entspricht). Wenn Sie damit fertig sind, zeichnen Sie das gesamte Bild auf einen Schlag auf Ihre Anzeigefläche.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X