Search code examples
javafxmedia-player

javafx MediaPlayer- getting the next song


When I start my mediaplayer, and click the next-song button, it starts at the first song and goes down the list as intended. But if I start the program, double-click an mp3 file to play it, then click the next-song button, the first song in the list plays, not the mp3 after the mp3 I double clicked.

btn.setOnAction((ActionEvent e) ->
{

    if(doubleClicked)
    {
        player.stop();
        media = new Media(rowData.toURI().toString()); // needs to go to next song
        player = new MediaPlayer(media);
        player.play();
        return;
    }
    if(music.hasNext())
    {
        try
        {               
            player.stop();
            media = new Media(music.next());
            player = new MediaPlayer(media);

            player.play();

            lbl.setText(media.getSource());   
        }
        catch(MediaException a)
        {
            System.out.println("Unsupported Format");
        }
    }

});

rowData is the mp3 file when double clicked. I've tried a bunch of things but nothing seems to work. I have my own data structure for this, but its pretty much the same as the built in Iterator and ArrayList code.


Solution

  • You don't adjust the Iterator's position according to the new position in the playlist. Given the index of the item clicked by the user you can simply replace the Iterator by a new one using List.listIterator.

    Here's an simplified example using a ListView and Strings that are displayed in a label:

    private Iterator<String> songIterator;
    
    @Override
    public void start(Stage primaryStage) {
        ObservableList<String> songs = FXCollections.observableArrayList("Song 1", "Song 2", "Song 3", "Song 4");
    
        // start with first song
        songIterator = songs.iterator();
        Label songLabel = new Label(songIterator.next());
        ListView<String> lv = new ListView(songs);
    
        MultipleSelectionModel<String> selectionModel = lv.getSelectionModel();
    
        lv.setCellFactory(t -> new ListCell<String>() {
    
            {
                setOnMouseClicked(evt -> {
                    if (evt.getButton() == MouseButton.PRIMARY && evt.getClickCount() == 2) {
                        evt.consume();
                        // update label
                        songLabel.setText(getItem());
                        // iterator should return next item next
                        songIterator = songs.listIterator(selectionModel.getSelectedIndex()+1);
                    }
                });
            }
    
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                setText(empty ? null : item);
            }
    
        });
    
        Button btn = new Button();
        btn.setText("Next");
        btn.setOnAction((ActionEvent event) -> {
            if (songIterator.hasNext()) {
                songLabel.setText(songIterator.next());
            }
        });
    
        Scene scene = new Scene(new VBox(songLabel, lv, btn));
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }