Panel scrollToBottom()

I am trying to implement a auto scrolling log file viewer using Scrollable Panel which contains a Label component to hold the text and a hidden refresher component on the client side to pull the latest text content and updates the lable component inside the panel.

Everything seems to be working fine except the auto scrolling part.

What I want is:

  • The panel should behave like unix tail command. When log file gets updated on server side I pull the latest content and append to the Panel…But when the Panel view area fills up, I want the Scroll bar to show up and automatically get scrolled down so that the latest added content shows up.

  • Eventually the scroll bar stays at the bottom of the panel always and old content gets scrolled up and only latest content is visible.

I tired to implement this as follows

  • First of all it would be nice if there was a scrollToBottom() function on Panel that did this job for me

  • Since that is not there, I tried to use the setScrollTop(getScrollTop()). But all this does is keep the text scrolled to the last postion it was in even while new content is getting added into the panel. This is useful, but not what I want.

  • I tried setting scroll top to a very high value 99999, as suggested by some members on forum. But that is not working at all. The scroll bar does not scroll at all. It seems setScrollTop() will ignore if a value is provided that is larger than the actual height(in pixels) of the component(s) that the panel contains.

  • I then tried setting scrollTop to exact height(in pixels) of the text that the panel holds each time. But it was not not easy to calculate this. I approximated , via visual inspection that my 540px Panel holds 27 lines of text. So based on this I recalculate the new number of lines, and hence the actual height in pixels of the whole text. But the approximation does not work exactly, and the scroll bar does not go all the way down…Some times it is 2-3 lines above the bottom, some times even higher…I could not figure out why this is happening or if there is a flaw in my way of approximating the actual height of text

Is there a better way to do this???

I read in another post that there is talks of implementing scrollToComponent() function …How is that coming? If that were there, I could easily add a ‘marker’ component at the bottom of my ‘text’ component (label) and always scroll down to that marker component whenever I update the text and refresh the panel.

Even better than this is the ‘scrollToBottom()’ function that I mentioned. Can this be implemented please?

Thanks!

If I remember correctly at all, you should also call Panel.setScrollable() to make the scrolling work properly. And setting a very large scrollTop should work, at least it has worked as far as I remember.

And as a matter of fact, this topic has come up earlier, and I created an example of it then:
panelscrolling @ uilder
(click “show source” the to see how it’s done)

Works fine in Safari/OSX.

Hi Jouni,

It was one of your posts that I came across and tried the very high setting (99999) that you suggested. I am also already setting setScrollable(true). I have been testing on IE 7 and Firefox 3.5.6 . Haven’t tested on safari.

I am wondering if this is a recent fix that is now ignoring abnormally high values passed into setScrollTop().

I am doing very similar to what your example source code shows…only difference is that I am using just a single Label Component whose ‘value’ I reset every time I have new text to be displayed. And each time I setScrollTop(99999).

So initially my Label has text which contains only one line, then 2 lines…then 100 lines …so on . And also every update does not necessarily increment the Label text with one additional line only…sometimes I can get more lines as a batch from the server side logs. Each time I completely reset the Label component with entire new text (with more and more lines as time progresses).

Should I instead use one Label per one line of log file text, and keep on adding Label Components to the Panel?

I think that may not be very scalable since if there are thousand lines, then there will be 1000 Label Components in the Panel and ‘refreshLayout()’ will start to suffer in performance…

I will test your sample with one Label Component with 99 lines of text and see if it works. Will post again abt the result.

Thanks very much.

Ok. I tested your sample code with one Label set with text containing 99 lines. And it works.

Even in my application it works in the case where I do it the very first time. But if I am doing the ‘regular refresh’ with new data every time, then it does not work. Not sure why it is any different for ‘one time’ case versus, when I am updating the Label with new data and doing the same set of steps. This is the kind of use case one would require for a ‘live’ autoscroll to the bottom as new data gets added to the panel.

I would be glad if you have some time to cook up a working example for this.

meanwhile I am doing more investigation on my end as well. Will post any findings.

I’m having exactly your very same problem, trying to implement kind of a tail -f too (using 6.2.4 here) for our logs.

A scrollToBottom() method would be really great to have.

I believe that calling setScrollTop with a high value works, problem is that when you call it for a second time with the same high value, Vaadin believes it has not changed, so it doesn’t call requestRepaint() (see Panel.java circa line 448)

