You can do this by using a linear-gradient
for the track background, and binding the point where the gradient changes to the slider's value. The basic idea would be that when, e.g., the slider's value is at 50%, the background should be defined by
.slider .track {
-fx-background-color: linear-gradient(to right, red 0%, red 50%, -fx-base 50%, -fx-base 100%);
}
but the 50%
should change according to the slider's value.
So define the following in a CSS file (I introduced some extra looked-up colors to make it easier to modify the style):
.slider {
/* default track color: */
-slider-filled-track-color: red ;
-slider-track-color: -slider-filled-track-color ;
}
/* Make thumb same color as filled part of track */
.slider .thumb {
-fx-background-color: -slider-filled-track-color ;
}
.slider .track {
-fx-background-color: -slider-track-color ;
}
and then you can do
slider.styleProperty().bind(Bindings.createStringBinding(() -> {
double percentage = (slider.getValue() - slider.getMin()) / (slider.getMax() - slider.getMin()) * 100.0 ;
return String.format("-slider-track-color: linear-gradient(to right, -slider-filled-track-color 0%%, "
+ "-slider-filled-track-color %f%%, -fx-base %f%%, -fx-base 100%%);",
percentage, percentage);
}, slider.valueProperty(), slider.minProperty(), slider.maxProperty()));
to bind the place where the color changes to the value of the slider.
Here's a SSCCE:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SliderStyleTest extends Application {
private static final String SLIDER_STYLE_FORMAT =
"-slider-track-color: linear-gradient(to right, -slider-filled-track-color 0%%, "
+ "-slider-filled-track-color %1$f%%, -fx-base %1$f%%, -fx-base 100%%);";
@Override
public void start(Stage primaryStage) {
Slider slider = new Slider();
slider.styleProperty().bind(Bindings.createStringBinding(() -> {
double percentage = (slider.getValue() - slider.getMin()) / (slider.getMax() - slider.getMin()) * 100.0 ;
return String.format(SLIDER_STYLE_FORMAT, percentage);
}, slider.valueProperty(), slider.minProperty(), slider.maxProperty()));
StackPane root = new StackPane(slider);
root.setPadding(new Insets(10));
Scene scene = new Scene(root);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
where style.css
is just the CSS file above. This gives:
