JavaFX - Adapt TableView height to number of rows
Asked Answered
W

1

21

I want my TableView's height to adapt to the number of filled rows, so that it never shows any empty rows. In other words, the height of the TableView should not go beyond the last filled row. How do I do this?

Warr answered 14/1, 2015 at 14:56 Comment(4)
I don't understand why people are voting to close this question on the basis of "unclear what you are asking" or "too broad". The question is clearly stated, and is quite specific. If you are voting to close, please comment and explain why.Pushkin
In my opinion, the question is perfectly clear to anyone who has worked with JavaFX (particularly with TableViews, but even without that). I note that none of those who voted to close has answered a single JavaFX question. "I am not familiar with that technology" is not really a reason to close a question. Voting to reopen...Pushkin
I usually do table.setPrefHeight( ); to get rid those empty rows out of my eyes XDEleanore
related question (with working answer, biased me ;), some might call this a duplicate - https://mcmap.net/q/525092/-tableview-adjust-number-of-visible-rowsStyrax
N
24

If you want this to work you have to set the fixedCellSize.

Then you can bind the height of the TableView to the size of the items contained in the table multiplied by the fixed cell size.

Demo:

@Override
public void start(Stage primaryStage) {

    TableView<String> tableView = new TableView<>();
    TableColumn<String, String> col1 = new TableColumn<>();
    col1.setCellValueFactory(cb -> new SimpleStringProperty(cb.getValue()));
    tableView.getColumns().add(col1);
    IntStream.range(0, 20).mapToObj(Integer::toString).forEach(tableView.getItems()::add);

    tableView.setFixedCellSize(25);
    tableView.prefHeightProperty().bind(tableView.fixedCellSizeProperty().multiply(Bindings.size(tableView.getItems()).add(1.01)));
    tableView.minHeightProperty().bind(tableView.prefHeightProperty());
    tableView.maxHeightProperty().bind(tableView.prefHeightProperty());

    BorderPane root = new BorderPane(tableView);
    root.setPadding(new Insets(10));
    Scene scene = new Scene(root, 400, 400);
    primaryStage.setScene(scene);
    primaryStage.show();
}

Note: I multiplied fixedCellSize * (data size + 1.01) to include the header row.

Nguyen answered 14/1, 2015 at 17:35 Comment(10)
hmm .. doesn't work for me (arbitrary factors are nearly certain to fail sooner or later ;)Styrax
What do you mean with "doesn't work"? A bit more details would be nice.. ;-)Nguyen
it's ways showing a vertical scrollbar (btw: if you forget the @somenick then somenick will not get a notification)Styrax
@Styrax Yeah that is the struggle to find the correct table header height. Seems like your header is large and / or your screens DPI made the header larger..Nguyen
@Nguyen It doesn't work with me. I'm getting IntegerBinding [invalid] when I debug Bindings.size(tableView.getItems()).Rozanna
@user3552551 the comments are the wrong place for this.. consider asking a new question describing your problem.Nguyen
@Nguyen Do you know why this works only after I set the items to the tableView? If I put this before it does nothing. While it is a binding, theoretically it should work isn't?Cheltenham
@Cheltenham you would be better off to ask a new question. But in short: The ìtems` of the TableView is an ObjectProperty containing an ObservableList so if you swap the entire list the binding is bound to a different list..Nguyen
@Nguyen Hmm, yes, that is why it didn't listens to getItems().size() because it changes at setItems(). After I read you answer I was pretty sure that it is working but when I tired I was wondering why not, and after experimenting a little bit I saw that it works doing after table.setItems(), but didn't know why, now it is clear thanks.Cheltenham
@fabian the TableViews computed preferred size does not respect the number of non-empty cells. And why should it? Thus the "hack".Nguyen

© 2022 - 2024 — McMap. All rights reserved.