From 0b68b084df1ceba692e4ce11ab43fe7a0c81983c Mon Sep 17 00:00:00 2001 From: Soroush Date: Fri, 12 Jun 2026 19:15:02 +0330 Subject: [PATCH] Assignment-7 --- pom.xml | 5 + src/main/java/sbu/javafx/Launcher.java | 5 +- src/main/java/sbu/javafx/MusicApp.java | 7 +- src/main/java/sbu/javafx/MusicController.java | 163 ++++++++++++++++-- src/main/resources/sbu/javafx/App-view.fxml | 86 ++++++++- .../resources/sbu/javafx/Playlist-view.fxml | 93 ++++++++++ src/main/resources/sbu/javafx/dark.css | 24 +++ src/main/resources/sbu/javafx/style.css | 30 ++++ 8 files changed, 390 insertions(+), 23 deletions(-) create mode 100644 src/main/resources/sbu/javafx/Playlist-view.fxml create mode 100644 src/main/resources/sbu/javafx/dark.css create mode 100644 src/main/resources/sbu/javafx/style.css diff --git a/pom.xml b/pom.xml index e45147d..3eb32ec 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,11 @@ javafx-controls 21 + + org.openjfx + javafx-media + 21 + org.openjfx javafx-fxml diff --git a/src/main/java/sbu/javafx/Launcher.java b/src/main/java/sbu/javafx/Launcher.java index c288d10..06d78e7 100644 --- a/src/main/java/sbu/javafx/Launcher.java +++ b/src/main/java/sbu/javafx/Launcher.java @@ -2,7 +2,8 @@ package sbu.javafx; import javafx.application.Application; -public class Launcher{ +public class Launcher { public static void main(String[] args) { - // TODO: Launch the JavaFX application by calling Application.launch(Main.class) } + Application.launch(MusicApp.class); + } } diff --git a/src/main/java/sbu/javafx/MusicApp.java b/src/main/java/sbu/javafx/MusicApp.java index a50badc..787b7e7 100644 --- a/src/main/java/sbu/javafx/MusicApp.java +++ b/src/main/java/sbu/javafx/MusicApp.java @@ -10,14 +10,11 @@ import java.io.IOException; public class MusicApp extends Application { @Override - public void start(Stage stage) throws IOException - { + public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("App-view.fxml")); Scene scene = new Scene(fxmlLoader.load()); stage.setTitle("Music Player"); stage.setScene(scene); - //TODO: add icon to the stage stage.show(); } - -} +} \ No newline at end of file diff --git a/src/main/java/sbu/javafx/MusicController.java b/src/main/java/sbu/javafx/MusicController.java index 5da27a9..6e343b2 100644 --- a/src/main/java/sbu/javafx/MusicController.java +++ b/src/main/java/sbu/javafx/MusicController.java @@ -1,31 +1,168 @@ package sbu.javafx; import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; import javafx.event.ActionEvent; -import javafx.scene.control.Label; -import javafx.scene.input.MouseEvent; +import javafx.scene.Parent; +import javafx.stage.Stage; +import javafx.scene.Node; import javafx.scene.layout.VBox; +import javafx.scene.layout.HBox; +import javafx.scene.layout.BorderPane; +import javafx.scene.control.Button; +import javafx.scene.control.Label; + +import java.util.ArrayList; +import java.util.List; public class MusicController { - // TODO: Define your UI components using the @FXML annotation. + @FXML private BorderPane mainContainer; + @FXML private BorderPane playlistContainer; + @FXML private Button themeButton; + @FXML private Label emptyLabel; + @FXML private Label nowPlayingLabel; + + @FXML private Button mainPlay1, mainPlay2, mainPlay3; + @FXML private Button mainAdd1, mainAdd2, mainAdd3; + + @FXML private VBox playlistTable; + @FXML private HBox playlistRow1, playlistRow2, playlistRow3; + @FXML private Button playlistPlay1, playlistPlay2, playlistPlay3; + + private static final List myPlaylist = new ArrayList<>(); + private static String currentSongName = "-"; + private static boolean isDark = false; - //TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing. @FXML - public void handlePlayAction() { - //Update labels, change button icons, etc. + public void initialize() { + if (nowPlayingLabel != null) { + nowPlayingLabel.setText("Now Playing: " + currentSongName); + } + refreshButtons(); + refreshPlaylist(); + refreshTheme(); } - //TODO: Logic to add a specific song to the user's playlist. + private void refreshButtons() { + if (mainContainer == null) return; - public void addToPlaylist(String songName) { - //Add the song to a list or update a ListView. + mainPlay1.setText("Familiar".equals(currentSongName) ? "Stop" : "Play"); + mainPlay2.setText("Reminder".equals(currentSongName) ? "Stop" : "Play"); + mainPlay3.setText("Spotlight".equals(currentSongName) ? "Stop" : "Play"); + + mainAdd1.setText(myPlaylist.contains("Familiar") ? "Remove from Playlist" : "Add to Playlist"); + mainAdd2.setText(myPlaylist.contains("Reminder") ? "Remove from Playlist" : "Add to Playlist"); + mainAdd3.setText(myPlaylist.contains("Spotlight") ? "Remove from Playlist" : "Add to Playlist"); } - // TODO:This method should open a new window or change the current scene to display the "Playlist" page. + private void refreshPlaylist() { + if (playlistTable == null) return; - public void openPlaylistWindow() { - //Create a new stage and show the playlist UI. + boolean isEmpty = myPlaylist.isEmpty(); + emptyLabel.setVisible(isEmpty); + emptyLabel.setManaged(isEmpty); + playlistTable.setVisible(!isEmpty); + playlistTable.setManaged(!isEmpty); + + if (isEmpty) return; + + playlistTable.getChildren().removeAll(playlistRow1, playlistRow2, playlistRow3); + + for (String song : myPlaylist) { + if ("Familiar".equals(song)) { + activateRow(playlistRow1, playlistPlay1, song); + } + else if ("Reminder".equals(song)) { + activateRow(playlistRow2, playlistPlay2, song); + } + else if ("Spotlight".equals(song)) { + activateRow(playlistRow3, playlistPlay3, song); + } + } } -} + + private void refreshTheme() { + Parent activeContainer = (mainContainer != null) ? mainContainer : playlistContainer; + if (activeContainer == null) return; + + String darkCss = getClass().getResource("dark.css").toExternalForm(); + + if (isDark) { + activeContainer.getStylesheets().add(darkCss); + themeButton.setText("Light Mode"); + } else { + activeContainer.getStylesheets().remove(darkCss); + themeButton.setText("Dark Mode"); + } + } + + private void activateRow(HBox row, Button playBtn, String songName) { + playlistTable.getChildren().add(row); + row.setVisible(true); + row.setManaged(true); + playBtn.setText(songName.equals(currentSongName) ? "Stop" : "Play"); + } + + @FXML + public void playMusic(ActionEvent event) { + Button clickedButton = (Button) event.getSource(); + String songName = (String) clickedButton.getUserData(); + + currentSongName = songName.equals(currentSongName) ? "-" : songName; + + if (nowPlayingLabel != null) { + nowPlayingLabel.setText("Now Playing: " + currentSongName); + } + refreshPlaylist(); + refreshButtons(); + } + + @FXML + public void addToPlaylist(ActionEvent event) { + Button btn = (Button) event.getSource(); + String songName = (String) btn.getUserData(); + + if (myPlaylist.contains(songName)) { + myPlaylist.remove(songName); + } else { + myPlaylist.add(songName); + } + refreshButtons(); + } + + @FXML + public void RemoveFromPlaylist(ActionEvent event) { + Button btn = (Button) event.getSource(); + String songName = (String) btn.getUserData(); + + myPlaylist.remove(songName); + refreshPlaylist(); + } + + + @FXML public void openPlaylist(ActionEvent event) { + switchScene(event, "Playlist-view.fxml"); + } + + @FXML public void closePlaylist(ActionEvent event) { + switchScene(event, "App-view.fxml"); + } + + private void switchScene(ActionEvent event, String fxml) { + try { + Parent root = FXMLLoader.load(getClass().getResource(fxml)); + Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); + stage.getScene().setRoot(root); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @FXML + public void toggleTheme() { + isDark = !isDark; + refreshTheme(); + } +} \ No newline at end of file diff --git a/src/main/resources/sbu/javafx/App-view.fxml b/src/main/resources/sbu/javafx/App-view.fxml index 306c8d3..e141909 100644 --- a/src/main/resources/sbu/javafx/App-view.fxml +++ b/src/main/resources/sbu/javafx/App-view.fxml @@ -1,8 +1,88 @@ + - + + + + + - + + + + - + + + + + +