9 Commits
Author SHA1 Message Date
mohammadreza 437ba68405 add PlaylistController.java 2026-05-27 11:32:44 -07:00
mohammadreza ae8efc62f0 add Playlist.fxml 2026-05-27 11:32:02 -07:00
mohammadreza e51de99ebe add Song.java 2026-05-27 11:31:20 -07:00
mohammadreza 70d8d94145 implement App-view.fxml 2026-05-27 11:30:21 -07:00
mohammadreza 23108b39cf implement MusicController.java 2026-05-27 11:29:11 -07:00
mohammadreza 0357013292 implement MusicApp.java 2026-05-27 11:28:07 -07:00
mohammadreza e6fb142e41 implement Launcher.java 2026-05-27 11:27:23 -07:00
mohammadreza 92a4c34d48 add three Song.mp3 2026-05-27 11:26:20 -07:00
mohammadreza 5a94ae8cec deps: add javafx-media dependency to pom.xml 2026-05-27 11:23:34 -07:00
11 changed files with 271 additions and 17 deletions
+5
View File
@@ -14,6 +14,11 @@
<junit.version>5.10.2</junit.version> </properties> <junit.version>5.10.2</junit.version> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>21.0.4</version>
</dependency>
<dependency> <dependency>
<groupId>org.openjfx</groupId> <groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId> <artifactId>javafx-controls</artifactId>
+3 -1
View File
@@ -4,5 +4,7 @@ import javafx.application.Application;
public class Launcher{ public class Launcher{
public static void main(String[] args) { public static void main(String[] args) {
// TODO: Launch the JavaFX application by calling Application.launch(Main.class) }
Application.launch(MusicApp.class);
}
} }
-1
View File
@@ -16,7 +16,6 @@ public class MusicApp extends Application {
Scene scene = new Scene(fxmlLoader.load()); Scene scene = new Scene(fxmlLoader.load());
stage.setTitle("Music Player"); stage.setTitle("Music Player");
stage.setScene(scene); stage.setScene(scene);
//TODO: add icon to the stage
stage.show(); stage.show();
} }
+142 -13
View File
@@ -1,31 +1,160 @@
package sbu.javafx; package sbu.javafx;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.event.ActionEvent; import javafx.fxml.FXMLLoader;
import javafx.scene.control.Label; import javafx.scene.Parent;
import javafx.scene.input.MouseEvent; import javafx.scene.Scene;
import javafx.scene.layout.VBox; 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 { public class MusicController {
// TODO: Define your UI components using the @FXML annotation. @FXML private Label nowPlayingLabel;
@FXML private TableView<Song> songsTable;
@FXML private TableColumn<Song, String> titleCol;
@FXML private TableColumn<Song, String> artistCol;
@FXML private TableColumn<Song, String> durationCol;
//TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing. // There is no connection between Song and Button so we should use void
@FXML private TableColumn<Song, Void> addCol;
@FXML private TableColumn<Song, Void> playCol;
private Song nowPlayingSong = null;
private final ObservableList<Song> 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<Song> 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 @FXML
public void handlePlayAction() { public void handlePlayAction() {
//Update labels, change button icons, etc. 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();
}
} }
//TODO: Logic to add a specific song to the user's playlist.
public void addToPlaylist(String songName) { public void addToPlaylist(Song song) {
//Add the song to a list or update a ListView. if (!playlist.contains(song)) {
playlist.add(song);
song.setAdded(true);
songsTable.refresh();
}
} }
// TODO:This method should open a new window or change the current scene to display the "Playlist" page.
public void openPlaylistWindow() { public void openPlaylistWindow() {
//Create a new stage and show the playlist UI. 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();
}
} }
} }
@@ -0,0 +1,31 @@
package sbu.javafx;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class PlaylistController {
@FXML public TableView<Song> playListTable;
@FXML public TableColumn<Song, String> titleCol;
@FXML public TableColumn<Song, String> artistCol;
@FXML public TableColumn<Song, String> durationCol;
private ObservableList<Song> playlist;
@FXML
public void initialize() {
titleCol.setCellValueFactory(new PropertyValueFactory<>("title"));
artistCol.setCellValueFactory(new PropertyValueFactory<>("artistName"));
durationCol.setCellValueFactory(new PropertyValueFactory<>("duration"));
}
public void setPlaylist(ObservableList<Song> playlist) {
this.playlist = playlist;
playListTable.setItems(this.playlist);
}
}
+42
View File
@@ -0,0 +1,42 @@
package sbu.javafx;
public class Song {
private String Title;
private String ArtistName;
private String Duration;
private boolean added;
private String FilePath;
public Song(String title, String artistName, String duration, String filePath) {
this.Title = title;
this.ArtistName = artistName;
this.Duration = duration;
this.added = false;
this.FilePath = filePath;
}
public String getTitle() {
return Title;
}
public String getArtistName() {
return ArtistName;
}
public String getDuration() {
return Duration;
}
public boolean isAdded() {
return added;
}
public void setAdded(boolean added) {
this.added = added;
}
public String getFilePath() {
return FilePath;
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+32 -2
View File
@@ -1,8 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/fxml" alignment="CENTER" spacing="10"> <?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<!-- TODO: Add your code here! --> <VBox xmlns:fx="http://javafx.com/fxml" alignment="CENTER" spacing="10" fx:controller="sbu.javafx.MusicController">
<padding><Insets right="30" left="30" bottom="20"/></padding>
<Label text="Music Player" styleClass="title"/>
<VBox styleClass="box" spacing="10">
<padding><Insets top="10" right="10" bottom="10" left="10"/></padding>
<TableView fx:id="songsTable" prefHeight="420">
<columns>
<TableColumn fx:id="titleCol" text="Song Title" prefWidth="220"/>
<TableColumn fx:id="artistCol" text="Artist Name" prefWidth="220"/>
<TableColumn fx:id="durationCol" text="Duration" prefWidth="120"/>
<TableColumn fx:id="addCol" text="Add to Playlist" prefWidth="200"/>
<TableColumn fx:id="playCol" text="Play" prefWidth="120"/>
</columns>
</TableView>
</VBox>
<HBox styleClass="box" spacing="10" alignment="CENTER_LEFT">
<padding><Insets top="16" right="16" bottom="16" left="16"/></padding>
<Label text="Now Playing: " />
<Label fx:id="nowPlayingLabel" text="-"/>
<Pane HBox.hgrow="ALWAYS"/>
<Button fx:id="playListButton" text="Open Playlist" onAction="#openPlaylistWindow"/>
</HBox>
</VBox> </VBox>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<VBox xmlns:fx="http://javafx.com/fxml" alignment="CENTER" spacing="10" fx:controller="sbu.javafx.PlaylistController" >
<Label text="Playlist" styleClass="title"/>
<TableView fx:id="playListTable">
<columns>
<TableColumn fx:id="titleCol" text="Song Name" prefWidth="150" />
<TableColumn fx:id="artistCol" text="Artist Name" prefWidth="150" />
<TableColumn fx:id="durationCol" text="Duration" prefWidth="100" />
</columns>
</TableView>
</VBox>