forked from AdvancedProgramming1404/HW-07-JavaFX
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b68b084df |
@@ -19,6 +19,11 @@
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> 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();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox xmlns="http://javafx.com/fxml" alignment="CENTER" spacing="10">
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
|
||||
<!-- TODO: Add your code here! -->
|
||||
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="sbu.javafx.MusicController" fx:id="mainContainer" stylesheets="@style.css">
|
||||
<padding>
|
||||
<Insets top="25" right="25" bottom="25" left="25"/>
|
||||
</padding>
|
||||
|
||||
</VBox>
|
||||
|
||||
<top>
|
||||
<StackPane>
|
||||
<padding><Insets bottom="20" top="10" left="10" right="10"/></padding>
|
||||
|
||||
<Label text="Music Player" styleClass="main-title" StackPane.alignment="CENTER"/>
|
||||
|
||||
<Button fx:id="themeButton" text="Dark Mode" onAction="#toggleTheme" focusTraversable="false" StackPane.alignment="CENTER_RIGHT"/>
|
||||
</StackPane>
|
||||
</top>
|
||||
|
||||
<center>
|
||||
<VBox styleClass="table-container" BorderPane.alignment="TOP_CENTER">
|
||||
|
||||
<HBox spacing="15" alignment="CENTER_LEFT">
|
||||
<padding><Insets top="10" right="15" bottom="10" left="15"/></padding>
|
||||
<Label text="Song Title" prefWidth="160" styleClass="header-text"/>
|
||||
<Label text="Artist" prefWidth="140" styleClass="header-text"/>
|
||||
<Label text="Duration" prefWidth="80" alignment="CENTER" styleClass="header-text"/>
|
||||
<Label text="Playlist" prefWidth="130" alignment="CENTER" styleClass="header-text"/>
|
||||
<Label text="Play" prefWidth="70" alignment="CENTER" styleClass="header-text"/>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Familiar" prefWidth="160" />
|
||||
<Label text="Liam Payne" prefWidth="140" />
|
||||
<Label text="03:16" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button fx:id="mainAdd1" text="Add to Playlist" onAction="#addToPlaylist" focusTraversable="false" userData="Familiar"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="mainPlay1" text="Play" onAction="#playMusic" focusTraversable="false" userData="Familiar"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Reminder" prefWidth="160" />
|
||||
<Label text="The Weeknd" prefWidth="140" />
|
||||
<Label text="03:40" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button fx:id="mainAdd2" text="Add to Playlist" onAction="#addToPlaylist" focusTraversable="false" userData="Reminder"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="mainPlay2" text="Play" onAction="#playMusic" focusTraversable="false" userData="Reminder"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Spotlight" prefWidth="160" />
|
||||
<Label text="Lil Peep" prefWidth="140" />
|
||||
<Label text="02:58" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button fx:id="mainAdd3" text="Add to Playlist" onAction="#addToPlaylist" focusTraversable="false" userData="Spotlight"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="mainPlay3" text="Play" onAction="#playMusic" focusTraversable="false" userData="Spotlight"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
</VBox>
|
||||
</center>
|
||||
|
||||
<bottom>
|
||||
<BorderPane styleClass="footer-box">
|
||||
<BorderPane.margin><Insets top="20"/></BorderPane.margin>
|
||||
<padding><Insets top="20" right="20" bottom="20" left="20"/></padding>
|
||||
<left><Label fx:id="nowPlayingLabel" text="Now Playing: -" BorderPane.alignment="CENTER"/></left>
|
||||
<right><Button text="Open Playlist" onAction="#openPlaylist" focusTraversable="false" BorderPane.alignment="CENTER"/></right>
|
||||
</BorderPane>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
|
||||
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="sbu.javafx.MusicController" fx:id="playlistContainer" stylesheets="@style.css">
|
||||
<padding>
|
||||
<Insets top="25" right="25" bottom="25" left="25"/>
|
||||
</padding>
|
||||
|
||||
|
||||
<top>
|
||||
<StackPane>
|
||||
<padding><Insets bottom="20" top="10" left="10" right="10"/></padding>
|
||||
|
||||
<Label text="My Playlist" styleClass="main-title" StackPane.alignment="CENTER"/>
|
||||
|
||||
<Button fx:id="themeButton" text="Dark Mode" onAction="#toggleTheme" focusTraversable="false" StackPane.alignment="CENTER_RIGHT"/>
|
||||
</StackPane>
|
||||
</top>
|
||||
|
||||
<center>
|
||||
<VBox alignment="TOP_CENTER">
|
||||
<Label fx:id="emptyLabel" text="Your saved songs will appear here.">
|
||||
<padding><Insets top="100"/></padding>
|
||||
</Label>
|
||||
|
||||
<VBox fx:id="playlistTable" styleClass="table-container" visible="false" managed="false">
|
||||
<HBox spacing="15" alignment="CENTER_LEFT">
|
||||
<padding><Insets top="10" right="15" bottom="10" left="15"/></padding>
|
||||
<Label text="Song Title" prefWidth="160" styleClass="header-text"/>
|
||||
<Label text="Artist" prefWidth="140" styleClass="header-text"/>
|
||||
<Label text="Duration" prefWidth="80" alignment="CENTER" styleClass="header-text"/>
|
||||
<Label text="Playlist" prefWidth="130" alignment="CENTER" styleClass="header-text"/>
|
||||
<Label text="Play" prefWidth="70" alignment="CENTER" styleClass="header-text"/>
|
||||
</HBox>
|
||||
|
||||
<HBox fx:id="playlistRow1" spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Familiar" prefWidth="160" />
|
||||
<Label text="Liam Payne" prefWidth="140" />
|
||||
<Label text="03:16" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button text="Remove" onAction="#RemoveFromPlaylist" focusTraversable="false" userData="Familiar"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="playlistPlay1" text="Play" onAction="#playMusic" focusTraversable="false" userData="Familiar"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
|
||||
<HBox fx:id="playlistRow2" spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Reminder" prefWidth="160" />
|
||||
<Label text="The Weeknd" prefWidth="140" />
|
||||
<Label text="03:40" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button text="Remove" onAction="#RemoveFromPlaylist" focusTraversable="false" userData="Reminder"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="playlistPlay2" text="Play" onAction="#playMusic" focusTraversable="false" userData="Reminder"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
|
||||
<HBox fx:id="playlistRow3" spacing="15" alignment="CENTER_LEFT" styleClass="table-row">
|
||||
<padding><Insets top="15" right="15" bottom="15" left="15"/></padding>
|
||||
<Label text="Spotlight" prefWidth="160" />
|
||||
<Label text="Lil Peep" prefWidth="140" />
|
||||
<Label text="02:58" prefWidth="80" alignment="CENTER" />
|
||||
<HBox prefWidth="130" alignment="CENTER">
|
||||
<Button text="Remove" onAction="#RemoveFromPlaylist" focusTraversable="false" userData="Spotlight"/>
|
||||
</HBox>
|
||||
<HBox prefWidth="70" alignment="CENTER">
|
||||
<Button fx:id="playlistPlay3" text="Play" onAction="#playMusic" focusTraversable="false" userData="Spotlight"/>
|
||||
</HBox>
|
||||
</HBox>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</center>
|
||||
|
||||
<bottom>
|
||||
<BorderPane styleClass="footer-box">
|
||||
<BorderPane.margin><Insets top="20"/></BorderPane.margin>
|
||||
<padding><Insets top="20" right="20" bottom="20" left="20"/></padding>
|
||||
<left><Label fx:id="nowPlayingLabel" text="Now Playing: -" BorderPane.alignment="CENTER"/></left>
|
||||
<right><Button text="Back to Player" onAction="#closePlaylist" focusTraversable="false" BorderPane.alignment="CENTER"/></right>
|
||||
</BorderPane>
|
||||
</bottom>
|
||||
</BorderPane>
|
||||
@@ -0,0 +1,24 @@
|
||||
BorderPane {
|
||||
-fx-background-color: #26292e;
|
||||
}
|
||||
|
||||
.main-title, .header-text, .label {
|
||||
-fx-text-fill: #f0f2f5;
|
||||
}
|
||||
|
||||
.table-container, .table-row, .footer-box {
|
||||
-fx-border-color: #3e4249;
|
||||
}
|
||||
|
||||
.button {
|
||||
-fx-background-color: #34383e;
|
||||
-fx-text-fill: #f0f2f5;
|
||||
-fx-border-color: #484e57;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-border-radius: 4px;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
-fx-background-color: #40454d;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
.main-title {
|
||||
-fx-font-size: 24px;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-style: solid;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 1px 0px 0px 0px;
|
||||
-fx-border-style: solid;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.footer-box {
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-style: solid;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
Reference in New Issue
Block a user