[英]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.