3

I'm trying to develop a desktop app using javaFX (2.2), and I'm experiencing some difficulties to really get it to behave like I would like it to. Being a new user of the framework, I might not be using it as it should be...

What I want is a kind of dashbord, with several JavaFX or custom controls inside a ScrollPane. I currently have several views that look like this :

<AnchorPane id="userContent" xmlns:fx="http://javafx.com/fxml" fx:controller="squalp.view.OrgViewController">
    <children>
        <ScrollPane fx:id="scrollPane" styleClass="transparent" hbarPolicy="NEVER" vbarPolicy="AS_NEEDED" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <content>
                <VBox fx:id="vBox" styleClass="transparent" alignment="TOP_LEFT" focusTraversable="true">
                    <children>
                        <Label text="Label" />
                        <Button fx:id="bTest" text="Test" onAction="#test"/>
                        <TreeView fx:id="orgTree" focusTraversable="true" />
                    </children>
                </VBox>
            </content>
        </ScrollPane>
    </children>     
</AnchorPane>

As long as I keep using simple controls, no problem, items are correctly placed one after another in th VBox.

But when using TreeViews or TableViews, I can only get my controls to have fixed height, meaning extra space on the bottom, or new scroll bars, in addition to the main one. What I would like to achieve is to adapt my controls to their current content height.

Qt's QML, for exemple, has a childrenHeight property, and it's kind of what I'm looking for. I figure this content height must be calculated somehow, since components scrollbars do adapt to the content.

I had to use a workaround for tableviews :

table.setPrefHeight(list.size() * rowHeight + headerHeight);

but I couldn't find a way to track displayed items on a treeview.

Has anyone an idea of what I could be doing to handle this issue ? Or I am really not using the framework as I should ?

Thanks in advance.

EDIT : Visual description of the problem :

Case 1

Here my treeview's height is set to a default value. There are not enough items to fill the treeview : if I want to put another component below, there'll be a gap; if my scene is not big enough, the ScrollPane's scrollbar appears, even though all the displayable content is visible.

Case 2

If if expand my treeview's items, there are now too many of them. They are not all visible at once, and the treeview's scrollbar appears, even though I already have a scrollable view with the scrollpane.

What I would like is my TreeView to adapt to its content height (reduced height if items are collapsed, bigger height if they are expanded), in order to be able to put several components one after another and to scroll through them all using the ScrollPane's scrollbar.

Since the TreeView component has itself a scrollbar, its visible content's height must be calculated at some point (since scrollbars basically use ratios based on contentHeight/componentHeight). This information doesn't seem to be available in the public API, but I wonder if, developping a custom class that expands TreeView, there could be a way to bind my component to its "visible height".

claveault
  • 43
  • 1
  • 4
  • So you want that the tableview and treeview are showed their content without vertical scrollbar? – Uluk Biy Mar 13 '14 at 10:21
  • No, my goal is not to hide the scrollbar, but to bind the views heights to their content height (the sum of the cell heights, basically). – claveault Mar 13 '14 at 13:12
  • Visual description of the problem would be more helpful. Being a bit more specific about your question, like which node(s) do you want to resize/expand in which case, also would be helpful. – Uluk Biy Mar 13 '14 at 17:28
  • Ok! I edited my post : tried to be more specific on the problem and added some visual info. – claveault Mar 14 '14 at 08:34

3 Answers3

1

There maybe a proper way to achieve your goal, but I can suggest the approach similar to tableview's.

orgTree.prefHeightProperty().bind(orgTree.impl_treeItemCountProperty()
        .multiply(treeRowHeight)); // treeRowHeight maybe 24.

Note that this is only a workaround where the deprecated and internal use-only method is used, which maybe removed in future releases.

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
1

I was looking for way to make TreeView auto-resize to fit its content, e.g. when a node is expanded or collapsed. Here's what I eventually do. Note the Platform.runLater() is required, thus simple property binding would not work here. Also note the cellHeight is the height of a tree node. It's beyond the scope of the question here how to get that.

treeView.expandedItemCountProperty().addListener((obs, oldV, newV) -> {
    Platform.runLater(() -> {
        treeView.setPrefHeight(newV.intValue() * cellHeight);
    });
});
Ling_2008
  • 11
  • 1
  • This works well for me in both tree view and tree table views. I was trying to set the property binding of prefHeight to the expandedItemCountProperty multiplied by an estimated cell height, but this never updated until the view received another input. This suggestion by Ling works nicely. – Snibbor May 28 '22 at 15:01
0

You can use the binding property of the view to the childs height property. By this, whenever the height of the Parent changes, childs height will automatically change ! This is not automatic height adaption, like you want, but a forced adaption, which will help you !

Width property is also available

Basically this is a snippet that will help you :

pane.heightProperty().addListener(new ChangeListener<Number>() {
    @Override
    public void changed(ObservableValue<? extends Number> arg0,
                                 Number oldValue, Number newValue) {
        table.setPrefHeight(newValue - 200);/*The difference of height between 
                                             parent and child to be maintained*/    
    }
});
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
  • Thanks for your answer. It is usefull indeed to adapt a node to its pane dimensions. But since I wish to use a scrollPane as "root" layout, I'm not trying to fit the nodes to the layout, but to expand them in order to see all their visual content, even if it causes the node to be bigger than the scrollpane. – claveault Mar 13 '14 at 15:45