簡體   English   中英

如何在播放列表TableView中突出顯示當前播放的歌曲?

[英]How to highlight current playing song in playlist TableView?

我正在編程某種音樂播放器應用程序,並且左側有我的播放列表表,並且試圖突出顯示播放列表中的當前播放歌曲。 當我通過雙擊播放列表中的歌曲來播放這首歌曲時,效果很好,但是,我的問題是當當前歌曲結束后自動播放一首新歌曲,或者單擊下一步或上一個按鈕時。

我通過雙擊處理突出顯示的方式是直接在行工廠中進行添加,並將其添加到TableRow.onMouseClick事件處理程序中。

在過去的幾天中,我一直在嘗試通過下一個和上一個按鈕來完成此任務,但是沒有成功。

我當前的想法如下:在行工廠中添加某種自定義事件偵聽器,它偵聽自身播放列表中當前播放索引的變化,但是我不確定如何實現,因為我非常通常是JavaFX和GUI的新功能。

下面是應用程序通過雙擊播放歌曲時,如何看起來PIC: 應用

以下是一些相關的代碼部分:

幾個全局變量:

private TableRow<PlaylistTable> lastPlayed;
private TableRow<PlaylistTable> currentPlayed;

PlaylistTable構造函數:

private final Song song;
private final SimpleStringProperty songTitle;
private final SimpleStringProperty artist;
private final SimpleStringProperty album;
private final SimpleStringProperty trackNumber;

public PlaylistTable(LibraryTable row){
    this.song = row.getSong();
    this.songTitle = new SimpleStringProperty(row.getSongTitle());
    this.artist = new SimpleStringProperty(row.getArtist());
    this.album = new SimpleStringProperty(row.getAlbum());
    this.trackNumber = new SimpleStringProperty(row.getTrackNumber());
}

控制器類的initialize方法內具有onMouseClick事件處理程序的Factory行:

 playlistTable.setRowFactory(e -> {
        TableRow<PlaylistTable> row = new TableRow<>();

        row.setOnMouseClicked(e1 -> {

            if (e1.getButton() == MouseButton.PRIMARY && e1.getClickCount() == 2) {
                if (lastPlayed == null) {
                    lastPlayed = row;
                } else if (lastPlayed != row) {
                    lastPlayed.setStyle("");  //("-fx-background-color: #39CCCC;-fx-border-color: white; -fx-text-fill: white;");
                    lastPlayed = row;
                }
                playSongFromPlaylist();
                currentPlayed = row;

                row.setStyle("-fx-background-color: #FFDC00;-fx-border-color: black; -fx-text-fill: white;");
                System.out.println("highlighting row");


            }
        });

當按下下一個按鈕時。

public void onNext() {
    if (mediaPlayer != null) {
        MediaPlayer.Status status = mediaPlayer.getStatus();
        if (status == MediaPlayer.Status.PLAYING || status == MediaPlayer.Status.PAUSED) {
            mediaPlayer.stop();
            playlist.next().orElse(0);
            playSong();
           /* Song song = playlist.getCurrentSong().get();
            File songFile = song.getFilePath().toAbsolutePath().toFile();
            currentSong = new Media(songFile.toURI().toString());
            mediaPlayer = new MediaPlayer(currentSong);
            mediaPlayer.setAutoPlay(false);
            mediaPlayer.play();
            currentSongName.setText(song.getMetadata().getSongTitle().orElse("Unknown Song"));
            playing = true;
            playButton.setText("\u23F8");*/
        } else if (status == MediaPlayer.Status.READY) {
            playlist.setCurrent(0);
            playSong();
        }
    }

該方法調用播放歌曲的實際方法,即playSongFromPlaylist,但是這里的方法有點無關緊要,因為它可以照顧好一切,實際上可以控制音樂播放器本身及其外觀。

public void playSong() {
    if (!playlist.getCurrentSong().isPresent()) {
        System.out.println("returning");
        return;
    }

    System.out.println(playlistTable.getSelectionModel().getSelectedIndex());
    int currentIndex = playlist.getCurrent().get();
    Song song = playlist.getCurrentSong().get();
    System.out.println("current index: " + currentIndex);

    playlistTable.getSelectionModel().select(currentIndex);
    selectedFromButtons = true;
    System.out.println(playlistTable.getSelectionModel().getSelectedIndex());
    playSongFromPlaylist();
}

可能最簡單的方法是為當前播放的歌曲引入一個屬性,並在項目和歌曲更改上設置(取消設置)CSS偽類:

final ObjectProperty<PlaylistTable> currentSong = new SimpleObjectProperty();
final PseudoClass playing = PseudoClass.getPseudoClass("playing");

playlistTable.setRowFactory(e -> {

    final TableRow<PlaylistTable> row = new TableRow<>();
    InvalidationListener listener = o -> {
        row.pseudoClassStateChanged(playing, currentSong.get() == row.getItem());
    };
    row.itemProperty().addListener(listener);
    currentSong.addListener(listener);

    ...

    return row;
});

通過將以下樣式表添加到場景中,可以對行進行樣式設置:

/* filled pseudoclass is important here to prevent selection
   of empty rows when no song is playing */
.table-view .table-row-cell:filled:playing {
    -fx-background-color: #FFDC00;
    -fx-border-color: black;
    -fx-text-fill: white;
}

通過設置currentSong的值,您可以突出顯示包含當前正在播放的歌曲的行。

您需要從事件處理程序中刪除樣式。 無論如何,這將無法正常工作,因為可以通過TableView修改行的item屬性。

注意:您可能還想添加不同的規則,以顯示正在播放和選擇/聚焦不同的歌曲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM