Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Auto Resizing TableView to accommodate all rows without a scrollbar.

robbob-JavaNetNov 19 2015 — edited Nov 20 2015

So I have a TableView for which I want it to automatically resize its height to be just large enough to display all the rows and not require a vertical scrollbar. This is easy enough if all of the rows are the same height. However, We are using a custom CustomTableCellFactory, and a custom TableCell which is using a Text object to automatically wrap any text that is too long to fit in the cell. I have subclassed TableView and provided a custom Skin so that I could extend the flow class and get access to the row height of each cell. I have a listener tied to the items property in the table to then go and try to find the new size of all the rows via the getFlowPrefHeight() method. However, when this method is called, all the rows are present, but they are still set to their default size, and have their height has not been adjusted for the wrapped text.

I'm out of ideas on this one, but I'm hoping that I'm missing something obvious. Below is a screenshot of how our table looks (correctly sized), but as soon as rows are added a vertical scrollbar appears. Also below is a snippet of my subclass TableView, skin and virtual flow.

Any help would be greatly greatly appreciated.

Thanks,

-Rob

Untitled.png

/*

* To change this license header, choose License Headers in Project Properties.

* To change this template file, choose Tools | Templates

* and open the template in the editor.

*/

package com.lynden.glitter.table;

import com.sun.javafx.scene.control.skin.TableViewSkin;

import com.sun.javafx.scene.control.skin.VirtualFlow;

import java.util.List;

import javafx.application.Platform;

import javafx.beans.property.IntegerProperty;

import javafx.beans.property.SimpleIntegerProperty;

import javafx.beans.value.ChangeListener;

import javafx.collections.ObservableList;

import javafx.scene.control.Skin;

import javafx.scene.control.TableColumn;

import javafx.scene.control.TableView;

public class AutoSizingTableView<T> extends TableView<T> {

private TableViewSkinX\<T> skin;

private IntegerProperty visibleRowCount = new SimpleIntegerProperty(this, "visibleRowCount", 10);

public AutoSizingTableView() {

}

public AutoSizingTableView(ObservableList\<T> items) {

    super(items);

    TableColumn\<T, ?> tc = getColumns().get(3);

}

public void lc() {

    layoutChildren();

}

public IntegerProperty visibleRowCountProperty() {

    return visibleRowCount;

}

@Override

protected Skin\<?> createDefaultSkin() {

    skin = new TableViewSkinX\<T>(this);

    return skin;

}

/\*\*

 \* Skin that respects table's visibleRowCount property.

 \*/

public static class TableViewSkinX\<T> extends TableViewSkin\<T>  {

    public TableViewSkinX(AutoSizingTableView\<T> tableView) {

        super(tableView);

    }

    @Override

    public void updateTableItems(ObservableList\<T> oldList, ObservableList\<T> newList) {

        super.updateTableItems(oldList, newList); //To change body of generated methods, choose Tools | Templates.

        setProperties();

        handleControlPropertyChanged("VISIBLE\_ROW\_COUNT");

    }

    @Override

    protected void handleControlPropertyChanged(String p) {

        super.handleControlPropertyChanged(p);

    }

    /\*\*

     \* Returns the visibleRowCount value of the table.

     \*/

    private int getVisibleRowCount() {

        return ((AutoSizingTableView\<T>) getSkinnable()).getItems().size();

        //return ((AutoSizingTableView\<T>) getSkinnable()).visibleRowCountProperty().get();

    }

    /\*\*

     \* Calculates and returns the pref height of the for the given number of

     \* rows.

     \*

     \* If flow is of type MyFlow, queries the flow directly otherwise

     \* invokes the method.

     \*/

    protected double getFlowPrefHeight(int rows) {

        double height = 0;

        height = ((MyFlow) flow).getPrefLength(rows);

        return height + snappedTopInset() + snappedBottomInset();

    }

    protected void setProperties() {

        double height = computePrefHeight(0, 0, 0, 0, 0);

        getSkinnable().minHeightProperty().set(height);

    }

    @Override

    protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {

        return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset);

    }

    /\*\*

     \* Overridden to compute the sum of the flow height and header

     \* prefHeight.

     \*/

    @Override

    protected double computePrefHeight(double width, double topInset,

            double rightInset, double bottomInset, double leftInset) {

        // super hard-codes to 400 .. doooh

        double prefHeight = getFlowPrefHeight(getVisibleRowCount());

        //double prefHeight = getFlowPrefHeight(25);

        //Add pixels for the header row as well as the horizontal scroll bar.

        return prefHeight + getTableHeaderRow().prefHeight(width) + 10;

    }

    /\*\*

     \* Overridden to return custom flow.

     \*/

    @Override

    protected VirtualFlow createVirtualFlow() {

        return new MyFlow();

    }

    /\*\*

     \* Extended to expose length calculation per a given # of rows.

     \*/

    public static class MyFlow extends VirtualFlow {

        ChangeListener\<Number> listener;

        public MyFlow() {

        }

        protected double getPrefLength(int rowsPerPage) {

            List cells = getCells();

            System.out.println("Cell Count: " + cells.size());

            double sum = 0.0;

            int rows = rowsPerPage; //Math.min(rowsPerPage, getCellCount());

            for (int i = 0; i \< rows; i++) {

                sum += getCellLength(i);

            }

            return sum;

        }

    }

}

}

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Dec 17 2015
Added on Nov 19 2015
0 comments
2,349 views