代码之家  ›  专栏  ›  技术社区  ›  Ashley

动态更改javafx css属性

  •  1
  • Ashley  · 技术社区  · 8 年前

    在我的fxml中,我有一个简单的滑块:

    <Slider fx:id="timeSlider" showTickLabels="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="4"/>
    

    这个滑块是我正在编写的桌面音乐应用程序的一部分,它表示歌曲播放了多远。我写了一个更改事件,每次更改歌曲时间都称为更改事件,这成功地完成了向下滑动旋钮/拇指的操作。

    现在,我还试图在旋钮向下滑动时,将左侧部分(已播放)变为蓝色,右侧部分(尚未播放)变为白色。如果我将这一行硬编码到我的CSS中,我可以在50%标记处完成从蓝色/白色淡出。

    .slider .track {-fx-background-color: linear-gradient(to right, #90C7E0 50%, white 50%);}
    

    然而,我需要这是动态的根据我在歌曲的多远。我已经编写了以下代码,但似乎无法应用CSS样式

    song.getMediaPlayer().currentTimeProperty().addListener(new ChangeListener<Duration>() {
            @Override
            public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
                if (newValue != null && timeSlider != null) {
                    timeSlider.setValue(newValue.toSeconds());
                    double percentage = (newValue.toSeconds()/song.getDuration())*100;
                    String css = ".slider .track{-fx-background-color: linear-gradient(to right, #90C7E0 " +
                     percentage + "%, white " + percentage + "%);}";
                    timeSlider.getStyleClass().add(css);
                }
            }
        });
    

    我相信这与我如何将CSS作为样式添加有关,因为即使添加简单的非动态样式也不起作用。我没有错误,所以我不确定我做错了什么。

    我们感谢您的帮助,也感谢您更好地实现这一目标。谢谢!

    2 回复  |  直到 8 年前
        1
  •  2
  •   James_D    8 年前

    方法 getStyleClass() 返回与节点关联的CSS类名列表。这些类名用于确定将外部CSS文件中的哪些规则应用于节点。您不能在这里传递CSS选择器和规则。

    相反,编写一个外部CSS文件,其中包含一个用于跟踪的背景色规则。您可以在这里使用“查找颜色”,基本上类似于“css变量”。为滑块定义“查找颜色”,并在轨迹的规则中使用它来设置背景颜色:

    style.css :

    .slider {
        -track-color: white ;
    }
    .slider .track {
        -fx-background-color: -track-color ;
    }
    

    现在,在Java代码中,可以通过调用来更新查找颜色的值。 setStyle("-track-color: /* someColor */") 在滑块上。下面是一个简单的例子:

    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.Slider;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class SliderTest extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            Slider slider = new Slider();
            slider.valueProperty().addListener((obs, oldValue, newValue) -> {
                double percentage = 100.0 * (newValue.doubleValue() - slider.getMin()) / (slider.getMax() - slider.getMin());
                slider.setStyle("-track-color: linear-gradient(to right, #90C7E0 " + percentage+"%, white "+percentage+("%);"));
            });
            StackPane root = new StackPane(slider);
            root.setPadding(new Insets(20));
            Scene scene = new Scene(root);
            scene.getStylesheets().add("style.css");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    在您的应用程序中,您可以使用媒体播放器的当前时间执行相同的操作(或者在滑块的值属性上注册一个监听器,因为这也在改变)。

        2
  •  0
  •   Ashley    8 年前

    在这些评论的帮助下,我想出了一个解决办法,

    .getStyleClass.add(…)没有按我最初的想法执行,我需要使用.setStyle(…)而不是在滑块轨道上设置样式。这是我的密码…

    public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
                if (newValue != null && timeSlider != null) {
                    double percentage = (newValue.toSeconds()/song.getDuration())*100;
                    String cssValue = "-fx-background-color: linear-gradient(to right, #90C7E0 " +
                     percentage + "%, white " + percentage + "%)";
                    StackPane sliderTrack = (StackPane) timeSlider.lookup(".track");
                    sliderTrack.setStyle(cssValue);
                    timeSlider.setValue(newValue.toSeconds());
                }
            }