2

I can trivially create a scroll pane in JavaFX that only scrolls horizontally like so:

ScrollPane scroll = new ScrollPane(lcp);
scroll.setPannable(true);
scroll.setFitToHeight(true);
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

However, the mouse scroll wheel still tries to scroll vertically rather than horizontally in this case (unless I specifically scroll over the horizontal scroll bar.)

How can I set up the scroll pane so that the mouse wheel pans horizontally?

Michael Berry
  • 70,193
  • 21
  • 157
  • 216

2 Answers2

4

Here is the example application that I wrote for you and does exactly what you want:

public class Test extends Application {

    ScrollPane scrollPane;
    int pos = 0;
    final int minPos = 0;
    final int maxPos = 100;

    @Override
    public void start(Stage primaryStage) {

        Label label = new Label("TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT");
        label.setPrefSize(500, 100);
        label.setOnScroll(new EventHandler<ScrollEvent>() {
            @Override
            public void handle(ScrollEvent event) {

                if (event.getDeltaY() > 0)
                    scrollPane.setHvalue(pos == minPos ? minPos : pos--);
                else
                    scrollPane.setHvalue(pos == maxPos ? maxPos : pos++);

            }
        });

        scrollPane = new ScrollPane();
        scrollPane.setHmin(minPos);
        scrollPane.setHmax(maxPos);
        scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
        scrollPane.setHbarPolicy(ScrollBarPolicy.ALWAYS);
        scrollPane.setPannable(true);
        scrollPane.setFitToHeight(true);
        scrollPane.setContent(label);

        BorderPane root = new BorderPane();
        root.setPrefSize(200, 100);
        root.setCenter(scrollPane);

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }

}
Ugurcan Yildirim
  • 5,973
  • 3
  • 42
  • 73
  • Thanks, `setOnScroll()` is what I needed - is there a way however to make the scrollpane scroll a constant amount irrespective of the width of the component? As the scrollpane content grows in width, simply adding / removing a fixes value will scroll it by a percentage of its width rather than (say) 50 pixels each time. – Michael Berry Sep 13 '15 at 01:19
  • Everytime the content of scrollpane changes, you can set the "Hmax" value (maxPos) accordingly, probably to the content width. This will make the scrolling amount independent from the content width. – Ugurcan Yildirim Sep 13 '15 at 01:25
  • Thanks, that did the trick - should have spotted it earlier really! Clearly having a slow day... :) – Michael Berry Sep 13 '15 at 16:56
3

I have also been looking for a solution and found this one from Ugurcan Yildirim but didn't like the fact that the natural scroll bar length and speed is modified also. This one worked for me:

scrollPane.setOnScroll(event -> {
    if(event.getDeltaX() == 0 && event.getDeltaY() != 0) {
        scrollPane.setHvalue(scrollPane.getHvalue() - event.getDeltaY() / this.allComments.getWidth());
    }
});

event.getDeltaX() == 0 just to be sure that the user is only using the mouse wheel and nothing is adding up

this.allComments is the content of the scrollPane (a HBox in my case). By dividing the delta y value by it's content width the scroll speed is natural according to the amount of content to scroll.

Renats Stozkovs
  • 2,549
  • 10
  • 22
  • 26