views:

144

answers:

2

Hello,

I want to have a JEditorPane inside a JScrollPane. When the user clicks a button, the click listener will create a textEditor, call jscrollpane.setViewPort(textEditor), call textEditor.setText(String) to fill it with editable text, and call jscrollpane.getVerticalScrollBar().setValue(0). In case you're wondering, yes, the setText() must come after the setViewPort() for reasons that aren't on topic.

Here is the problem: After the user clicks the button, the JScrollPane's view scrolls all the way to the bottom. I want the scrollbar to be at the top, as per the last line in my click listener.

I popped open a debugger, and to my horror, discovered that the jscrollpane's viewport is being forced down to the bottom after the conclusion of the click listener (when pumping filters). It appears that Swing is delaying the population of the editor/jscrollpane until after the conclusion of the clicklistener, but is calling the scrollbar command first. Thus, the undesired behavior.

Anyway, I'm wondering if there is a clean solution. It seems that wanting a scrollpane to be scrolled to the top after modification would be a reasonably common requirement, so I'm assuming this is a well-solved problem.

Thanks!

+1  A: 

Ok, it amazes me how I always figure out the answer fractions of a second after posting.

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        pane.getVerticalScrollBar().setValue(0);
    }
});

This allows the scrolling action to be delayed until after the other task completes. Question: is this good style/reliable or is it just a race condition? Can I depend on this working?

Jim
@Konrad Garus' idea is better, but actions on the EDT will be in program order. http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html
trashgod
I would avoid solutions that use invokeLater, there's usually a better way.For example, one drawback of invoke later is that there might be a repaint after setting the invokeLater and it actually running. This can produce flicker on screen if the look of a component is changed.
Keilly
+1  A: 

You could use JEditorPane.setCaretPosition(0).

Konrad Garus