1

I have a JavaFX TableView and I would like the table behavior to truncate the image of the TableView when the parent node resizes too small to display the data, instead of it becoming scrollable. To clarify, I just want the scroll bars disabled or not visible, so they don't show up.

Below is my node hierarchy in SceneBuilder in case that helps.

enter image description here

Things I've tried below

I read this post, but the answer just makes the cells resize to fit the width, instead of disabling the ScrollBar. I read the documentation on ScrollBars here, but I couldn't find a visible or enabled property. I also read the TableView documentation here with no luck.

I searched the JavaFX CSS guide here and found that there are the two policies below that can refer to a scroll pane.

-fx-hbar-policy:
-fx-vbar-policy:

But wrapping the TableView in a ScrollPane did not work as expected. It did not allow me to "fit-to-parent". I would like to refer to these properties, but in a TableView directly if that's possible. Any suggestions are greatly appreciated.

geekTechnique
  • 850
  • 1
  • 11
  • 38
  • I'm not sure on this, but could you use a `lookup()` on the `TableView` to access the `ScrollBar` directly? `ScrollBar scrollBar = (ScrollBar) tableView.lookup(".scroll-bar:vertical");` and then disable it? – Zephyr Mar 11 '19 at 00:35
  • "_but I couldn't find a setVisible() or setEnabled() property_". `ScrollBar` inherits from `Node` which provides the `visible` and `disable` properties. And unfortunately the `ScrollBarPolicy` enum is specific to `ScrollPane` whereas controls like `TableView` have their `ScrollBar`s created as part of the `VirtualFlow`. As far as I know, there is no public API allowing one to configure the `ScrollBar`s of a `TableView` to never show. – Slaw Mar 11 '19 at 00:45
  • @Zephyr I tried this, and I am able to apply .setDisable(true); to the scrollbar. However, that only makes the scrollbar gray out, and appear like a disabled button, but it is still visibly there and functioning. I am about to try setVisible, and some other things. I am just writing this to confirm that the lookup did work to a degree and communicate with you. Still trying to make this work myself in the mean time. Thank you for advancing me so far towards my goal. – geekTechnique Mar 11 '19 at 01:10
  • @Slaw Thank you so much for the clear explanation. I am not terribly familiar with VirtualFlow, just now reading about it as I am still new to javafx, and I understand why I can't configure it directly. Your input is very useful, as always. – geekTechnique Mar 11 '19 at 01:12
  • 1
    There's a feature request, [JDK-8090721](https://bugs.openjdk.java.net/browse/JDK-8090721), asking for a public/supported way to hide the scroll bars of a `TableView` but it hasn't been implemented as JavaFX 11.0.2. – Slaw Mar 11 '19 at 01:26

1 Answers1

7

Hiding the scroll bars completely, whether they're "supposed" to be displayed or not, can be achieved with the following 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;
}

If you want to disable all scrolling then you can add an event filter to the TableView:

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

// or if you only want to disable horizontal scrolling
table.addEventFilter(ScrollEvent.ANY, event -> {
    if (event.getDeltaX() != 0) {
        event.consume();
    }
});

If you don't want the TableView to shrink when the parent gets too small, set the min size to use the pref size:

table.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);

If you don't want the TableView to grow beyond its pref size, do the same with the max size. You can also give an explicit pref size if you want.

Slaw
  • 37,820
  • 8
  • 53
  • 80
  • The comprehensiveness of this answer is fantastic, but I have one small question regarding the css. I have multiple tables, and I would like to scroll in the others. If I wanted to refer to just one TableView, and the css-id for it was firstTable, how would I do that? I tried preceding the block with ".firstTable", but there is clearly something I don't understand yet about javafx css beyond referring to certain id's. Thanks for being so helpful! – geekTechnique Mar 11 '19 at 05:17
  • 1
    If `"firstTable"` is the _id_ then you should use `#firstTable`. All together it'd look like `#firstTable .scroll-bar * { ... }`. JavaFX-CSS is [based on](https://openjfx.io/javadoc/11/javafx.graphics/javafx/scene/doc-files/cssref.html#introscenegraph) CSS 2.1 and some CSS 3, along with some custom features; the linked document provides links to the CSS reference pages. – Slaw Mar 11 '19 at 05:29
  • You can also use `.table-view .scroll-bar * {-fx-min-width: 0; -fx-pref-width: 0; -fx-max-width: 0;}` to get only the vertical scroll bar, and vice versa for only the horizontal scroll bar. I know it's counterintuitive, but it won't work if you use it the other way. (P.S. I can't get the code formatting correct here in the comments; I suggested an edit to the answer for this but it was rejected.) – Tech Expert Wizard Dec 06 '20 at 19:42