Conditionally autoscroll a JScrollPane
I’m currently developing some GUI stuff and was wondering how to let a JScrollPane scroll automatically if it’s already on the bottom and the size of it’s content increases.
For example if you use a JTextArea to display some log or whatever, than it would be nice if the scroll bars move down while there are messages produced, but it shouldn’t scroll down when the user just scrolled up to read a specific line. To scroll down to the end of a JTextArea can be done with just setting the carret to the end of the text:
But we first want to check whether the scroll bar is already at the bottom, and only if that’s the case it should automatically scroll down to the new bottom if another message is inserted. To obtain the position data of the vertical scroll bar on can use the following code:
Unfortunately log.append ("some msg")
won’t append the text in place, so the size of the text area will not necessarily change before we ask for the new maximum position. To avoid a wrong max value one can also schedule the scroll event:
As you can see, here a new event is put in the EventQueue, and this event is told to put another event in the queue that will do the scroll event. Correct, that’s a bit strange, but the swing stuff is very lazy and it might take a while until the new maximum position of the scroll bar is calculated after the whole GUI stuff is re-validated. So let’s be sure that our event definitely happens when all dependent swing events are processed.
Leave a comment
There are multiple options to leave a comment:
- send me an email
- submit a comment through the feedback page (anonymously via TOR)
- Fork this repo at GitHub, add your comment to the _data/comments directory and send me a pull request
- Fill the following form and Staticman will automagically create a pull request for you:
1 comment
Thanks for the post, it was very useful to me. But when i tried to implement it i ran into some trouble because the scroll bar wouldn’t follow the incoming data. It turned out that i had to add to the current position the value of the visible part of the scroll bar like:
int currentpos =vbar.getValue() +vbar.getVisibleAmount();
Once i did this it worked just fine. Thanks again for the post.