Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24186c47a9 | ||
|
|
04d776c434 | ||
|
|
783b24c82a | ||
|
|
f2a9b8021e | ||
|
|
574ef215ee | ||
|
|
06fc183025 | ||
|
|
0a1a707ab9 | ||
|
|
ef31487a02 | ||
|
|
dc60e5954f |
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -25,6 +25,12 @@
|
|||||||
<version>21</version>
|
<version>21</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-media</artifactId>
|
||||||
|
<version>17.0.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package sbu.javafx;
|
|||||||
|
|
||||||
import javafx.application.Application;
|
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) }
|
// TODO: Launch the JavaFX application by calling Application.launch(Main.class)
|
||||||
|
|
||||||
|
Application.launch(Main.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package sbu.javafx;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class Main extends Application {
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/sbu/javafx/App-view.fxml"));
|
||||||
|
Parent root = loader.load();
|
||||||
|
|
||||||
|
MusicController controller = loader.getController();
|
||||||
|
|
||||||
|
controller.musicsListView.getItems().addAll(
|
||||||
|
new Song("Blinding Lights", "The Weeknd","/musics/The-Weeknd-Blinding-Lights-128.mp3"),
|
||||||
|
new Song("Comme des enfants", "Coert De Pirate","/musics/Coeur-De-Pirate-Comme-des-enfants-128.mp3"),
|
||||||
|
new Song("Slow Down", "GRAE", "/musics/GRAE-Slow-Down-128.mp3"),
|
||||||
|
new Song("Cigarettes out the Window", "TV Girl", "/musics/TV-Girl-Cigarettes-out-the-Window-128.mp3"),
|
||||||
|
new Song("deja vu", "Olivia Rodirgo", "/musics/Olivia-Rodrigo-deja-vu-320.mp3"),
|
||||||
|
new Song("The Line", "Twoenty One Pilots", "/musics/Twenty-One-Pilots-The-Line-128.mp3"),
|
||||||
|
new Song("Bones", "Imagine Dragons", "/musics/Imagine-Dragons-Bones-128.mp3"),
|
||||||
|
new Song("Bunker", "Balthazar", "/musics/Balthazar-Bunker-128.mp3"),
|
||||||
|
new Song("As It Was", "Harry Styles", "/musics/Harry-Styles-As-It-Was-320.mp3")
|
||||||
|
);
|
||||||
|
|
||||||
|
controller.setupListView(controller.musicsListView);
|
||||||
|
controller.setupListView(controller.playlistListView);
|
||||||
|
|
||||||
|
Scene scene = new Scene(root, 500, 600);
|
||||||
|
scene.getStylesheets().add(
|
||||||
|
getClass().getResource("/css/light.css").toExternalForm()
|
||||||
|
);
|
||||||
|
|
||||||
|
primaryStage.setTitle("Music Player");
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.getIcons().add(
|
||||||
|
new Image(getClass().getResourceAsStream("/image/icon.png"))
|
||||||
|
);
|
||||||
|
primaryStage.setResizable(false);
|
||||||
|
primaryStage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
launch(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ package sbu.javafx;
|
|||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -13,9 +15,38 @@ public class MusicApp extends Application {
|
|||||||
public void start(Stage stage) throws IOException
|
public void start(Stage stage) throws IOException
|
||||||
{
|
{
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("App-view.fxml"));
|
FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("App-view.fxml"));
|
||||||
Scene scene = new Scene(fxmlLoader.load());
|
Parent root = fxmlLoader.load();
|
||||||
|
|
||||||
|
MusicController controller = fxmlLoader.getController();
|
||||||
|
|
||||||
|
controller.musicsListView.getItems().addAll(
|
||||||
|
new Song("Blinding Lights", "The Weeknd","/musics/The-Weeknd-Blinding-Lights-128.mp3"),
|
||||||
|
new Song("Comme des enfants", "Coert De Pirate","/musics/Coeur-De-Pirate-Comme-des-enfants-128.mp3"),
|
||||||
|
new Song("Slow Down", "GRAE", "/musics/GRAE-Slow-Down-128.mp3"),
|
||||||
|
new Song("Cigarettes out the Window", "TV Girl", "/musics/TV-Girl-Cigarettes-out-the-Window-128.mp3"),
|
||||||
|
new Song("deja vu", "Olivia Rodirgo", "/musics/Olivia-Rodrigo-deja-vu-320.mp3"),
|
||||||
|
new Song("The Line", "Twoenty One Pilots", "/musics/Twenty-One-Pilots-The-Line-128.mp3"),
|
||||||
|
new Song("Bones", "Imagine Dragons", "/musics/Imagine-Dragons-Bones-128.mp3"),
|
||||||
|
new Song("Bunker", "Balthazar", "/musics/Balthazar-Bunker-128.mp3"),
|
||||||
|
new Song("As It Was", "Harry Styles", "/musics/Harry-Styles-As-It-Was-320.mp3")
|
||||||
|
);
|
||||||
|
|
||||||
|
controller.setupListView(controller.musicsListView);
|
||||||
|
controller.setupListView(controller.playlistListView);
|
||||||
|
|
||||||
|
Scene scene = new Scene(root, 500, 600);
|
||||||
|
|
||||||
|
scene.getStylesheets().add(
|
||||||
|
getClass().getResource("/css/dark.css").toExternalForm()
|
||||||
|
);
|
||||||
|
|
||||||
stage.setTitle("Music Player");
|
stage.setTitle("Music Player");
|
||||||
|
stage.getIcons().add(
|
||||||
|
new Image(getClass().getResourceAsStream("/image/icon.png"))
|
||||||
|
);
|
||||||
stage.setScene(scene);
|
stage.setScene(scene);
|
||||||
|
stage.setResizable(false);
|
||||||
|
|
||||||
//TODO: add icon to the stage
|
//TODO: add icon to the stage
|
||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,363 @@
|
|||||||
package sbu.javafx;
|
package sbu.javafx;
|
||||||
|
|
||||||
|
import javafx.animation.PauseTransition;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.control.Label;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.media.Media;
|
||||||
|
import javafx.scene.media.MediaPlayer;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
|
||||||
public class MusicController {
|
public class MusicController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public ListView<Song> playlistListView;
|
||||||
|
@FXML
|
||||||
|
public ListView<Song> musicsListView;
|
||||||
|
@FXML
|
||||||
|
private VBox root;
|
||||||
|
@FXML
|
||||||
|
Label nowPlayingLabel;
|
||||||
|
@FXML
|
||||||
|
Button playPauseBtn;
|
||||||
|
@FXML
|
||||||
|
Button audioBtn;
|
||||||
|
@FXML
|
||||||
|
Button openPlaylistBtn;
|
||||||
|
@FXML
|
||||||
|
Button themeToggleBtn;
|
||||||
|
@FXML
|
||||||
|
Button nextBtn;
|
||||||
|
@FXML
|
||||||
|
Button preveBtn;
|
||||||
|
@FXML
|
||||||
|
Button repeatBtn;
|
||||||
|
@FXML
|
||||||
|
private Label messageLabel;
|
||||||
|
private boolean isDarkMode=true;
|
||||||
|
private boolean isPlaying=false;
|
||||||
|
private boolean isMute=false;
|
||||||
|
private boolean isOpen=false;
|
||||||
|
private boolean isRepeat=false;
|
||||||
|
private Song currentSong = null;
|
||||||
|
ImageView playIcon;
|
||||||
|
ImageView pauseIcon;
|
||||||
|
ImageView audioIcon;
|
||||||
|
ImageView muteIcon;
|
||||||
|
|
||||||
|
String path;
|
||||||
|
Media media;
|
||||||
|
MediaPlayer player ;
|
||||||
|
|
||||||
// TODO: Define your UI components using the @FXML annotation.
|
// TODO: Define your UI components using the @FXML annotation.
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
Image playImg = new Image(getClass().getResourceAsStream("/image/play.png"));
|
||||||
|
Image pauseImg = new Image(getClass().getResourceAsStream("/image/pause.png"));
|
||||||
|
Image audioImg= new Image(getClass().getResourceAsStream("/image/icons8-audio-64.png"));
|
||||||
|
Image muteImg= new Image(getClass().getResourceAsStream("/image/icons8-mute-64.png"));
|
||||||
|
|
||||||
|
playIcon = new ImageView(playImg);
|
||||||
|
pauseIcon = new ImageView(pauseImg);
|
||||||
|
audioIcon= new ImageView(audioImg);
|
||||||
|
muteIcon= new ImageView(muteImg);
|
||||||
|
|
||||||
|
playIcon.setFitWidth(35);
|
||||||
|
playIcon.setFitHeight(35);
|
||||||
|
pauseIcon.setFitWidth(35);
|
||||||
|
pauseIcon.setFitHeight(35);
|
||||||
|
audioIcon.setFitWidth(35);
|
||||||
|
audioIcon.setFitHeight(35);
|
||||||
|
muteIcon.setFitWidth(35);
|
||||||
|
muteIcon.setFitHeight(35);
|
||||||
|
|
||||||
|
playPauseBtn.setGraphic(playIcon);
|
||||||
|
|
||||||
|
nextBtn.setOnAction(e ->{
|
||||||
|
|
||||||
|
player.pause();
|
||||||
|
|
||||||
|
if(isOpen) {
|
||||||
|
currentSong=playlistListView.getItems().get(findIndex(playlistListView,currentSong)+1);
|
||||||
|
setPlayer(currentSong).play();
|
||||||
|
}else{
|
||||||
|
currentSong=musicsListView.getItems().get(findIndex(musicsListView,currentSong)+1);
|
||||||
|
setPlayer(currentSong).play();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
preveBtn.setOnAction(e ->{
|
||||||
|
|
||||||
|
player.pause();
|
||||||
|
|
||||||
|
if(isOpen) {
|
||||||
|
currentSong=playlistListView.getItems().get(findIndex(playlistListView,currentSong)-1);
|
||||||
|
setPlayer(currentSong).play();
|
||||||
|
}else{
|
||||||
|
currentSong=musicsListView.getItems().get(findIndex(musicsListView,currentSong)-1);
|
||||||
|
setPlayer(currentSong).play();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
repeatBtn.setOnAction(e->{
|
||||||
|
if(!isRepeat){
|
||||||
|
repeatBtn.setStyle(
|
||||||
|
"-fx-border-color: blue;" +
|
||||||
|
"-fx-border-width: 2px;" +
|
||||||
|
"-fx-border-radius: 100em;"
|
||||||
|
);
|
||||||
|
isRepeat=true;
|
||||||
|
}else{
|
||||||
|
repeatBtn.setStyle("-fx-border-color: transparent;");
|
||||||
|
isRepeat=false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupListView(ListView<Song> listView) {
|
||||||
|
|
||||||
|
listView.setCellFactory(param -> new ListCell<Song>() {
|
||||||
|
@Override
|
||||||
|
protected void updateItem(Song song, boolean empty) {
|
||||||
|
super.updateItem(song, empty);
|
||||||
|
|
||||||
|
if (empty || song == null) {
|
||||||
|
setText(null);
|
||||||
|
setGraphic(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label nameLabel = new Label(song.getName());
|
||||||
|
nameLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 14px;");
|
||||||
|
|
||||||
|
Label singerLabel = new Label(song.getSinger());
|
||||||
|
singerLabel.setStyle("-fx-text-fill: gray; -fx-font-size: 12px;");
|
||||||
|
|
||||||
|
VBox songInfo = new VBox(3);
|
||||||
|
songInfo.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
songInfo.getChildren().addAll(nameLabel, singerLabel);
|
||||||
|
|
||||||
|
Button addToPlaylistBtn = new Button("Add to playlist");
|
||||||
|
addToPlaylistBtn.getStyleClass().add("playlist-button");
|
||||||
|
addToPlaylistBtn.setOnAction(e -> {
|
||||||
|
addToPlaylist(e, song);
|
||||||
|
});
|
||||||
|
|
||||||
|
Button playBtn = new Button("Play");
|
||||||
|
playBtn.getStyleClass().add("play-button");
|
||||||
|
playBtn.setOnAction(e -> {
|
||||||
|
play(e, song);
|
||||||
|
});
|
||||||
|
|
||||||
|
HBox row = new HBox(10);
|
||||||
|
row.setPadding(new Insets(10));
|
||||||
|
row.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
Region spacer = new Region();
|
||||||
|
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||||
|
|
||||||
|
row.getChildren().addAll(songInfo, spacer, playBtn, addToPlaylistBtn);
|
||||||
|
|
||||||
|
setGraphic(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void toggleTheme(ActionEvent event) {
|
||||||
|
if (isDarkMode) {
|
||||||
|
themeToggleBtn.setText("Dark");
|
||||||
|
changeTheme();
|
||||||
|
isDarkMode = false;
|
||||||
|
} else {
|
||||||
|
themeToggleBtn.setText("Light");
|
||||||
|
changeTheme();
|
||||||
|
isDarkMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeTheme(){
|
||||||
|
Scene scene = root.getScene();
|
||||||
|
scene.getStylesheets().clear();
|
||||||
|
|
||||||
|
if(isDarkMode){
|
||||||
|
scene.getStylesheets().add(
|
||||||
|
getClass().getResource("/css/dark.css").toExternalForm()
|
||||||
|
);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
scene.getStylesheets().add(
|
||||||
|
getClass().getResource("/css/light.css").toExternalForm()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
isDarkMode=!isDarkMode;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing.
|
//TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing.
|
||||||
|
|
||||||
|
|
||||||
|
public MediaPlayer setPlayer(Song song) {//این تابع برای ست کردن مدیای در حال پخشه
|
||||||
|
|
||||||
|
nowPlayingLabel.setText(song.getName());
|
||||||
|
|
||||||
|
path = getClass()
|
||||||
|
.getResource(song.getPath())
|
||||||
|
.toExternalForm();
|
||||||
|
media = new Media(path);
|
||||||
|
player = new MediaPlayer(media);
|
||||||
|
|
||||||
|
//این برا اینه که تموم شد بره بعدی
|
||||||
|
player.setOnEndOfMedia(() -> {
|
||||||
|
if(isRepeat){
|
||||||
|
player.seek(player.getStartTime());
|
||||||
|
player.play();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nextBtn.fire();
|
||||||
|
});
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(ActionEvent event, Song song){
|
||||||
|
|
||||||
|
currentSong = song;
|
||||||
|
|
||||||
|
if(player != null){
|
||||||
|
player.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
setPlayer(currentSong);
|
||||||
|
|
||||||
|
player.play();
|
||||||
|
|
||||||
|
isPlaying = true;
|
||||||
|
|
||||||
|
playPauseBtn.setGraphic(pauseIcon);
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void handlePlayAction() {
|
public void playPause(ActionEvent a){
|
||||||
//Update labels, change button icons, etc.
|
|
||||||
|
if(player == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isPlaying){
|
||||||
|
playPauseBtn.setGraphic(playIcon);
|
||||||
|
|
||||||
|
player.pause();
|
||||||
|
isPlaying = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
playPauseBtn.setGraphic(pauseIcon);
|
||||||
|
|
||||||
|
player.play();
|
||||||
|
isPlaying = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void mute(ActionEvent e){
|
||||||
|
if(!isMute){
|
||||||
|
audioBtn.setGraphic(muteIcon);
|
||||||
|
player.setVolume(0);
|
||||||
|
isMute=true;
|
||||||
|
}else{
|
||||||
|
audioBtn.setGraphic(audioIcon);
|
||||||
|
player.setVolume(100);
|
||||||
|
isMute=false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Logic to add a specific song to the user's playlist.
|
//TODO: Logic to add a specific song to the user's playlist.
|
||||||
|
|
||||||
public void addToPlaylist(String songName) {
|
public void addToPlaylist(ActionEvent event, Song song) {
|
||||||
//Add the song to a list or update a ListView.
|
//Add the song to a list or update a ListView.
|
||||||
|
playlistListView.getItems().add(song);
|
||||||
|
|
||||||
|
messageLabel.setText("Added to playlist!");
|
||||||
|
messageLabel.setVisible(true);
|
||||||
|
|
||||||
|
PauseTransition pause = new PauseTransition(Duration.seconds(2));
|
||||||
|
|
||||||
|
pause.setOnFinished(e -> {
|
||||||
|
messageLabel.setVisible(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
pause.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:This method should open a new window or change the current scene to display the "Playlist" page.
|
// TODO:This method should open a new window or change the current scene to display the "Playlist" page.
|
||||||
|
|
||||||
public void openPlaylistWindow() {
|
public void openPlaylistWindow(ActionEvent e) {
|
||||||
//Create a new stage and show the playlist UI.
|
|
||||||
|
if(isPlaying) {
|
||||||
|
playPause(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isOpen){
|
||||||
|
// باز کردن پلی لیست
|
||||||
|
if(playlistListView.getItems().isEmpty()){
|
||||||
|
|
||||||
|
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||||
|
|
||||||
|
alert.setTitle("Empty Playlist");
|
||||||
|
alert.setHeaderText(null);
|
||||||
|
alert.setContentText("Playlist is empty!");
|
||||||
|
|
||||||
|
alert.showAndWait();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOpen = true;
|
||||||
|
|
||||||
|
openPlaylistBtn.setText("Back");
|
||||||
|
|
||||||
|
musicsListView.setVisible(false);
|
||||||
|
musicsListView.setManaged(false);
|
||||||
|
|
||||||
|
playlistListView.setVisible(true);
|
||||||
|
playlistListView.setManaged(true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// برگشت به صفحه اصلی
|
||||||
|
isOpen = false;
|
||||||
|
|
||||||
|
openPlaylistBtn.setText("Open Playlist");
|
||||||
|
|
||||||
|
musicsListView.setVisible(true);
|
||||||
|
musicsListView.setManaged(true);
|
||||||
|
|
||||||
|
playlistListView.setVisible(false);
|
||||||
|
playlistListView.setManaged(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int findIndex(ListView<Song> listView, Song song){
|
||||||
|
for(int i = 0; i < listView.getItems().size(); i++){
|
||||||
|
|
||||||
|
if(listView.getItems().get(i).equals(song)){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package sbu.javafx;
|
||||||
|
|
||||||
|
public class Song {
|
||||||
|
private String name;
|
||||||
|
private String singer;
|
||||||
|
private String path;
|
||||||
|
public Song(String name, String singer, String path)
|
||||||
|
{
|
||||||
|
this.name=name;
|
||||||
|
this.singer=singer;
|
||||||
|
this.path=path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public String getSinger() {
|
||||||
|
return singer;
|
||||||
|
}
|
||||||
|
public String getPath(){return path;}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
.root{
|
||||||
|
-fx-background-color: #0f172a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label{
|
||||||
|
-fx-text-fill: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button{
|
||||||
|
-fx-background-color: #334155;;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
-fx-background-radius: 14px;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover{
|
||||||
|
-fx-background-color: #475569;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-view{
|
||||||
|
-fx-background-color: #111827;
|
||||||
|
-fx-control-inner-background: #111827;
|
||||||
|
-fx-background-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-cell{
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-cell:selected{
|
||||||
|
-fx-background-color: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.circle-button{
|
||||||
|
|
||||||
|
-fx-background-color: #dbeafe;
|
||||||
|
|
||||||
|
-fx-background-radius: 100em;
|
||||||
|
-fx-background-insets: 0;
|
||||||
|
|
||||||
|
-fx-padding: 0;
|
||||||
|
|
||||||
|
-fx-pref-width: 34px;
|
||||||
|
-fx-pref-height: 34px;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
.root{
|
||||||
|
-fx-background-color: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label{
|
||||||
|
-fx-text-fill: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button{
|
||||||
|
-fx-background-color: #dbeafe;
|
||||||
|
-fx-text-fill: #1e3a8a;
|
||||||
|
-fx-background-radius: 14px;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover{
|
||||||
|
-fx-background-color: #bfdbfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-view{
|
||||||
|
-fx-background-color: #ffffff;
|
||||||
|
-fx-control-inner-background: #ffffff;
|
||||||
|
-fx-background-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-cell{
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-cell:selected {
|
||||||
|
-fx-background-color: #93c5fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.circle-button{
|
||||||
|
|
||||||
|
-fx-background-color: #dbeafe;
|
||||||
|
|
||||||
|
-fx-background-radius: 100em;
|
||||||
|
-fx-background-insets: 0;
|
||||||
|
|
||||||
|
-fx-padding: 0;
|
||||||
|
|
||||||
|
-fx-pref-width: 35px;
|
||||||
|
-fx-pref-height: 35px;
|
||||||
|
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,8 +1,106 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.geometry.*?>
|
||||||
<VBox xmlns="http://javafx.com/fxml" alignment="CENTER" spacing="10">
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
<!-- TODO: Add your code here! -->
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.image.Image?>
|
||||||
|
<VBox fx:id="root" spacing="10" xmlns="http://javafx.com/javafx/17.0.12" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sbu.javafx.MusicController">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="10" left="10" right="10" top="10" />
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
<!-- دکمه تغییر تم و open playlist -->
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="10">
|
||||||
|
|
||||||
|
<Button fx:id="themeToggleBtn"
|
||||||
|
text="Dark"
|
||||||
|
onAction="#toggleTheme"/>
|
||||||
|
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
|
||||||
|
<Button fx:id="openPlaylistBtn"
|
||||||
|
onAction="#openPlaylistWindow"
|
||||||
|
text="Open Playlist"
|
||||||
|
style="-fx-background-radius: 15px;" />
|
||||||
|
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<Label fx:id="messageLabel"
|
||||||
|
textFill="green"
|
||||||
|
visible="false"/>
|
||||||
|
|
||||||
|
<!--آهنگ های موجود -->
|
||||||
|
<ListView fx:id="musicsListView" VBox.vgrow="ALWAYS"/>
|
||||||
|
|
||||||
|
<!-- آهنگ های پلی لیست-->
|
||||||
|
<ListView fx:id="playlistListView"
|
||||||
|
visible="false"
|
||||||
|
managed="false"
|
||||||
|
VBox.vgrow="ALWAYS"/>
|
||||||
|
|
||||||
|
<!-- باکس آهنگ در حال پخش -->
|
||||||
|
<VBox alignment="CENTER" spacing="5">
|
||||||
|
|
||||||
|
<Label fx:id="nowPlayingLabel"
|
||||||
|
text="No song playing"/>
|
||||||
|
|
||||||
|
<HBox alignment="CENTER" spacing="20">
|
||||||
|
<!-- دکمههای جلو عقب -->
|
||||||
|
<Button fx:id="audioBtn"
|
||||||
|
onAction="#mute"
|
||||||
|
styleClass="circle-button">
|
||||||
|
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="35" fitHeight="35">
|
||||||
|
<Image url="/image/icons8-audio-64.png" />
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button fx:id="preveBtn"
|
||||||
|
styleClass="circle-button">
|
||||||
|
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="35" fitHeight="35">
|
||||||
|
<Image url="/image/icons8-skip-to-start-64.png" />
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
<Button fx:id="playPauseBtn"
|
||||||
|
onAction="#playPause"
|
||||||
|
styleClass="circle-button">
|
||||||
|
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="35" fitHeight="35">
|
||||||
|
<Image url="/image/pause.png" />
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
<Button fx:id="nextBtn"
|
||||||
|
styleClass="circle-button">
|
||||||
|
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="35" fitHeight="35">
|
||||||
|
<Image url="/image/icons8-end-64.png" />
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button fx:id="repeatBtn"
|
||||||
|
styleClass="circle-button">
|
||||||
|
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="35" fitHeight="35">
|
||||||
|
<Image url="/image/icons8-synchronize-64.png" />
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</HBox>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
</VBox>
|
||||||