+ Implemented the main.fxml and its controller (MusicController) #1
Generated
+1
-1
@@ -8,7 +8,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="23" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="25" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -24,6 +24,11 @@
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>21</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
||||
@@ -4,5 +4,6 @@ import javafx.application.Application;
|
||||
|
||||
public class Launcher{
|
||||
public static void main(String[] args) {
|
||||
// TODO: Launch the JavaFX application by calling Application.launch(Main.class) }
|
||||
Application.launch(MusicApp.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,21 +2,27 @@ package sbu.javafx;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MusicApp extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException
|
||||
{
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("App-view.fxml"));
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(MusicApp.class.getResource("main.fxml"));
|
||||
Scene scene = new Scene(fxmlLoader.load());
|
||||
Image icon = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/icon.png")));
|
||||
|
||||
stage.getIcons().add(icon);
|
||||
stage.setTitle("Music Player");
|
||||
stage.setScene(scene);
|
||||
//TODO: add icon to the stage
|
||||
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,143 @@
|
||||
package sbu.javafx;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.media.Media;
|
||||
import javafx.scene.media.MediaPlayer;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public class MusicController {
|
||||
|
||||
// TODO: Define your UI components using the @FXML annotation.
|
||||
|
||||
//TODO: Implement the logic to play a song. This method should update the UI to show which song is currently playing.
|
||||
@FXML
|
||||
private Button pausePlay;
|
||||
|
||||
@FXML
|
||||
public void handlePlayAction() {
|
||||
//Update labels, change button icons, etc.
|
||||
private ListView<Song> songListView;
|
||||
|
||||
@FXML
|
||||
private ListView<Song> playlist;
|
||||
|
||||
@FXML
|
||||
private Label nowPlayingLabel;
|
||||
|
||||
private MediaPlayer mediaPlayer;
|
||||
private Song currentSong;
|
||||
private boolean isPlaying = false;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
loadSongs();
|
||||
}
|
||||
|
||||
//TODO: Logic to add a specific song to the user's playlist.
|
||||
// Adds songs to ListView
|
||||
private void loadSongs() {
|
||||
// Songs paths (used URL so the songs can stay in the resources folder so in case of building to jar the songs remain in the app)
|
||||
URL comeAsYouAre = getClass().getResource("/songs/comeAsYouAre.mp3");
|
||||
URL childIWillHurtYou = getClass().getResource("/songs/childIWillHurtYou.mp3");
|
||||
URL lucky = getClass().getResource("/songs/lucky.mp3");
|
||||
URL fitterHappier = getClass().getResource("/songs/fitterHappier.mp3");
|
||||
|
||||
public void addToPlaylist(String songName) {
|
||||
//Add the song to a list or update a ListView.
|
||||
songListView.getItems().addAll(
|
||||
new Song("Come As You Are", "Nirvana", "03:38", comeAsYouAre),
|
||||
new Song("Child I Will Hurt You", "Crystal Castles", "03:33", childIWillHurtYou),
|
||||
new Song("Lucky", "Radiohead","04:18", lucky),
|
||||
new Song("Fitter Happier","Radiohead","01:57",fitterHappier)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO:This method should open a new window or change the current scene to display the "Playlist" page.
|
||||
private void playSelectedSong(Song song) {
|
||||
try {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.dispose();
|
||||
}
|
||||
|
||||
public void openPlaylistWindow() {
|
||||
//Create a new stage and show the playlist UI.
|
||||
currentSong = song;
|
||||
|
||||
mediaPlayer = new MediaPlayer(
|
||||
new Media(song.getUrl().toString())
|
||||
);
|
||||
|
||||
nowPlayingLabel.setText("Now Playing: " + song.getTitle() + " - " + song.getArtist());
|
||||
pausePlay.setText("Pause");
|
||||
isPlaying = true;
|
||||
mediaPlayer.play();
|
||||
|
||||
} catch (Exception e) {
|
||||
nowPlayingLabel.setText("Error: Cannot play file - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void togglePlayPause() {
|
||||
if (mediaPlayer == null) return;
|
||||
|
||||
if (isPlaying) {
|
||||
mediaPlayer.pause();
|
||||
pausePlay.setText("Play");
|
||||
isPlaying = false;
|
||||
} else {
|
||||
mediaPlayer.play();
|
||||
isPlaying = true;
|
||||
pausePlay.setText("Pause");
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void addCurrentToPlaylist() {
|
||||
if (currentSong != null) {
|
||||
boolean alreadyExists = false;
|
||||
for (Song song : playlist.getItems()) {
|
||||
if (song.getUrl().toString().equals(currentSong.getUrl().toString())) {
|
||||
alreadyExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyExists) {
|
||||
playlist.getItems().add(currentSong);
|
||||
System.out.println("Added to playlist : " + currentSong.getTitle());
|
||||
nowPlayingLabel.setText("Now Playing : " + currentSong.getTitle() + " - Added to playlist!");
|
||||
} else {
|
||||
System.out.println("Song already in playlist");
|
||||
nowPlayingLabel.setText("Now Playing : " + currentSong.getTitle() + " - Already in playlist!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clearPlaylist() {
|
||||
playlist.getItems().clear();
|
||||
System.out.println("Playlist cleared");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void removeSelectedFromPlaylist() {
|
||||
Song selectedSong = playlist.getSelectionModel().getSelectedItem();
|
||||
if (selectedSong != null) {
|
||||
playlist.getItems().remove(selectedSong);
|
||||
System.out.println("Removed from playlist : " + selectedSong.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void handleSongClick() {
|
||||
// Get the selected song from the song ListView
|
||||
Song selectedSong = songListView.getSelectionModel().getSelectedItem();
|
||||
if (selectedSong != null) {
|
||||
playSelectedSong(selectedSong);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void handleSongClickPlaylist(){
|
||||
// Get the selected song from the playlist ListView
|
||||
Song selectedSong = playlist.getSelectionModel().getSelectedItem();
|
||||
if (selectedSong != null) {
|
||||
playSelectedSong(selectedSong);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package sbu.javafx;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public class Song {
|
||||
private String title;
|
||||
private String artist;
|
||||
private String duration;
|
||||
private URL url;
|
||||
|
||||
public Song(String title, String artist, String duration, URL url) {
|
||||
this.title = title;
|
||||
this.artist = artist;
|
||||
this.duration = duration;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getTitle() { return title; }
|
||||
public String getArtist() { return artist; }
|
||||
public String getDuration() { return duration; }
|
||||
public URL getUrl() { return url; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getTitle() + " - " + getArtist() + " (" + getDuration() + ")";
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox xmlns="http://javafx.com/fxml" alignment="CENTER" spacing="10">
|
||||
|
||||
<!-- TODO: Add your code here! -->
|
||||
|
||||
</VBox>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<AnchorPane prefHeight="600" prefWidth="800" xmlns="http://javafx.com/javafx/17.0.12"
|
||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sbu.javafx.MusicController">
|
||||
<TabPane prefHeight="600.0" prefWidth="800.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0"
|
||||
AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0">
|
||||
<Tab text="Music Player">
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||
<VBox layoutX="10.0" layoutY="10.0" prefHeight="560.0" prefWidth="780.0" spacing="15"
|
||||
AnchorPane.bottomAnchor="10" AnchorPane.leftAnchor="10"
|
||||
AnchorPane.rightAnchor="10" AnchorPane.topAnchor="10">
|
||||
<HBox alignment="CENTER" prefHeight="60.0" prefWidth="780.0">
|
||||
<Label text="Music Player" textAlignment="CENTER">
|
||||
<font>
|
||||
<Font size="28.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</HBox>
|
||||
|
||||
<VBox spacing="5" VBox.vgrow="ALWAYS">
|
||||
<Label style="-fx-font-weight: bold; -fx-font-size: 14px;"
|
||||
text="Available Songs"/>
|
||||
<ListView fx:id="songListView" onMouseClicked="#handleSongClick"
|
||||
prefHeight="400.0" prefWidth="780.0" VBox.vgrow="ALWAYS"/>
|
||||
</VBox>
|
||||
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="60.0" prefWidth="780.0" spacing="10">
|
||||
<Label fx:id="nowPlayingLabel" style="-fx-font-weight: bold"
|
||||
text="Now Playing: -"/>
|
||||
<Region prefHeight="52.0" HBox.hgrow="ALWAYS"/>
|
||||
<Button fx:id="pausePlay" onAction="#togglePlayPause" prefWidth="70"
|
||||
text="Play"/>
|
||||
<Button onAction="#addCurrentToPlaylist" fx:id="addToPlaylist" prefWidth="150" text="Add Current to Playlist"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
</AnchorPane>
|
||||
</Tab>
|
||||
<Tab text="Playlist">
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||
<VBox layoutX="10.0" layoutY="10.0" prefHeight="560.0" prefWidth="780.0" spacing="15"
|
||||
AnchorPane.bottomAnchor="10" AnchorPane.leftAnchor="10"
|
||||
AnchorPane.rightAnchor="10" AnchorPane.topAnchor="10">
|
||||
<Label style="-fx-font-weight: bold; -fx-font-size: 18px;" text="Playlist"/>
|
||||
|
||||
<ListView fx:id="playlist" onMouseClicked="#handleSongClickPlaylist" prefHeight="480.0" prefWidth="780.0" VBox.vgrow="ALWAYS"/>
|
||||
|
||||
<HBox alignment="CENTER_RIGHT" spacing="10">
|
||||
<Button onAction="#clearPlaylist" text="Clear Playlist"/>
|
||||
<Button onAction="#removeSelectedFromPlaylist" text="Remove Selected"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
</AnchorPane>
|
||||
</Tab>
|
||||
</TabPane>
|
||||
</AnchorPane>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user