如何打印媒体和样式滑块的持续时间| JavaFX的

时间:2017-10-22 13:09:58

标签: java javafx slider

我正在为我的大学项目制作一个音乐播放器,并面对Sliders的一些问题。

以下是我想要寻找酒吧的事情:

  1. 如何设置搜索滑块的样式? (-fx-accent不起作用)。
  2. 如何打印歌曲的总时间以及播放歌曲的当前时间。
  3. 以下是我用于seekSlider的代码:

    package musicplayer;
    
    import java.io.File;
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.beans.Observable;
    import javafx.beans.binding.Bindings;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.MapChangeListener;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.Slider;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.media.MediaView;
    import javafx.stage.FileChooser;
    import javafx.util.Duration;
    
    
    
    public class FXMLDocumentController implements Initializable {
    
        @FXML
        private Button playbtn;
        @FXML
        private Button pausebtn;
        @FXML
        private Button stopbtn;
        @FXML
        private Button open;
        @FXML
        private Slider seekSlider;
        @FXML
        private Slider volumeSlider;
        @FXML
        private Label durationLabel;
        @FXML
        private Label musicBox;
        @FXML
        private Label playTime;
        @FXML
        private ImageView albumCover;
        @FXML
        private ImageView playbtnimg;
    
        @FXML
        private MediaView mv; 
        private MediaPlayer mp;
        private Media me;
        Double duration;
        File selectedFile = null;
        /**
         * Initializes the controller class.
         * @param e
         */
    
        //Open button code for choosing file through FileChooser
         public void open(ActionEvent e){
    
    
            FileChooser fc = new FileChooser();
            //Extension filter for showing mp3 and m4a files
            fc.getExtensionFilters().addAll(new
            FileChooser.ExtensionFilter("MP3", "*.mp3"),new
            FileChooser.ExtensionFilter("M4A", "*.m4a"));
            selectedFile = fc.showOpenDialog(null);
    
            //If runs when user selects a file
            if(selectedFile != null){
    
            String path = selectedFile.getAbsolutePath(); //gets the path of file
            if(mp!=null) //This if works when any song is playing
            {
                mp.stop(); //Stops the currently playing music
    
                //Change the album art to default.png
                File file = new File("src/musicplayer/default.png");
                Image image = new Image(file.toURI().toString());
                albumCover.setImage(image);
            }
    
            path = path.replace("\\","/");
            me = new Media(new File(path).toURI().toString());
            mp = new MediaPlayer(me);
            mv.setMediaPlayer(mp);
            //Code for Volume Slider 
            volumeSlider.setValue(0.7 * 100);
            volumeSlider.valueProperty().addListener((Observable observable) -> {
            mp.setVolume(volumeSlider.getValue()/100);
            });
            //Code for seeking bar
    
            seekSlider.maxProperty().bind(Bindings.createDoubleBinding(
                () -> mp.getTotalDuration().toSeconds(),
                mp.totalDurationProperty()));
    
            mp.currentTimeProperty().addListener((ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) -> {
                seekSlider.setValue(newValue.toSeconds());
            });
    
            seekSlider.setOnMouseClicked((MouseEvent event) -> {
                mp.seek(Duration.seconds(seekSlider.getValue()));
            });
    
    
    
    
    
    
            mp.play(); //Plays the selected song
    
            me.getMetadata().addListener(new MapChangeListener<String, Object>() {
            @Override
            public void onChanged(Change<? extends String, ? extends Object> ch) {
              if (ch.wasAdded()) {
                handleMetadata(ch.getKey(), ch.getValueAdded());
              }
            }
    
                private void handleMetadata(String key, Object value) {        
                    if(key.equals("title")){   
                        musicBox.setText(value.toString());
                        }
                    if(key.equals("image")){
                        albumCover.setImage((Image)value);
                        }
                    }
                });
            }
        }
        public void play(ActionEvent e){
        mp.play();
        }
    
        public void pause(ActionEvent e){
        mp.pause();
        }
    
        public void stop(ActionEvent e){
        mp.stop();
        }
    
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {
    
    
        }
    
    
    
    }
    

    我使用playTime Label显示totalDuration和durationLabel来显示当前时间。 另外,检查seekSlider的代码,有时,拖动时它无法正常工作。

1 个答案:

答案 0 :(得分:1)

您可以创建Label并将其text属性绑定到格式化MediaPlayer当前时间的绑定:

Label timeLabel = new Label();
timeLabel.textProperty().bind(
    Bindings.createStringBinding(() -> {
            Duration time = mp.getCurrentTime();
            return String.format("%4d:%02d:%04.1f",
                (int) time.toHours(),
                (int) time.toMinutes() % 60,
                time.toSeconds() % 3600);
        },
        mp.currentTimeProperty()));

请注意,您不应该听鼠标输入,因为可以使用键盘和屏幕触摸来控制控件。最好是听取value属性:

Slider seekSlider = new Slider(0, 1, 0);
seekSlider.maxProperty().bind(
    Bindings.createDoubleBinding(
        () -> mp.getTotalDuration().toSeconds(),
        mp.totalDurationProperty()));

mp.currentTimeProperty().addListener((observable, oldValue, newValue) -> {
    seekSlider.setValue(newValue.toSeconds());
});

seekSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
    mp.seek(Duration.seconds(newValue.doubleValue()));
});

请注意,MediaPlayer的某些属性在首次构建时可能毫无意义,因为它会在后台加载媒体。例如,totalDuration的初始值可能是Duration.UNKNOWN。

您可以通过将依赖于MediaPlayer的所有代码移动到Runnable中并将该Runnable传递给setOnReady来处理此问题:

Label timeLabel = new Label();
Slider seekSlider = new Slider();

mp.setOnReady(() -> {
    timeLabel.textProperty().bind(
        Bindings.createStringBinding(() -> {
                Duration time = mp.getCurrentTime();
                return String.format("%4d:%02d:%04.1f",
                    (int) time.toHours(),
                    (int) time.toMinutes() % 60,
                    time.toSeconds() % 3600);
            },
            mp.currentTimeProperty()));

    seekSlider.maxProperty().bind(
        Bindings.createDoubleBinding(
            () -> mp.getTotalDuration().toSeconds(),
            mp.totalDurationProperty()));

    mp.currentTimeProperty().addListener((observable, oldValue, newValue) -> {
        seekSlider.setValue(newValue.toSeconds());
    });

    seekSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
        mp.seek(Duration.seconds(newValue.doubleValue()));
    });
});