forked from AdvancedProgramming1404/HW-07-JavaFX
MusicPlayer
This commit is contained in:
@@ -36,7 +36,13 @@
|
|||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency> </dependencies>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-media</artifactId>
|
||||||
|
<version>21</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ 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) }
|
|
||||||
|
Application.launch(MusicApp.class, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,21 +3,40 @@ package sbu.javafx;
|
|||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
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;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MusicApp extends Application {
|
public class MusicApp extends Application {
|
||||||
|
|
||||||
@Override
|
@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"));
|
FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("App-view.fxml"));
|
||||||
Scene scene = new Scene(fxmlLoader.load());
|
Scene scene = new Scene(fxmlLoader.load());
|
||||||
stage.setTitle("Music Player");
|
stage.setTitle("Music Player");
|
||||||
stage.setScene(scene);
|
|
||||||
//TODO: add icon to the stage
|
|
||||||
stage.show();
|
try {
|
||||||
|
|
||||||
|
var iconUrl = MusicApp.class.getResource("/icon.png");
|
||||||
|
if (iconUrl != null) {
|
||||||
|
stage.getIcons().add(new Image(iconUrl.toExternalForm()));
|
||||||
|
} else {
|
||||||
|
System.out.println("فایل آیکون در پوشه resources پیدا نشد!");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Image icon = new Image(Objects.requireNonNull(MusicApp.class.getResourceAsStream("/icon.png")));
|
||||||
|
stage.getIcons().add(icon);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Icon not found. Please add icon.png to resources.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,97 @@
|
|||||||
package sbu.javafx;
|
package sbu.javafx;
|
||||||
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.scene.media.Media;
|
||||||
|
import javafx.scene.media.MediaPlayer;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
|
||||||
public class MusicController {
|
public class MusicController {
|
||||||
|
|
||||||
// TODO: Define your UI components using the @FXML annotation.
|
@FXML private Label statusLabel;
|
||||||
|
private static final ObservableList<String> playlist = FXCollections.observableArrayList();
|
||||||
//TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing.
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void handlePlayAction() {
|
public void handlePlayAction(ActionEvent event) {
|
||||||
//Update labels, change button icons, etc.
|
|
||||||
|
Button clickedButton = (Button) event.getSource();
|
||||||
|
String songName = (String) clickedButton.getUserData();
|
||||||
|
statusLabel.setText("Now Playing: " + songName);
|
||||||
|
|
||||||
|
if (mediaPlayer != null) {
|
||||||
|
mediaPlayer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Logic to add a specific song to the user's playlist.
|
// پیدا کردن فایل آهنگ و پخش آن
|
||||||
|
String fileName = mapSongToFileName(songName);
|
||||||
|
try {
|
||||||
|
// نکته: فایلها باید در پوشه resources باشند
|
||||||
|
String path = getClass().getResource("/" + fileName).toExternalForm();
|
||||||
|
Media media = new Media(path);
|
||||||
|
mediaPlayer = new MediaPlayer(media);
|
||||||
|
|
||||||
public void addToPlaylist(String songName) {
|
// فراخوانی متد تنظیم تایمر
|
||||||
//Add the song to a list or update a ListView.
|
setupTimer();
|
||||||
|
|
||||||
|
mediaPlayer.play();
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusLabel.setText("خطا در پخش فایل");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:This method should open a new window or change the current scene to display the "Playlist" page.
|
|
||||||
|
|
||||||
public void openPlaylistWindow() {
|
private void setupTimer() {
|
||||||
//Create a new stage and show the playlist UI.
|
mediaPlayer.setOnReady(() -> {
|
||||||
|
Duration duration = mediaPlayer.getTotalDuration();
|
||||||
|
String time = String.format("%d:%02d",
|
||||||
|
(int) duration.toMinutes(),
|
||||||
|
(int) duration.toSeconds() % 60);
|
||||||
|
|
||||||
|
|
||||||
|
String songName = statusLabel.getText().replace("Now Playing: ", "");
|
||||||
|
statusLabel.setText(songName + " (" + time + ")");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void handleAddAction(ActionEvent event) {
|
||||||
|
Button clickedButton = (Button) event.getSource();
|
||||||
|
String songName = (String) clickedButton.getUserData();
|
||||||
|
|
||||||
|
if (songName != null) {
|
||||||
|
playlist.add(songName);
|
||||||
|
statusLabel.setText("وضعیت: " + songName + " به لیست اضافه شد.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void openPlaylistWindow(ActionEvent event) {
|
||||||
|
Stage playlistStage = new Stage();
|
||||||
|
ListView<String> listView = new ListView<>(playlist);
|
||||||
|
listView.setStyle("-fx-background-color: #1e1e2e; -fx-control-inner-background: #1e1e2e; -fx-text-fill: white;");
|
||||||
|
|
||||||
|
VBox root = new VBox(listView);
|
||||||
|
root.setStyle("-fx-background-color: #1e1e2e; -fx-padding: 10;");
|
||||||
|
|
||||||
|
playlistStage.setScene(new Scene(root, 300, 400));
|
||||||
|
playlistStage.setTitle("لیست پخش من");
|
||||||
|
playlistStage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mapSongToFileName(String songName) {
|
||||||
|
if (songName == null) return "mp3.mp3";
|
||||||
|
if (songName.contains("اول")) return "mp3.mp3";
|
||||||
|
if (songName.contains("دوم")) return "mp4.mp3";
|
||||||
|
return "mp5.mp3";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,63 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.image.*?>
|
||||||
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||||
<VBox xmlns="http://javafx.com/fxml" alignment="CENTER" spacing="10">
|
fx:controller="sbu.javafx.MusicController"
|
||||||
|
style="-fx-background-color: #1e1e2e;"
|
||||||
|
prefWidth="400" prefHeight="650">
|
||||||
|
|
||||||
<!-- TODO: Add your code here! -->
|
<VBox style="-fx-background-image: url('frozen_bg.jpg');
|
||||||
|
-fx-background-size: cover;
|
||||||
|
-fx-background-position: center;"/>
|
||||||
|
|
||||||
</VBox>
|
<VBox alignment="CENTER" spacing="25" style="-fx-padding: 30;">
|
||||||
|
|
||||||
|
<Label fx:id="statusLabel" text="آماده پخش..."
|
||||||
|
wrapText="true"
|
||||||
|
maxWidth="350"
|
||||||
|
style="-fx-text-fill: white;
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-background-color: rgba(0,0,0,0.5);
|
||||||
|
-fx-padding: 10;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-alignment: center;
|
||||||
|
-fx-text-alignment: center;"/>
|
||||||
|
|
||||||
|
<VBox spacing="15" alignment="CENTER"
|
||||||
|
style="-fx-background-color: rgba(255, 255, 255, 0.75);
|
||||||
|
-fx-padding: 20;
|
||||||
|
-fx-background-radius: 25;
|
||||||
|
-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.3), 10, 0, 0, 0);">
|
||||||
|
|
||||||
|
<HBox spacing="10" alignment="CENTER_LEFT">
|
||||||
|
<Label text="❄️ آهنگ اول" style="-fx-text-fill: #004d40; -fx-font-weight: bold; -fx-font-size: 14px;"/>
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button text="Play" userData="آهنگ اول" onAction="#handlePlayAction"/>
|
||||||
|
<Button text="Add" userData="آهنگ اول" onAction="#handleAddAction"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<HBox spacing="10" alignment="CENTER_LEFT">
|
||||||
|
<Label text="❄️ آهنگ دوم" style="-fx-text-fill: #004d40; -fx-font-weight: bold; -fx-font-size: 14px;"/>
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button text="Play" userData="آهنگ دوم" onAction="#handlePlayAction"/>
|
||||||
|
<Button text="Add" userData="آهنگ دوم" onAction="#handleAddAction"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<HBox spacing="10" alignment="CENTER_LEFT">
|
||||||
|
<Label text="❄️ آهنگ سوم" style="-fx-text-fill: #004d40; -fx-font-weight: bold; -fx-font-size: 14px;"/>
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button text="Play" userData="آهنگ سوم" onAction="#handlePlayAction"/>
|
||||||
|
<Button text="Add" userData="آهنگ سوم" onAction="#handleAddAction"/>
|
||||||
|
</HBox>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
<Button text="مشاهده لیست پخش" onAction="#openPlaylistWindow"
|
||||||
|
style="-fx-background-color: linear-gradient(to right, #0288d1, #ec407a);
|
||||||
|
-fx-text-fill: white; -fx-font-size: 15px; -fx-font-weight: bold;
|
||||||
|
-fx-padding: 12 35; -fx-background-radius: 25;
|
||||||
|
-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.4), 5, 0, 0, 0); -fx-cursor: hand;"/>
|
||||||
|
</VBox>
|
||||||
|
</StackPane>
|
||||||
Reference in New Issue
Block a user