controlsfx / controlsfx

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

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

Closed james-d closed 11 months ago

james-d commented 12 months 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 11 months ago

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