2

I realize there are other posts about this, but this is not a duplicate.

If I use the following code to hide the horizontal scrollbar from a TableView, there still is 1 or 2 pixel area at the bottom of the table, from which the user can scroll the TableView horizontally --- with the mouse wheel (SHIFT+mouse wheel also works, from anywhere in the table area).

.table-view *.scroll-bar:horizontal *.increment-button,
.table-view *.scroll-bar:horizontal *.decrement-button {
    -fx-background-color: null;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-padding: 0;
}

.table-view *.scroll-bar:horizontal *.increment-arrow,
.table-view *.scroll-bar:horizontal *.decrement-arrow {
    -fx-background-color: null;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-padding: 0;
    -fx-shape: null;
}

I tried some reflection hacks to access the scrollbar and attempt to disable it that way, with no success. Anyone have ideas?

EDIT - here's a minimal example, for me it's always reproducible on Win 10, JavaFX 12.0.1.

Test.java:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * Horizontal scrolling via mouse wheel is possible when you place the cursor at the bottom of the window, just above the resize-area.
 */
public class Test extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<String> table = new TableView<>();

        table.getColumns().add(new TableColumn<>("first"));
        table.getColumns().add(new TableColumn<>("second"));
        table.getColumns().add(new TableColumn<>("third"));
        table.getColumns().add(new TableColumn<>("fourth"));
        table.getColumns().add(new TableColumn<>("fifth"));
        table.getColumns().add(new TableColumn<>("sixth"));
        table.getColumns().add(new TableColumn<>("seventh"));
        table.getColumns().add(new TableColumn<>("eighth"));
        table.getColumns().add(new TableColumn<>("ninth"));
        table.getColumns().add(new TableColumn<>("tenth"));

        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

//        table.addEventFilter(ScrollEvent.ANY, Event::consume);

        ObservableList<String> data = FXCollections.observableArrayList();
        for (int i = 0; i < 5000; i++) {
            data.add("foobar");
        }
        table.setItems(data);

        StackPane root = new StackPane();
        root.getChildren().add(table);

        Scene scene = new Scene(root, 300, 250);

        scene.getStylesheets().add("test.css");

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(Test.class);
    }
}

Test.CSS:

.table-view .scroll-bar * {
    -fx-min-width: 0;
    -fx-pref-width: 0;
    -fx-max-width: 0;

    -fx-min-height: 0;
    -fx-pref-height: 0;
    -fx-max-height: 0;
}
user38725
  • 876
  • 1
  • 10
  • 26
  • 1
    Possible duplicate of [JavaFX: How to disable ScrollBars in TableView](https://stackoverflow.com/questions/55093764/javafx-how-to-disable-scrollbars-in-tableview) – Slaw Jun 26 '19 at 08:42
  • `table.addEventFilter(ScrollEvent.ANY, Event::consume);` does work. However I don't want to disable vertical scrolling, and `getDeltaX()` always returns 0 and thus the TableView is still horizontally scrollable via the 1 pixel at the bottom. – user38725 Jun 26 '19 at 08:57
  • The CSS in my answer should remove all traces of the scroll bar (currently both horizontal and vertical, but you can change that by specifying the appropriate pseudo class). – Slaw Jun 26 '19 at 09:05
  • I tried your CSS too, but the problem persists: there's still 1 pixel area at the bottom from which the user can scroll via mouse wheel. And it's vertically scrollable via mouse wheel too -- from anywhere -- even though the scrollbars aren't showing. – user38725 Jun 26 '19 at 09:22
  • Hmm. I can't reproduce the 1 pixel area, as far as I can tell. And even with 1 pixel of scroll bar showing, the event filter should prevent it from being usable. And I'm not sure I understand the problem with the vertical scrolling—thought you said you _don't want_ to disable vertical scrolling. – Slaw Jun 26 '19 at 09:40
  • Yes sorry I just stated obvious there --- i _don't_ want to disable vertical scrolling. I can reproduce this in a simple test application and it's a problem in my own larger application too. (JavaFX 12) – user38725 Jun 26 '19 at 09:44
  • 1
    Can you add a [mre], possibly with a GIF showing the problem? I'm using JavaFX 12.0.1 (on Windows 10) but can't seem to reproduce the problem, though I may just be missing it. – Slaw Jun 26 '19 at 10:08
  • I added a minimal test case. – user38725 Jun 26 '19 at 11:46
  • Adding `-fx-translate-y: 5px;` (the `5px` was arbitrary) seems to workaround the problem (using `.table-view .scroll-bar:horizontal *` as a selector). – Slaw Jun 26 '19 at 20:32

1 Answers1

2

If you don't want to go for the css solution then you can do this way

public static <T extends Control> void removeScrollBar(T table) {
        ScrollBar scrollBar = (ScrollBar) table.queryAccessibleAttribute(AccessibleAttribute.HORIZONTAL_SCROLLBAR);
        /*
         *This null-check is for safety reasons if you are using when the table's skin isn't yet initialized.
         * If you use this method in a custom skin you wrote, where you @Override the layoutChildren method,
         * use it there, and it should be always initialized, so null-check would be unnecessary.
         *
         */
        if (scrollBar != null) {
            scrollBar.setPrefHeight(0);
            scrollBar.setMaxHeight(0);
            scrollBar.setOpacity(1);
            scrollBar.setVisible(false); // If you want to keep the scrolling functionality then delete this row.
        }
    }
Sunflame
  • 2,993
  • 4
  • 24
  • 48