Is there a way to update a scrollbar when there is a modification which changes its scrollpane content height. It is during a dragging operation

霸气de小男生 提交于 2020-01-06 06:25:07

问题


There is a JAVAFX Scrollpane which contains a treeview. Inside the treeview, i have a few vboxs. Their height can change. Firstly, there was a problem : when i move a vbox thanks to a drag operation, the scrollbar which belongs to the scrollpane didn't want to move. In order to resolve this problem, i have done a few researches here. I found a solution. The code is below

 private ScrollBar getVerticalScrollbar() {
    ScrollBar result = null;
    for (Node n : scrollPane.lookupAll(".scroll-bar")) {
        if (n instanceof ScrollBar) {
            ScrollBar sb = (ScrollBar) n;
            if (sb.getOrientation().equals(Orientation.VERTICAL)) {
                result = sb;

            }
        }
    }

    return result;
}

 private void dragScroll() {
    ScrollBar sb = getVerticalScrollbar();
    if (sb != null && !dropped) {
        double newValue = sb.getValue() + scrollVelocity;
        newValue = Math.min(newValue, 1.0);
        newValue = Math.max(newValue, 0.0);
        sb.setValue(newValue);
    }
}

  public void setupScrolling() {

    scrolltimeline.setCycleCount(Timeline.INDEFINITE);
    scrolltimeline.getKeyFrames().add(new KeyFrame(Duration.millis(15), (ActionEvent) -> {
        dragScroll();
    }));

    scrollPane.setOnDragExited((DragEvent event) -> {

        if (event.getY() > 0) {
            scrollVelocity = 1.0 / 100;
        } else {
            scrollVelocity = -1.0 / 100;
        }
        if (!dropped) {
            scrolltimeline.play();
        } else {
            scrolltimeline.stop();
        }

    });

    scrollPane.setFitToHeight(true);

    scrollPane.setOnDragEntered(event -> {
        scrolltimeline.stop();
        dropped = false;
    });
    scrollPane.setOnDragDone(event -> {
        scrolltimeline.stop();
    });
    scrollPane.setOnMouseReleased(event -> {
        scrolltimeline.stop();

    });

    scrollPane.setOnDragDropped((DragEvent event) -> {
        dropped = true;
        scrolltimeline.stop();
        event.setDropCompleted(true);

    });

    scrollPane.setOnDragOver((DragEvent event) -> {
        event.acceptTransferModes(TransferMode.MOVE);
    });

    scrollPane.setOnScroll((ScrollEvent event) -> {
        scrolltimeline.stop();
    });
}

The setupScrolling is called into the method which inits the Controller. Nevertheless, you must be surprised : where is managed the vbox drag and drop operation ? There is another drag and drop interface which is created and the dropped variable value is changed to true into the dragDropped method. It permits to stop the used timeline (the timeline function is to move the scrollbar by changing the scrollbar value).

private final void onLabelDragDropped(DragEvent event) {
    ...
    dropped = true;
    scrolltimeline.stop()
    ...
};

Now, we arrive to the current problem. When a Label is moved over a VBOX (there are a few VBOX which contain labels), the VBOX size changes. It is made thanks to the css code: "-fx-padding: 10 10 10 10". However, the scrollbar doesn't have its size which change. So, when the scrollbar goes down during the drag operation, its size is not updated automatically. So, some VBoxs are not visible anymore. In fact, they are below.

Thanks you for your help.

Cordially,

VinzFR

PS: i am sorry, i don't speak english very well

来源:https://stackoverflow.com/questions/55722820/is-there-a-way-to-update-a-scrollbar-when-there-is-a-modification-which-changes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!