Compare commits

3 Commits
Author SHA1 Message Date
MehrdadShirvani 8b9665f95e Merge PR 'Develop' (#1) from develop into main
Full Mark 100/100 + Bonus
2026-07-10 16:05:39 +00:00
bitahajati 98f8235fc3 Add Style 2026-05-29 12:15:06 +03:30
bitahajati d0739af98a Edit MediaPlayer 2026-05-27 22:11:08 +03:30
6 changed files with 183 additions and 42 deletions
+10 -1
View File
@@ -4,7 +4,8 @@ import javafx.application.Application;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.scene.image.Image;
import java.awt.*;
import java.io.IOException; import java.io.IOException;
public class MusicApp extends Application { public class MusicApp extends Application {
@@ -14,8 +15,16 @@ public class MusicApp extends Application {
{ {
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());
String lightStyle = getClass().getResource("light.css").toExternalForm();
scene.getStylesheets().add(lightStyle);
stage.setTitle("Music Player"); stage.setTitle("Music Player");
stage.setScene(scene); stage.setScene(scene);
Image icon = new Image(getClass().getResourceAsStream("icon.png"));
stage.getIcons().add(icon);
stage.show(); stage.show();
} }
+68 -40
View File
@@ -19,13 +19,15 @@ public class MusicController {
@FXML private ListView<String> lvSongs; @FXML private ListView<String> lvSongs;
@FXML private Label lblStatus; @FXML private Label lblStatus;
@FXML private Button btnPlayStop; @FXML private Button btnPlayStop;
@FXML private Button btnViewPlaylist; @FXML private Button btnTheme;
private int previousSongIndex = -1;
private MediaPlayer mediaPlayer; private MediaPlayer mediaPlayer;
private ArrayList<String> playlist = new ArrayList<>(); private ArrayList<String> playlist = new ArrayList<>();
private String[] songsArray = {"Arcade Duncan Laurence 3.07", private String[] songsArray = {"Arcade Duncan Laurence 3.07",
"How i love you Engelbert 4.20", "How i love you Engelbert 4.20",
"Memories Conan Gray 4.09", "Memories Conan Gray 4.09",
"Night Changes One Direction 3.47", "Night Changes One Direction 3.47",
@@ -41,7 +43,7 @@ public class MusicController {
String songName = ""; String songName = "";
if (a == 0) songName = "Arcade"; if (a == 0) songName = "Arcade";
else if (a == 1) songName = "How i love you"; else if (a == 1) songName = "How i love you";
else if (a == 2) songName = "Memmories"; else if (a == 2) songName = "Memories";
else if (a == 3) songName = "Night Changes"; else if (a == 3) songName = "Night Changes";
else songName = "Careless Whisper"; else songName = "Careless Whisper";
@@ -52,65 +54,74 @@ public class MusicController {
public void handlePlayAction() public void handlePlayAction()
{ {
String selectedSong = lvSongs.getSelectionModel().getSelectedItem(); String selectedSong = lvSongs.getSelectionModel().getSelectedItem();
int newSongIndex = lvSongs.getSelectionModel().getSelectedIndex();
boolean isNewSong = (newSongIndex != previousSongIndex);
if (selectedSong == null) if (selectedSong == null)
{ {
lblStatus.setText("Please choose a song"); lblStatus.setText("Please choose a song");
return; return;
} }
String filePath = "src/main/resources/sbu.javafx/songs/" + songName(lvSongs.getSelectionModel().getSelectedIndex()) + ".mp3"; if (isNewSong)
File file = new File(filePath); {
if (mediaPlayer != null)
{
mediaPlayer.dispose();
mediaPlayer = null;
}
boolean isPlayingOrPaused = (mediaPlayer != null && String filePath = "src/main/resources/sbu/javafx/songs/" + songName(lvSongs.getSelectionModel().getSelectedIndex()) + ".mp3";
(mediaPlayer.getStatus() == MediaPlayer.Status.PLAYING || File file = new File(filePath);
mediaPlayer.getStatus() == MediaPlayer.Status.PAUSED));
if (isPlayingOrPaused) try {
Media media = new Media(file.toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnEndOfMedia(new Runnable() {
@Override
public void run() {
mediaPlayer.stop();
btnPlayStop.setText("Play ▶");
lblStatus.setText("Finished");
}
});
mediaPlayer.play();
btnPlayStop.setText("Paused ⏸");
lblStatus.setText("Playing : " + songName(lvSongs.getSelectionModel().getSelectedIndex()));
previousSongIndex = newSongIndex;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
else
{ {
if (mediaPlayer.getStatus() == MediaPlayer.Status.PLAYING) if (mediaPlayer.getStatus() == MediaPlayer.Status.PLAYING)
{ {
mediaPlayer.pause(); mediaPlayer.pause();
btnPlayStop.setText("Paused ⏸"); btnPlayStop.setText("Play ▶");
lblStatus.setText("Playing : " + songName(lvSongs.getSelectionModel().getSelectedIndex())); lblStatus.setText("Paused");
return;
} }
else if (mediaPlayer.getStatus() == MediaPlayer.Status.PAUSED) else if (mediaPlayer.getStatus() == MediaPlayer.Status.PAUSED)
{ {
mediaPlayer.play(); mediaPlayer.play();
btnPlayStop.setText("Play ▶"); btnPlayStop.setText("Pause ⏸");
lblStatus.setText("Paused"); lblStatus.setText("Playing: " + songName(lvSongs.getSelectionModel().getSelectedIndex()));
return; }
else
{
mediaPlayer.play();
btnPlayStop.setText("Pause ⏸");
lblStatus.setText("Playing: " + songName(lvSongs.getSelectionModel().getSelectedIndex()));
} }
}
if (mediaPlayer != null)
{
mediaPlayer.dispose();
mediaPlayer = null;
}
try {
Media media = new Media(file.toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnEndOfMedia(new Runnable() {
@Override
public void run() {
mediaPlayer.stop();
btnPlayStop.setText("Play ▶");
}
});
mediaPlayer.play();
btnPlayStop.setText("Paused ⏸");
lblStatus.setText("Playing : " + songName(lvSongs.getSelectionModel().getSelectedIndex()));
} catch (Exception e) {
throw new RuntimeException(e);
} }
} }
//TODO: Logic to add a specific song to the user's playlist. //TODO: Logic to add a specific song to the user's playlist.
@FXML
public void addToPlaylist() public void addToPlaylist()
{ {
String selectedSong = lvSongs.getSelectionModel().getSelectedItem(); String selectedSong = lvSongs.getSelectionModel().getSelectedItem();
@@ -148,4 +159,21 @@ public class MusicController {
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
} }
@FXML
private void toggleTheme()
{
if (!btnTheme.getText().contains("Light"))
{
btnTheme.getScene().getStylesheets().clear();
btnTheme.getScene().getStylesheets().add(getClass().getResource("style.css").toExternalForm());
btnTheme.setText("Light Mode");
}
else
{
btnTheme.getScene().getStylesheets().clear();
btnTheme.getScene().getStylesheets().add(getClass().getResource("light.css").toExternalForm());
btnTheme.setText("Dark Mode");
}
}
} }
+7 -1
View File
@@ -6,13 +6,19 @@
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="15.0" xmlns:fx="http://javafx.com/fxml" fx:controller="sbu.javafx.MusicController"> <VBox alignment="CENTER" spacing="15.0" xmlns:fx="http://javafx.com/fxml" fx:controller="sbu.javafx.MusicController">
<padding>
<Insets bottom="20" left="300" right="300" top="20"/>
</padding>
<Label fx:id="lblStatus" text="Music Player" style="-fx-font-size: 18px; -fx-font-weight: bold;"/> <Label fx:id="lblStatus" text="Music Player" style="-fx-font-size: 18px; -fx-font-weight: bold;"/>
<ListView fx:id="lvSongs" prefHeight="200.0" prefWidth="350.0"/> <ListView fx:id="lvSongs" prefHeight="200.0" prefWidth="350.0"/>
<HBox spacing="10" alignment="CENTER"> <HBox spacing="10" alignment="CENTER">
<Button fx:id="btnPlayStop" text="PLay ▶" onAction="#handlePlayAction" prefWidth="300"/> <Button fx:id="btnPlayStop" text="PLay ▶" onAction="#handlePlayAction" prefWidth="200"/>
<Button fx:id="btnTheme" text="Dark Mode" onAction="#toggleTheme" />
</HBox> </HBox>
<VBox spacing="10"/> <VBox spacing="10"/>
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+49
View File
@@ -0,0 +1,49 @@
.root {
-fx-background-color: #e0e0e0;
-fx-text-fill: black;
}
.label {
-fx-font-size: 14px;
-fx-font-weight: bold;
-fx-text-fill: #ff1493;
}
.list-view {
-fx-background-color: white;
-fx-border-color: #ff1493;
-fx-border-width: 2px;
-fx-background-radius: 10px;
-fx-border-radius: 10px;
}
.list-cell {
-fx-background-color: white;
-fx-text-fill: black;
-fx-font-weight: bold;
-fx-border-color: transparent;
-fx-background-radius: 10px;
-fx-border-radius: 10px;
}
.list-cell:selected {
-fx-background-color: #ffb6c1;
-fx-text-fill: black;
}
.button {
-fx-background-color: #ffe4e1;
-fx-text-fill: black;
-fx-font-weight: bold;
-fx-padding: 10px;
-fx-cursor: hand;
-fx-border-color: #ff1493;
-fx-border-width: 2px;
-fx-background-radius: 50px;
-fx-border-radius: 50px;
}
.button:hover {
-fx-background-color: #ffc0cb;
-fx-border-color: #ff1493;
}
+49
View File
@@ -0,0 +1,49 @@
.root {
-fx-background-color: #1e1e1e;
-fx-text-fill: #ffffff;
}
.label {
-fx-font-size: 14px;
-fx-font-weight: bold;
-fx-text-fill: #ff69b4;
}
.list-view {
-fx-background-color: #2d2d2d;
-fx-border-color: #ff1493;
-fx-border-width: 2px;
-fx-background-radius: 10px;
-fx-border-radius: 10px;
}
.list-cell {
-fx-background-color: #2d2d2d;
-fx-text-fill: #ffffff;
-fx-font-weight: bold;
-fx-border-color: transparent;
}
.list-cell:selected {
-fx-background-color: #4a002a;
-fx-text-fill: #ffffff;
-fx-background-radius: 10px;
-fx-border-radius: 10px;
}
.button {
-fx-background-color: #4a4a4a;
-fx-text-fill: #ffffff;
-fx-font-weight: bold;
-fx-padding: 10px;
-fx-cursor: hand;
-fx-border-color: #ff1493;
-fx-border-width: 2px;
-fx-background-radius: 50px;
-fx-border-radius: 50px;
}
.button:hover {
-fx-background-color: #5a5a5a;
-fx-border-color: #ff69b4;
}