Search code examples
javaswingjscrollpanejscrollbar

How to prevent JScrollBar from scrolling on certain events like page down?


I have a very large view of data. I want a scrollbar for the user, but I want to override the standard way that a scrollbar processes pressing the up and down arrows (or up and down keys on the keyboard), as well as clicking the track area which does a page up and page down. This is because the data is streamed into the view, and the model of a "min/max/value" for the JScrollBar won't work for this.

The standard way of processing these mouse or key events is that the scrollbar's value is adjusted by either the "unit increment" (the smaller value) or the "block increment" (the larger value). I don't want the scrollbar to change its value when clicked; I'd just like to receive an event saying "the user requested to scroll up by a block" or "the user requested to scroll down one unit." Does anyone know of a way to do this?

BTW, it appears that BasicScrollBarUI$TrackListener.mousePressed(MouseEvent) handles the click, and it always calls scrollbar.setValue(newValue). So I may be out of luck :(

Perhaps there is a way to do it with a SWT scrollbar?


Solution

  • I figured out how to do it. I give the scrollbar a custom UI that extends the default BasicScrollBarUI, but overrides the two important methods I need: scrollByBlock() and scrollByUnit(). It turns out I can call setValue() within those methods without messing up the event, if I need to.

    class MyUI extends BasicScrollBarUI
    {
        @Override
        protected void scrollByBlock(int direction)
        {
            System.out.println("scrollByBlock " + direction);
            // super.scrollByBlock(direction);
            scrollBar.setValue(scrollBar.getValue() + (direction * 10));
        }
    
        @Override
        protected void scrollByUnit(int direction)
        {
            System.out.println("scrollByUnit " + direction);
            // super.scrollByUnit(direction);
            scrollBar.setValue(scrollBar.getValue() + (direction * 3));
        }
    }