package sbu.javafx; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import javafx.stage.Stage; import java.io.IOException; public class MusicController { @FXML private Label nowPlayingLabel; @FXML private TableView songsTable; @FXML private TableColumn titleCol; @FXML private TableColumn artistCol; @FXML private TableColumn durationCol; // There is no connection between Song and Button so we should use void @FXML private TableColumn addCol; @FXML private TableColumn playCol; private Song nowPlayingSong = null; private final ObservableList playlist = FXCollections.observableArrayList(); private MediaPlayer mediaPlayer; @FXML public void initialize() { // connect song name,artist name,duration to song class titleCol.setCellValueFactory(new PropertyValueFactory<>("title")); artistCol.setCellValueFactory(new PropertyValueFactory<>("artistName")); durationCol.setCellValueFactory(new PropertyValueFactory<>("duration")); // Add button addCol.setCellFactory(param -> new TableCell<>() { private final Button btn = new Button("Add"); { btn.getStyleClass().add("add-button"); btn.setOnAction(event -> { Song song = getTableView().getItems().get(getIndex()); addToPlaylist(song); }); } @Override protected void updateItem(Void item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); setText(null); } else { Song song = getTableView().getItems().get(getIndex()); if (song.isAdded()) { setGraphic(null); setText("Added ✓"); setStyle("-fx-text-fill: #2ecc71; -fx-font-weight: bold;"); } else { setGraphic(btn); setText(null); setStyle(""); } } } }); // Play button cell playCol.setCellFactory(param -> new TableCell<>() { private final Button btn = new Button("Play"); { btn.setOnAction(e -> { nowPlayingSong = getTableView().getItems().get(getIndex()); handlePlayAction(); }); } @Override protected void updateItem(Void item, boolean empty) { super.updateItem(item, empty); setGraphic(empty ? null : btn); } }); ObservableList songList = FXCollections.observableArrayList( new Song("Vasiat2", "Naaji", "5:26", "/Musics/Naaji.mp3"), new Song("SogandBe", "Unknown", "1:55", "/Musics/SogandBe.mp3"), new Song("Telo", "Hossein", "3:07", "/Musics/Telo.mp3") ); songsTable.setItems(songList); } @FXML public void handlePlayAction() { if (nowPlayingSong == null) return; try { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.dispose(); } String filePath = nowPlayingSong.getFilePath(); var resource = getClass().getResource(filePath); if (resource == null) { System.out.println("Error: File not found in resource path! Path checked: " + filePath); return; } String mediaUrl = resource.toExternalForm(); Media media = new Media(mediaUrl); mediaPlayer = new MediaPlayer(media); nowPlayingLabel.setText(nowPlayingSong.getTitle() + " - " + nowPlayingSong.getArtistName()); mediaPlayer.play(); } catch (Exception e) { System.out.println("Error while playing audio file: "); e.printStackTrace(); } } public void addToPlaylist(Song song) { if (!playlist.contains(song)) { playlist.add(song); song.setAdded(true); songsTable.refresh(); } } public void openPlaylistWindow() { try { FXMLLoader loader = new FXMLLoader(getClass().getResource("Playlist.fxml")); Parent root = loader.load(); PlaylistController controller = loader.getController(); controller.setPlaylist(playlist); Stage stage = new Stage(); stage.setTitle("Playlist"); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } catch (IOException e) { e.printStackTrace(); } } }