Search code examples
eclipseeclipse-rcpnattable

Scroll NatTable programmatically to the selected Row


I have an action which scrolls the NatTable to the selected Row. I tried to use the below snippet which works partially

natTable.doCommand(new ShowRowInViewportCommand(
natTable.getBodyLayer().getViewportLayer(), rowPosition+delta));

It works if I set the delta value to rowPosition+10. However, if the current scroll is at the bottom of the table, it doesnot scroll upto the row, it needs an extra scroll to see the selection. Logically I need to do rowPosition-10 to get the scroll up to the right location.

So, we need to find the scroll position is at end of table or beginning of table and then set the rowPosition+10 or rowPosition-10 accordingly. Is there a way to find the current scroll position??

This is similar to the question Scroll NatTable programmatically here. Unfortunately dont have reputation to comment and hence creating a separate thread for this question.

Appreciate if anyone has solved this issue could post the answer.

Thank you.


Solution

  • I've just run into the same situation as the original poster. What I came to realize after playing around with this for a while is that the ShowRowInViewportCommand is going to "Scroll" the viewport as minimally as possible to make the row visible. One of three pre-conditions will be true:

    • (A) The target row is already visible (in which case nothing will happen and the visible target row remains where it is);
    • (B) The target row is below the viewport (in which case the viewport is scrolled down so that the target row is at the bottom of the viewport)
    • (C) The target row is above the viewport (in which case the viewport is scrolled up so that the target row is at the top or the viewport).

    In my use case I wanted the target row to be positioned in the center of the viewport if it was not currently visible (or left where it is if it is visible).

    To do this I was calculating the index of the object that should be in the top row of the viewport and issuing the doCommand(). This worked fine for case (C), but failed for (B). The fix was simply recognizing if the viewport was going to go up or down and then calculating the correct top or bottom index accordingly.

    The direction of the scroll can be determined by code akin to (where dataIndex is the index of the row (within my base data set) that I want to make visible:

    int viewportPosition = bodyLayerStack.viewportLayer.getRowPositionByIndex(dataIndex);
    int viewportHeight = bodyLayerStack.viewportLayer.getRowCount();
    boolean isVisible = (viewportPosition >= 0) && (viewportPosition < viewportHeight);
    if (!isVisible) {
            if (viewportPosition < 0) {
                /*
                 * The target row is below the viewport window so we want to calculate the
                 * index of the bottom of the table.
                 */
                viewPortTargetPosition = dataIndex - (viewportHeight / 2) + columnHeaderLayer.getRowCount();
                viewPortTargetPosition  = Math.max(0, viewPortTargetPosition);
            }
            else {
                /*
                 * The target row is above the viewport window so we want to calculate the
                 * index of the top row to show in the viewport.
                 */
                viewPortTargetPosition = Math.min(dataIndex + (viewportHeight / 2) - 1, bodyLayerStack.bodyDataLayer.getRowCount()-1);
            }
    
        natTable.doCommand(new ShowRowInViewportCommand(bodyLayerStack.viewportLayer, viewPortTargetPosition));
            return true;
    }