JavaFX同步滚动窗格内容更改及其Vvalue

JavaFX同步滚动窗格内容更改及其Vvalue,javafx,javafx-8,Javafx,Javafx 8,我有一个滚动窗格,包含5个标题窗格(类别),每个标题窗格包含2个图像。每个标题窗格在展开状态下的高度为200,在折叠状态下的高度为25 图为: 我有一个文本字段,可以在其中输入要选择的图像的编号 例如,如果我输入“4”,滚动窗格将滚动至类别2中的图像-4,如下所示 我可以通过基于要滚动的高度和滚动窗格内内容的总高度计算滚动窗格的V值来实现这一点 问题就在这里 在上面的例子中,如果类别2被折叠,我必须“展开”它,然后移动到图像4 我使用以下代码算法来实现这一点: //将标题为pane-2的滚动

我有一个滚动窗格,包含5个标题窗格(类别),每个标题窗格包含2个图像。每个标题窗格在展开状态下的高度为200,在折叠状态下的高度为25

图为:

我有一个文本字段,可以在其中输入要选择的图像的编号

例如,如果我输入“4”,滚动窗格将滚动至类别2中的图像-4,如下所示

我可以通过基于要滚动的高度和滚动窗格内内容的总高度计算滚动窗格的V值来实现这一点

问题就在这里

在上面的例子中,如果类别2被折叠,我必须“展开”它,然后移动到图像4

我使用以下代码算法来实现这一点: //将标题为pane-2的滚动窗格内容在折叠状态下的高度设为(ht\U ScrollPaneBefore=825),滚动窗格视图端口高度设为(ht\U Viewport=180)。将标题窗格-2展开后的滚动窗格的ht设为ht\u ScrollPaneAfter,该值在以下算法的步骤3中计算得出

{       
   ....
   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.
   ....
}
问题

由于标题窗格的扩展尚未在视图上“可视化”应用,因此V值(0.52)将相对于ht_ScrollpaneBefore(800)应用,这将导致不正确的滚动ht,如下面的“实际输出”所示

实际输出:

    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);
            });
        }
    }

期望值:

    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);
            });
        }
    }

注意:使用链接中所述的过程成功获得标题窗格-2展开后滚动窗格的ht。仅在之后,而不是在ht\U ScrollPane之前,根据ht\U ScrollPane计算V值。这里唯一的问题是Vvalue的应用程序出错,因为滚动窗格视图尚未使用扩展的TitledPane-2更新

代码示例:

    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);
            });
        }
    }
private void scrollToImage(){
int imageNum=Integer.parseInt(textField.getText());//在文本字段中输入的数字
int categoryNum=imageNum/2+imageNum%2;//图像编号属于哪个类别。
Bounds scrollViewBounds=mscr.localToScene(mscr.getBoundsInLocal());//视口边界。
Platform.runLater(()->{
System.out.println(“Before:+mvbx.getHeight());
标题小组成员[categoryNum-1].setExpanded(true);
mvbx.applyCss();
mvbx.layout();
});
双滚动ht[]={0.0};
//选定图像类别之前的类别的ht。
对于(intidx=0;idx<(categoryNum-1);idx++){
scrollHt[0]+=titledPaneList[idx].getHeight();
}
//检查图像是否为类别中的第一个/第二个图像。
int-imageIdxInCategory=(imageNum%2==0)?1:0;
//如果所选图像是类别中的第二个图像,
//将标题栏和第一个图像ht添加到滚动ht。
如果(imageIdxInCategory>0){
scrollHt[0]+=25//标题栏ht。
+标题窗格成员[categoryNum-1].getInsets().getTop()//标题窗格顶部插图
+((VBox)titledPaneList[categoryNum-1].getContent()).getChildren().get(0).getBoundsInLocal().getHeight();//第一个图像的ht
//注意:由于,我的标题窗格包含一个vbox,其中包含
//图像编号标签和图像视图,
//我正在计算上述代码中第一个vbox her的ht。
}
Platform.runLater(()->{
System.out.println(“之后:+mvbx.getHeight());
双d_ScrollHtPerPix=1
/(mvbx.getHeight()
-(scrollViewBounds.getHeight()-mscr.getInsets().getTop()-mscr.getInsets().getBottom());
mscr.setVvalue(scrollHt[0]*d_ScrollHtPerPix);
});
}
}
输出:

折叠选定图像的类别时

前:825

之后:825


如你所见,即使在展开折叠的类别后,滚动窗格内容的高度也是相同的。

为什么要在展开titiledpane-2后计算高度?我需要根据该高度计算滚动窗格的V值,以将滚动移动到Image-4,但我认为可以在不加修改的情况下正确计算V值并滚动到Image-4展开它。我需要展开标题窗格-2,因为选定的“图像-4”在它下面。所以,我必须展开titledpane-2,然后移到图4。因为Vvalue类似于(/)。可滚动的总ht为=-。如果有任何方法可以计算正确的V值,以便滚动到图4,请让我知道。如果您可以提供MVCE进行观察,这将更有帮助。否则就只有猜测了。