views:

1218

answers:

2

I have this JTextPane (wrapped in a JScrollPane) that is backed by a HTMLEditorKit. The contents of the JTextPane is simple HTML with some images (local files) embedded using img tags. The problem is that when you load the the JTextPane, it takes a split second to load and then it comes up with the scroll bar at the bottom of the page. If I do:

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

it sets the scroll bar momentarily and then another thead (presumably that is in charge of loading the images) comes and knocks the scroll bar back to the bottom. I tried adding:

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

but that did not fix it. Is there any way to get an event from either text.getDocument() or text that will notify me when the pane is finished loading so that I can set the scroll bar then? The alternative is that I set up another thread to wait a second or so, and then set the scroll bar, but this is a bad hack.

Your suggestions?

A: 

Is your app single threaded by any chance? If it is you can request a list of running threads and get notified when they finish and then set the scrollbar value. Is that an option?

Or you can provide an ImageObserver to every image loaded and set the position of the scrollbar when all images are reported loaded?

Savvas Dalkitsis
Swing applications rely on a thread called the Event Dispatch Thread to control all GUI actions. You can get around this if you need to, but all the work I am doing right now is on the Event Dispatch Thread. This could be considered an option, but is probably just as bad a hack as what I proposed in my question. I will keep it in mind though.
twolfe18
the ImageObserver might work then...
Savvas Dalkitsis
+2  A: 

Have you tried using invokeLater?

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

If that doesn't work, digging into the image views is pretty tough so my next step would be to track down why the scrollbar is changing:

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

You could also use a debugger in the setValue() method instead of just printing the stack trace.

Spyder