Search code examples
javajavafxmp3playlistscenebuilder

Can't play all songs on a playlist


So I'm making an mp3 player with javafx that has a ListView where I drag and drop songs, I then select a song and press play to play it, you get the point.. Trouble is, with my current code, I can't play a sequence of more than two songs :/ (plays selected song, plays song next to it and then stops). Here's the code:

public class MainController implements Initializable {

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        list.setItems(tracklist);
    }

    private MediaPlayer player;
    private Duration pausetime = null;
    private int i;

    ObservableList<String> tracklist = FXCollections.observableArrayList();
    ArrayList<File> playlist = new ArrayList<File>();
    ArrayList<MediaPlayer> players = new ArrayList<MediaPlayer>();

    @FXML
    private Slider slider;

    @FXML
    private Button open;

    @FXML
    private Label csong;

    @FXML
    private ListView<String> list;

    public void getsongfromlist(){
        i = list.getSelectionModel().getSelectedIndex();
    }

    public void slide(int a){
        slider.setMin(0.0);
        slider.setValue(0.0);

        player.currentTimeProperty().addListener(new ChangeListener<Duration>(){

            @Override
            public void changed(ObservableValue<? extends Duration> observableValue, Duration duration,
                    Duration current) {
                // TODO Auto-generated method stub
                slider.setMax(players.get(a).getTotalDuration().toSeconds());
                slider.setValue(current.toSeconds());
            }
        });
    }

    public void move(){
        player.seek(Duration.seconds(slider.getValue()));
    }

    public void play(){              //This is where im getting it wrong
        if (player != null){
            player.stop();
        }
        this.player = players.get(i);
        player.play();
        slide(i);
        csong.setText(playlist.get(i).getName());
        for (int j = 0; j < players.size(); j++){
        player.setOnEndOfMedia(new Runnable(){
            @Override public void run(){
            i++;
            list.getSelectionModel().select(i);
            player = players.get(i);
            player.play();
            slide(i);
            csong.setText(playlist.get(i).getName());
            }
        });
    }
    }

    public void handle(DragEvent event) {
        Dragboard db = event.getDragboard();
        if (db.hasFiles()) {
            event.acceptTransferModes(TransferMode.COPY);
        } else {
            event.consume();
        }
    }

    public void dropped(DragEvent event){
        Dragboard db = event.getDragboard();
        event.acceptTransferModes(TransferMode.COPY);
        boolean success = false;
        if (db.hasFiles()){
            success = true;
            for (File file:db.getFiles()){
                tracklist.add(file.getName());
                playlist.add(file);
                try {
                    final Media media = new Media(file.toURI().toURL().toString());
                    final MediaPlayer set = new MediaPlayer(media);
                    players.add(set);
                } catch (MalformedURLException e) {

                    e.printStackTrace();
                }
            }
        }
        event.setDropCompleted(success);
        event.consume();
    }
}

Solution

  • Not tested, but try replacing

    for (int j = 0; j < players.size(); j++){
        player.setOnEndOfMedia(new Runnable(){
            @Override public void run(){
            i++;
            list.getSelectionModel().select(i);
            player = players.get(i);
            player.play();
            slide(i);
            csong.setText(playlist.get(i).getName());
            }
        });
    }
    

    with

    player.setOnEndOfMedia(new Runnable(){
        @Override
        public void run() {
            i++ ;
            play();
        }
    });
    

    and move the line

    list.getSelectionModel().select(i);
    

    from the endOfMedia listener to the main body of the play() method.