controlsfx / controlsfx

High quality UI controls to complement the core JavaFX distribution
https://controlsfx.org
BSD 3-Clause "New" or "Revised" License
1.58k stars 269 forks source link

RangeSlider: range bar jumps on dragging when orientation is vertical #1521

Closed james-d closed 1 year ago

james-d commented 1 year ago

See the stack overflow question at https://stackoverflow.com/questions/77239808/controlsfx-rangeslider-is-laggy-when-orientation-is-vertical

For some reason, this only reproduces for me when the example application (reproduced below) is running on the Retina display on my MacBook; it does not reproduce when the app is on a (lower-resolution) external monitor.

The following code reproduces the issue. Shorten the range of the vertical range bar and drag the range bar (not the thumbs).


import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.*;
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);

        rangeSliderVertical.lowValueProperty().addListener((obs, oldValue, newValue) -> System.out.printf("%.2f -> %.2f%n", oldValue.doubleValue(), newValue.doubleValue()));

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

}

The problem is caused by the RangeSliderSkin class, in the listeners attached to the lowValueProperty() and highValueProperty(). The code in those resizes (and for the low value property relocates) the range bar, assuming the range slider has a horizontal orientation. The correct layout is restored on the next layout pass, but it seems to cause intermittent jumping around.

abhinayagarwal commented 1 year ago

Fixed with https://github.com/controlsfx/controlsfx/pull/1522