I'm making a playlist based mp3 player using javafx and I got everything working except how to pause/resume a song. I tried simply checking the player.Status()
and using that but it didn't work so I stored the time of the song when pause()
is clicked, in a Duration pausetime
variable and it works that way but only once. What happens is: I click pause()
, it works, click play()
, it resumes the song but after that the pause button stops doing anything.
Btw I'm using two separate ToggleButton
for pause and play because of the style I'm going for.
Here's the part of the code i'm talking about:
public void play(){
if (player != null){
player.stop();
}
if (pausebutton.isSelected()){
pausebutton.setSelected(false); //resume part
slider.setValue(pausetime.toSeconds());
play();
}
this.player = players.get(i);
player.setStartTime(pausetime);
player.play();
slide(i);
csong.setText(playlist.get(i).getName());
player.setOnEndOfMedia(new Runnable(){
@Override public void run(){
if (shuffle.isSelected()){
i = rand.nextInt(players.size() + 1);
}
else{
i++;
}
if(loop.isSelected()){
if (i == players.size()){
i = 0;
}}
list.getSelectionModel().select(i);
play();
}
});
}
public void pause(){
player.pause();
pausetime = player.getCurrentTime();
playbutton.setSelected(false);
}
I have created a very simple mp3 player, which has most (if not all) of the components said above.
- It has play and pause toggle buttons, which do work ;)
- It has labels updating the time elapsed for the song
- It has a sliderbar, which can be used to move forward/backward. It automatically updates on song play.
Complete Code
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.text.DecimalFormat;
public class MediaPlayerSample extends Application {
private MediaPlayer player;
private final ToggleButton playButton = new ToggleButton("Play");
private final ToggleButton pauseButton = new ToggleButton("Pause");
private final ToggleGroup group = new ToggleGroup();
private final Label totalDuration = new Label();
private final Label currentDuration = new Label();
private final DecimalFormat formatter = new DecimalFormat("00.00");
private final SliderBar timeSlider = new SliderBar();
private Duration totalTime;
@Override
public void start(Stage primaryStage)
{
//Add a scene
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setStyle("-fx-background-color: ANTIQUEWHITE");
HBox playPause = new HBox(playButton, pauseButton);
HBox sliderBox = new HBox(timeSlider, currentDuration, totalDuration);
HBox.setHgrow(sliderBox, Priority.ALWAYS);
root.getChildren().addAll(sliderBox, playPause);
Scene scene = new Scene(root, 300, 100);
Media pick = new Media(getClass().getResource("/delete/abc/abc.mp3").toExternalForm());
player = new MediaPlayer(pick);
// Play the track and select the playButton
player.play();
playButton.setSelected(true);
player.currentTimeProperty().addListener(new ChangeListener<Duration>() {
@Override
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
timeSlider
.sliderValueProperty()
.setValue(newValue.divide(totalTime.toMillis()).toMillis() * 100.0);
currentDuration.setText(String.valueOf(formatter.format(newValue.toSeconds())));
}
});
player.setOnReady(() -> {
// Set the total duration
totalTime = player.getMedia().getDuration();
totalDuration.setText(" / " + String.valueOf(formatter.format(Math.floor(totalTime.toSeconds()))));
});
// Slider Binding
timeSlider.sliderValueProperty().addListener((ov) -> {
if (timeSlider.isTheValueChanging()) {
if (null != player)
// multiply duration by percentage calculated by
// slider position
player.seek(totalTime.multiply(timeSlider
.sliderValueProperty().getValue() / 100.0));
else
timeSlider.sliderValueProperty().setValue(0);
}
});
//Applying Toggle Group to Buttons
playButton.setToggleGroup(group);
pauseButton.setToggleGroup(group);
// Action for Buttons
playButton.setOnAction(e -> {
play();
});
pauseButton.setOnAction(e -> {
pause();
});
//show the stage
primaryStage.setTitle("Media Player");
primaryStage.setScene(scene);
primaryStage.show();
}
public void play(){
player.play();
playButton.setSelected(true);
}
public void pause(){
player.pause();
playButton.setSelected(false);
}
private class SliderBar extends StackPane {
private Slider slider = new Slider();
private ProgressBar progressBar = new ProgressBar();
public SliderBar() {
getChildren().addAll(progressBar, slider);
bindValues();
}
private void bindValues(){
progressBar.prefWidthProperty().bind(slider.widthProperty());
progressBar.progressProperty().bind(slider.valueProperty().divide(100));
}
public DoubleProperty sliderValueProperty() {
return slider.valueProperty();
}
public boolean isTheValueChanging() {
return slider.isValueChanging();
}
}
public static void main(String[] args) {
launch(args);
}
}
A simple look while it plays
You can style the mediaplayer using stylesheet. You can go through JavaFX CSS Reference for advanced topic on css.
For a mediaplayer with advanced features like:
- Adding songs to a Playlist
- Playing songs one after another
- Drag and drop songs into mediaview
and much more, you can go visit this example.