如何在javafx中更改滑块的填充颜色

M_r*_*000 1 java javafx

我制作一个视频播放器,并希望使用滑块的时间轴,我想将滑块从第一张图片更改为第二张

在此输入图像描述

在此输入图像描述

我可以使用css代码来做到这一点吗?如果是的话,这是什么代码

JKo*_*dis 8

下面的长篇文章..如果你想要一个简单的方法来实现滑块上的​​颜色我应该提到你可以使用具有你需要的功能的JFoenix Slider.

虽然如果你可以原生地获得相同的结果,实际上不需要使用第三个库.

好吧,没有任何CSS规则-fx-progress-color,你设置为特定的颜色,然后你就完成了..track的颜色使用以下CSS规则设置:

.slider .track {
      -fx-background-color:
          -fx-shadow-highlight-color,
          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
          linear-gradient(to bottom,
            derive(-fx-control-inner-background, -9%),
            derive(-fx-control-inner-background, 0%),
            derive(-fx-control-inner-background, -5%),
            derive(-fx-control-inner-background, -12%)
          );
    -fx-background-insets: 0 0 -1 0, 0, 1;
    -fx-background-radius: 0.25em, 0.25em, 0.166667em; /* 3 3 2 */
    -fx-padding: 0.25em; /* 3 */
}
Run Code Online (Sandbox Code Playgroud)

您需要做的事情很少,第一个是监听滑块的值变化,第二个是根据滑块的值更新曲目颜色.要设置背景颜色,您需要将线性渐变设置为背景,如:

-fx-background-color: linear-gradient(to right, #2D819D START, #969696 END);

使用上面的代码,您将使用颜色#2D819D(即"进度"颜色)和#969696(从左到右)开始设置线性渐变背景,表示剩余进度.现在START和END应该是数字,为了得到你想要的外观,两个数字必须相等,所以当一个停止另一个开始时.例如,如果您设置:

-fx-background-color: linear-gradient(to right, #2D819D 20%, #969696 20%);

在此输入图像描述

真正的挑战是找到一种在滑块的ChangeListener中以编程方式设置这些值的方法.我的第一种方法是使用CSS变量,如:

.slider .track{
    -progress : 0.2;
    -fx-background-color: linear-gradient(to right, #2D819D -progress, #969696 -progress);
}
Run Code Online (Sandbox Code Playgroud)

-progress在ChangeListener上更新使用内联CSS规则.可悲的是,由于某种原因,这不受支持.我也想知道为什么.此外,您不能为子类应用内联CSS,这意味着您不能执行slider.setStyle(".track {...}");

总而言之,您可以:

1.使用查找访问滑块的轨道并直接应用CSS.

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class CustomSlider extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        BorderPane mainPane = new BorderPane();
        mainPane.setPadding(new Insets(15));

        Slider slider = new Slider();
        slider.setId("color-slider");

        mainPane.setCenter(slider);

        Scene scene = new Scene(mainPane, 250, 400);
        stage.setScene(scene);
        stage.show();

        StackPane trackPane = (StackPane) slider.lookup(".track");

        slider.valueProperty().addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
                String style = String.format("-fx-background-color: linear-gradient(to right, #2D819D %d%%, #969696 %d%%);",
                        new_val.intValue(), new_val.intValue());
                trackPane.setStyle(style);
            }
        });

        trackPane.setStyle("-fx-background-color: linear-gradient(to right, #2D819D 0%, #969696 0%);");

    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

2.从头开始制作自定义滑块(不那么难)

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class SliderTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        BorderPane mainPane = new BorderPane();
        mainPane.setPadding(new Insets(15));

        mainPane.setCenter(new ColorSlider());

        Scene scene = new Scene(mainPane, 250, 400);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

    public class ColorSlider extends StackPane {

        public ColorSlider() {
            getStylesheets().add(this.getClass().getResource("colorSlider.css").toExternalForm());
            Slider slider = new Slider();
            slider.setId("color-slider");

            // The rectangle which shows the progress
            Rectangle progressRec = new Rectangle();
            // Bind both width and height to match the size of Slider
            progressRec.heightProperty().bind(slider.heightProperty().subtract(7));
            progressRec.widthProperty().bind(slider.widthProperty());

            progressRec.setFill(Color.web("#969696"));

            // Make the corners of Rectangle to be rounded
            progressRec.setArcHeight(15);
            progressRec.setArcWidth(15);

            // Listen on value changes on the slider to update the progress (color)
            slider.valueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
                    // Using linear gradient we can fill two colors to show the progress
                    // the new_val gets values between 0 - 100
                    String style = String.format("-fx-fill: linear-gradient(to right, #2D819D %d%%, #969696 %d%%);",
                            new_val.intValue(), new_val.intValue());
                    // set the Style
                    progressRec.setStyle(style);
                }
            });

            getChildren().addAll(progressRec, slider);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

colorSlider.css

