2009-07-22 8 views
6

Ich habe diese JTextPane (in einem JScrollPane verpackt), die von einem HTMLEditorKit unterstützt wird. Der Inhalt der JTextPane ist einfach HTML mit einigen Bildern (lokale Dateien) eingebettet mit Img-Tags. Das Problem ist, dass wenn Sie die JTextPane laden, dauert es einen Sekundenbruchteil zu laden und dann kommt es mit der Bildlaufleiste am unteren Rand der Seite. Wenn ich das tue:Einstellen der Bildlaufleiste auf einem JScrollPane

JTextPane text = new JTextPane(); 
JScrollPane scroll = new JScrollPane(text); 
// do some set up... 
scroll.getVerticalScrollBar().setValue(0); 

setzt die Bildlaufleiste für einen Moment und dann eine andere Thead (vermutlich ist, das verantwortlich für die Bilder des Ladens) kommt und klopft die Bildlaufleiste nach unten zurück. Ich habe versucht, hinzuzufügen:

((AbstractDocument)text.getDocument()).setAsynchronousLoadPriority(-1); 

aber das hat es nicht behoben. Gibt es eine Möglichkeit, ein Ereignis von text.getDocument() oder text zu erhalten, die mich benachrichtigt, wenn das Fenster geladen ist, so dass ich die Bildlaufleiste dann festlegen kann? Die Alternative ist, dass ich einen anderen Thread aufstelle, um eine Sekunde oder so zu warten, und dann die Bildlaufleiste einstelle, aber das ist ein schlechter Hack.

Ihre Vorschläge?

Antwort

20

Haben Sie versucht, mit invokeLater?

final JScrollPane scroll = new JScrollPane(text); 
javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     scroll.getVerticalScrollBar().setValue(0); 
    } 
}); 

Wenn das nicht funktioniert, in die Bildansichten zu graben ist ziemlich hart, so mein nächster Schritt aufzuspüren wäre, warum die Scrollbar verändert:

scroll.setVerticalScrollbar(new JScrollBar() { 
    public void setValue(int value) { 
     new Exception().printStackTrace(); 
     super.setValue(value); 
    } 
}); 

Sie auch einen Debugger verwenden könnte in der setValue() Methode, anstatt nur die Stack-Trace zu drucken.

+1

Erste Lösung funktioniert, danke. Warum auf der Erde gibt es keine Methode, dies einzustellen, ohne SwingUtilities aufrufen zu müssen? –

+3

Keine Ahnung. Ich denke, so wie es entworfen wurde, müssen Sie das JScrollPane erstellen, es dem Bildschirm hinzufügen und dann den Wert festlegen. Für mich ergibt das keinen Sinn. – Spyder

0

Ist Ihre App zufällig mit einem Thread verbunden? Wenn dies der Fall ist, können Sie eine Liste der laufenden Threads anfordern und sich benachrichtigen lassen, wenn sie fertig sind, und dann den Wert für die Bildlaufleiste festlegen. Ist das eine Option?

Oder Sie können eine Imageobserver zu jedem Bild liefern geladen und die Position der Scrollbar gesetzt, wenn alle Bilder geladen gemeldet werden?

+1

Swing-Anwendungen auf einem Thread verlassen, um den Event Dispatch Thread aufgerufen, um alle GUI Aktionen zu steuern. Sie können dies umgehen, wenn Sie müssen, aber die ganze Arbeit, die ich gerade mache, ist auf dem Event Dispatch Thread. Dies könnte als eine Option betrachtet werden, ist aber wahrscheinlich genauso ein schlechter Hack als das, was ich in meiner Frage vorgeschlagen habe. Ich werde es jedoch im Hinterkopf behalten. – twolfe18

+0

der ImageObserver könnte dann funktionieren ... –

1

Die folgende lösten das Problem für mich, nach 50 Minuten der Verzweiflung:

JTextPane.grabFocus(); 
JTextPane.setCaretPosition(20); 
Verwandte Themen