It seems that you can work around this problem by forcing a requestRepaint() after your call to setScrollTop().

I’m still not being able to scroll to the very bottom though, I keep adding Labels to a panel and my setScrollTop (Short.MAX_VALUE) followed by a requestRepaint() gets me to the label previous to the last one (has to be my problem).

BTW, I wonder what could be a really high value, Integer.MAX_VALUE seems to be too high and doesn’t work for me, Short.MAX_VALUE (32767) do work, but I’m curious to know what’s a safe high value to use.

PS.- Please take my comment with a grain of salt, I’m very new to this great Vaadin framework

Hi,
How about function to scroll down for table??
I have a table and I want after I added a new item to this table, the created item is selected and highlight and showed in the middle of the table. However, I dont know how to scroll down to that item.
Any help??

Hi, I found it anyway:
setCurrentPageFirstItemId()
Thanks.

Bump :slight_smile:

This would be really great. I tried to use a hack with javascript but it didn’t work. Some one got a workaround for this?

Uh, I solved this at last with a hack involving Refresher and doing requestRepaint() for the Panel.

See
this example
.

I’m not quite sure what the problem exactly is, but it seems to be in the client-side, somehow the scroll position is set before rendering the content (even though it’s set after rendering the content).

Here’s what I use, courtesy of Henri Kerola of Vaadin:


    private void scrollIntoView() {
        final VerticalLayout layout = (VerticalLayout)myPanel.getContent();
        if (getApplication() != null && layout.getComponentCount() > 0)
            getApplication().getMainWindow().scrollIntoView(layout.getComponent(layout.getComponentCount() - 1));
    }

I’ve tried several different methods and the scrollIntoView() solution above works well and seems to be the best way of doing this!

Thanks!

UI.getCurrent().getPage().getJavaScript().execute(“window.scrollTo(0,0);”);
Work fine.

Hi,

I’m not happy with the fact that 8 years after this thread was created we still don’t have a .scrollToBottom() (was what I was searching for on the 1st place)…

…but here I’m sharing my workaround. In combination with the great
SizeReporter add-on
, you can add a ComponentResizeListener for the component, listen for the height when it changes and then do a .setScrollTop(listenedNewHeight).

There are also about 3000 open issues for the framework project alone in GitHub. With a small team addressing them as well as new issues coming in all the time, it is absolutely impossible to fix all of them. Furthermore, many are not even relevant anymore for various reasons, and it is sometimes hard for the team to know this. The same team also maintains a number of other related projects, each with its own issues and priorities, and tries to produce as much value as possible for as many people as possible.

In this particular case, it seems nobody ever made an enhancement request about this in GitHub, so it is pretty much guaranteed that the requests for it in the forum drown in the noise of other posts, and have an even lower priority than those 3000 bug reports and enhancement requests.

(I considered creating one myself, which would have taken less time than writing this reply, but as I don’t know the actual current use cases you have for it and I would be the only one getting notifications about it, it is better someone who actually needs it describes his or her use case.)

Once there is an issue, if you can’t wait for the team to get around to it, the fastest ways to get it going forward are either to make a pull request (and be prepared to go through a few rounds of review and changes) or to get a
support subscription
and use paid support hours to have our support team implement it. In the meanwhile, published workarounds are of course very helpful for others who may run into the issue.

I didn’t mean to be rude, Henri.

Just wanted to share my workaround but in the intro I couldn’t avoid my little usual amount of rant.

Buying a subscription doesn’t really depend on me, so while you allow me to stay here I’ll try to be as collaborative as I can, sharing my thoughts and discovers with everybody…

In this case it’s easier and quickier for me to go ahead with my own workaround. But at first time I was surprised to discover at first glance that there weren’t bottom and right methods in the Scrollable interface while we had left and top ones. I thought it would have been easy to suspect that use cases would soon arise in this scenario…

What I’m trying to accomplish is something similar to what the original poster wanted to do. Instead of filling a log window, my case is a chat window where chat messages are appended to the existing content of the windows (pretty much like the ones you have on this page asking if “may I help you?”). If content is taller than container window, a scroll bar appears. I want this scroll bar to get automatically scrolled in order to make visible the new message each time a new one appears.