#color-slider .track{
    -fx-background-color:transparent;
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用“JFXSlider”,并且尝试访问跟踪节点,但第一个解决方案(带有“.lookup()”的解决方案)不起作用。 (2认同)
  • @TheTechExpertGuy 实现它非常容易(刚刚做了),你可以在这里找到所有 CSS 规则 https://github.com/jfoenixadmin/JFoenix/wiki/Slider 。如果您不知道如何在链接中使用 css 规则,如果您创建一个新帖子,我可以为您提供一个小示例,请告诉我,我将在那里发布一个完整的示例。 (2认同)

Jam*_*s_D 7

@JKostikiadis答案略有不同,它避免了 CSS 查找。CSS 查找可能会出现问题,因为null除非应用了 CSS 并进行了布局传递,否则它们将会返回。引用的答案通过在显示舞台后查找轨道来避免这种情况,但这在某些情况下可能很难实现(特别是使用 FXML,其中控制器初始化必须在 UI 添加到场景之前发生)。这个答案还尽了一定的努力来尽可能地保留默认样式。

这里的基本策略是:

  • 使用“查找颜色”定义线性渐变,它将值左侧的轨道与值右侧的轨道分开
  • 根据查找到的颜色设置轨道的背景颜色
  • 使用setStyle(...)滑块以编程方式修改查找的颜色。

这避免了 CSS 查找,因为查找的颜色是在 CSS 中继承的。因此,仅修改滑块本身的查找颜色就足够了:轨道(您不容易引用的轨道)将继承该值。

值得一看的是应用于滑块及其轨道的默认 CSS,您可以在源代码中看到:

.slider .track {
      -fx-background-color:
          -fx-shadow-highlight-color,
          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
          linear-gradient(to bottom,
            derive(-fx-control-inner-background, -9%),
            derive(-fx-control-inner-background, 0%),
            derive(-fx-control-inner-background, -5%),
            derive(-fx-control-inner-background, -12%)
          );
    -fx-background-insets: 0 0 -1 0, 0, 1;
    -fx-background-radius: 0.25em, 0.25em, 0.166667em; /* 3 3 2 */
    -fx-padding: 0.25em; /* 3 */
}
Run Code Online (Sandbox Code Playgroud)

该背景是“嵌套背景”,其嵌套由三个背景插入值定义。第一个值-fx-background-color定义轨道下方 1 像素处的阴影;第二个(由第一个线性渐变给出)定义了具有微妙渐变的 1 像素边框,第三个(第二个线性渐变)定义了轨道的大部分:它是基于标准主题颜色的微妙线性渐变-fx-control-inner-background

这里的计划是保留边框和阴影,并使用线性渐变改变中间的部分。由于我们不能使用一个线性渐变作为另一个线性渐变的目标,我们将使用以下方法近似轨道的默认中心-fx-control-inner-background

.slider {
    -default-track-color: -fx-control-inner-background;
    -track-color: -default-track-color ;
}
Run Code Online (Sandbox Code Playgroud)

然后使用相同的构造将阴影和边框包裹在轨道颜色周围。请注意,我们可以只使用默认样式表中定义的默认插入和填充:无需在此处重新定义它们:

.slider .track {
    -fx-background-color: -fx-shadow-highlight-color,
          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
          -track-color;
}
Run Code Online (Sandbox Code Playgroud)

现在在 Java 代码中我们可以更新-track-color滑块的定义:

    slider.valueProperty().addListener((obs, oldValue, newValue) -> {
        double percentage = 100.0 * newValue.doubleValue() / slider.getMax();
        String style = String.format(
                // in the String format, 
                // %1$.1f%% gives the first format argument ("1$"),
                // i.e. percentage, formatted to 1 decimal place (".1f").
                // Note literal % signs must be escaped ("%%")
                "-track-color: linear-gradient(to right, " +
                        "-fx-accent 0%%, " +
                        "-fx-accent %1$.1f%%, " +
                        "-default-track-color %1$.1f%%, " +
                        "-default-track-color 100%%);",
                percentage);
        slider.setStyle(style);
    });
Run Code Online (Sandbox Code Playgroud)

这是一个完整的示例:

样式.css:

.slider {
    -default-track-color: -fx-control-inner-background;
    -track-color: -default-track-color ;
}

.slider .track {
    -fx-background-color: -fx-shadow-highlight-color,
          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
          -track-color;
}
Run Code Online (Sandbox Code Playgroud)

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.io.IOException;

public class ProgressSlider extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        Slider slider = new Slider();
        slider.valueProperty().addListener((obs, oldValue, newValue) -> {
            double percentage = 100.0 * newValue.doubleValue() / slider.getMax();
            String style = String.format(
                    "-track-color: linear-gradient(to right, " +
                            "-fx-accent 0%%, " +
                            "-fx-accent %1$.1f%%, " +
                            "-default-track-color %1$.1f%%, " +
                            "-default-track-color 100%%);",
                    percentage);
            slider.setStyle(style);
        });
        BorderPane root = new BorderPane(slider);
        Scene scene = new Scene(root, 400, 400);
        scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述