I have a Scrollpane containing 5 Titledpanes(Categories) each containing 2 images. Height of each TitledPane is 200 in expanded state and 25 in collapsed state.
Here is the image :
I have a text field in which I can enter the number of the Image to be selected.
For example, If I enter "4", the scroll pane scrolls to the Image-4 in Category-2 as shown below.
I am able to achieve this by calculating the Vvalue of the scroll pane based on the height to be scrolled and total height of the content inside the scrollpane.
Here is the issue
In the above example, if Category-2 is collapsed, I have to "Expand" it and then move to Image-4.
I am doing this by using the following code algorithm : // Let the height of the scroll pane content with TitledPane-2 in collapsed state be (ht_ScrollPaneBefore = 825) and ScrollPane view port height be (ht_Viewport = 180). Let the ht of the scrollpane after expansion of TitledPane-2 be ht_ScrollPaneAfter which is calculated in step 3 in the following algorithm.
{
....
1. Expand TitledPane-2
2. Call applyCss() and layout() on the TitledPane to make the Expansion effective.(As addressed in the other query : https://stackoverflow.com/questions/26152642/get-the-height-of-a-node-in-javafx-generate-a-layout-pass)
3. Get the height of the total Content(ht_TotalContent) of the scroll pane with the expanded TitledPane-2.(ht_ScrollPaneAfter = 1000)
4. ****** Calculate the Vvalue based on (ht_TotalContent).(let it be Vvalue = 0.56) *****
5. Set the Vvalue to the scrollpane.
....
}
Issue
Since the expansion of the Titledpane is not yet applied "Visually" on the view, the Vvalue(0.52) is getting applied relative to ht_ScrollpaneBefore(800) which is leading to an incorrect scrolling ht as shown in the "Actual output" below.
Actual Output:
Expected:
Note: The ht of the scrollpane after the expansion of the TitledPane-2 is obtained successfully using the procedure described in the link: Get the height of a node in JavaFX (generate a layout pass). The Vvalue has been calculated based on ht_ScrollPaneAfter only not on ht_ScrollPaneBefore. The only problem here is the application of Vvalue is going wrong as the scroll pane view is not yet updated with the expanded TitledPane-2.
Code Sample :
private void scrollToImage() {
int imageNum = Integer.parseInt(textField.getText()); // Number entered in text field
int categoryNum = imageNum / 2 + imageNum % 2; // Which category the image number belongs to.
Bounds scrollViewBounds = mscr.localToScene(mscr.getBoundsInLocal()); // viewport bounds.
Platform.runLater(() -> {
System.out.println("Before: " + mvbx.getHeight());
titledPaneList[categoryNum - 1].setExpanded(true);
mvbx.applyCss();
mvbx.layout();
});
double scrollHt[] = {0.0};
//ht of the categories before selected image category.
for (int idx = 0; idx < (categoryNum - 1); idx++) {
scrollHt[0] += titledPaneList[idx].getHeight();
}
// check if the image is first/second image in the category.
int imageIdxInCategory = (imageNum % 2 == 0) ? 1 : 0;
// If the selected image is second image in the category,
// add the titlebar and first image ht to the scroll ht.
if (imageIdxInCategory > 0) {
scrollHt[0] += 25 //Title bar ht.
+ titledPaneList[categoryNum - 1].getInsets().getTop() // titled pane top insets
+ ((VBox) titledPaneList[categoryNum - 1].getContent()).getChildren().get(0).getBoundsInLocal().getHeight(); // ht of the first image
// Note: Since, my titledpane contains a vbox which contains the
// image number label and imageview,
// I am calculating the ht of the first vbox her in the above code.
}
Platform.runLater(() -> {
System.out.println("After: " + mvbx.getHeight());
double d_ScrollHtPerPix = 1
/ (mvbx.getHeight()
- (scrollViewBounds.getHeight() - mscr.getInsets().getTop() - mscr.getInsets().getBottom()));
mscr.setVvalue(scrollHt[0] * d_ScrollHtPerPix);
});
}
}
Output :
When the category of the selected image is collapsed,
Before : 825
After : 825
As u see, the height of the scrollpane content is same even after expanding the collapsed category.