当方向为垂直时,ControlsFX RangeSlider 滞后

dro*_*oid 7 java javafx controlsfx

setOrientation设置为时Orientation.HORIZONTAL滑块的运动非常平滑,但setOrientation设置为时Orientation.VERTICAL运动则比较滞后。

以下是最小再现:

package org.example;

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.controlsfx.control.RangeSlider;

public class App extends Application {

    @Override
    public void start(Stage stage) {

        RangeSlider rangeSliderVertical = new RangeSlider();
        rangeSliderVertical.setOrientation(Orientation.VERTICAL);
        rangeSliderVertical.setMinHeight(500);
        rangeSliderVertical.setMax(100);
        rangeSliderVertical.setMin(0);
        rangeSliderVertical.setHighValue(100);
        rangeSliderVertical.setLowValue(0);

        RangeSlider rangeSliderHorizontal = new RangeSlider();
        rangeSliderHorizontal.setMinWidth(500);
        rangeSliderHorizontal.setMax(100);
        rangeSliderHorizontal.setMin(0);
        rangeSliderHorizontal.setHighValue(100);
        rangeSliderHorizontal.setLowValue(0);
        rangeSliderHorizontal.setOrientation(Orientation.HORIZONTAL);

        FlowPane vBoxWithSliders = new FlowPane();
        VBox.setVgrow(vBoxWithSliders, Priority.ALWAYS);
        HBox.setHgrow(vBoxWithSliders, Priority.ALWAYS);

        vBoxWithSliders.setAlignment(Pos.CENTER);
        vBoxWithSliders.getChildren().addAll(rangeSliderVertical, rangeSliderHorizontal);

        var scene = new Scene(vBoxWithSliders, 600, 600);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}
Run Code Online (Sandbox Code Playgroud)

有关如何在 RangeSlider 垂直时实现平滑移动的任何提示吗?

在此输入图像描述

Jam*_*s_D 5

这是 中的一个错误RangeSliderSkinlowValueProperty()现有代码包括和上的以下侦听器highValueProperty()

    registerChangeListener(rangeSlider.lowValueProperty(), e -> {
        positionLowThumb();
        rangeBar.resizeRelocate(rangeStart, rangeBar.getLayoutY(), 
        rangeEnd - rangeStart, rangeBar.getHeight());
    });
    registerChangeListener(rangeSlider.highValueProperty(), e -> {
        positionHighThumb();
        rangeBar.resize(rangeEnd-rangeStart, rangeBar.getHeight());
    });
Run Code Online (Sandbox Code Playgroud)

请参阅源代码https://github.com/controlsfx/controlsfx/blob/master/controlsfx/src/main/java/impl/org/controlsfx/skin/RangeSliderSkin.java

rangeBar.resizeRelocate()rangeBar.resize()的调用假设范围滑块具有水平方向。(您可以看到这一点,因为只有栏的layoutX和/或width可以更改。 和layoutYheight设置为其当前值。)在方法中重新绘制范围栏本身之前,会纠正范围栏的不正确布局layoutChildren()。但是,我认为在某些情况下,可以在调用之前处理额外的拖动事件layoutChildren(),从而导致拇指位置的计算不正确。

我在https://github.com/james-d/controlsfx/tree/master有一个 ControlsFX 存储库的分支,它可以解决这个问题

    registerChangeListener(rangeSlider.lowValueProperty(), e -> {
        positionLowThumb();
        if (isHorizontal()) {
            rangeBar.resizeRelocate(rangeStart, rangeBar.getLayoutY(),
                    rangeEnd - rangeStart, rangeBar.getHeight());
        } else {
            rangeBar.resize(rangeBar.getWidth(), rangeEnd - rangeStart);
        }
    });
    registerChangeListener(rangeSlider.highValueProperty(), e -> {
        positionHighThumb();
        if (isHorizontal()) {
            rangeBar.resize(rangeEnd - rangeStart, rangeBar.getHeight());
        } else {
            rangeBar.resizeRelocate(rangeBar.getLayoutX(), rangeStart,
                    rangeBar.getWidth(), rangeEnd - rangeStart);
        }
    });
Run Code Online (Sandbox Code Playgroud)

并已将其作为问题 1521以及拉取请求提交。

请随意克隆和构建我的分叉作为临时措施,直到(除非)拉取请求被接受。