Aryan
Aryan

Reputation: 31

Javafx Slider increment with 10 on track click

Like JSlider in javafx how we can increment with specific value like I want my slider knob should move by +10 on every right click on slider(anywhere on track ) and -10 on left click of slider(anywhere on track ). I am using following code but not getting the result

Slider betSlider = new Slider(0, 1000, 100);
betSlider.setMinorTickCount(0);
betSlider.setMajorTickUnit(10);
betSlider.setBlockIncrement(10);
betSlider.setSnapToTicks(true);

container.getChildren().add(betSlider);
betSlider.valueProperty().addListener(new ChangeListener<Number>() {
    public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
        betSlider.setValue(new_val.intValue());
    }
});

Upvotes: 2

Views: 1075

Answers (1)

Enigo
Enigo

Reputation: 3885

The main difficulty of this problem is that we don't have direct access to the track OnMouseClick logic (SliderBehavior.trackPress). This might be solved by creating custom slider with custom SliderSkin and SliderBehavior, but that sounds like an overkill.

It doesn't work as-is in your code snippet because when you click on the track the logic behind this action is to place the knob to the closest tick (once again, have a look at SliderBehavior.trackPress)

To solve this the following approach might be used (Note, Java 8):

private boolean valueChanged;
....
public void setupSlider() {
    Slider betSlider = new Slider(0, 100, 10);
    int blockIncrementStep = 10;
    betSlider.setMinorTickCount(0);
    betSlider.setMajorTickUnit(10);
    betSlider.setBlockIncrement(blockIncrementStep);
    betSlider.setSnapToTicks(true);
    betSlider.setShowTickMarks(true);
    container.getChildren().add(betSlider);
    betSlider.valueProperty().addListener((ov, oldValue, newValue) -> {
        if (!valueChanged) {
            valueChanged = true;
            if (newValue.intValue() > oldValue.intValue()) {
                betSlider.setValue(oldValue.intValue() + blockIncrementStep);
            } else {
                betSlider.setValue(oldValue.intValue() - blockIncrementStep);
            }
        }
    });
    betSlider.setOnMouseClicked(event -> valueChanged = false);
}

Each time betSlider.setValue method is called - betSlider.valueProperty().changed method is triggered as well. And only when there are no more changes setOnMouseClicked is triggered. Hence, we can simply track if the value has been already changed after a click on a track and if not - change it manually.

Upvotes: 1

Related Questions