├── MP3MusicPlayer.iml ├── README.md ├── Screenshot_38.png ├── lib ├── jaudiotagger-3.0.1.jar ├── jlayer-1.0.1.jar └── mp3agic-0.9.0.jar ├── out └── production │ └── MP3MusicPlayer │ ├── App$1.class │ ├── App.class │ ├── MusicPlayer$1.class │ ├── MusicPlayer$2.class │ ├── MusicPlayer.class │ ├── MusicPlayerGUI$1.class │ ├── MusicPlayerGUI$2.class │ ├── MusicPlayerGUI$3.class │ ├── MusicPlayerGUI$4.class │ ├── MusicPlayerGUI$5.class │ ├── MusicPlayerGUI$6.class │ ├── MusicPlayerGUI$7.class │ ├── MusicPlayerGUI$8.class │ ├── MusicPlayerGUI.class │ ├── MusicPlaylistDialog$1.class │ ├── MusicPlaylistDialog$2.class │ ├── MusicPlaylistDialog.class │ ├── Song.class │ └── assets │ ├── Auld Lang Syne (Instrumental) - Jingle Punks.mp3 │ ├── Tropic Fuse - French Fuse.mp3 │ ├── Wind Riders - Asher Fulero.mp3 │ ├── next.png │ ├── pause.png │ ├── play.png │ ├── playlist.txt │ ├── playlist2.txt │ ├── playlist3.txt │ ├── previous.png │ └── record.png └── src ├── App.java ├── MusicPlayer.java ├── MusicPlayerGUI.java ├── MusicPlaylistDialog.java ├── Song.java └── assets ├── Auld Lang Syne (Instrumental) - Jingle Punks.mp3 ├── Tropic Fuse - French Fuse.mp3 ├── Wind Riders - Asher Fulero.mp3 ├── next.png ├── pause.png ├── play.png ├── playlist.txt ├── playlist2.txt ├── playlist3.txt ├── previous.png └── record.png /MP3MusicPlayer.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

MP3 Music Player App

3 | 4 | 5 |

Introduction

6 |

In this project, you'll learn how to build a MP3 Music Player App in Java! You can check out the full tutorial here 7 | , where I carefully go over the logic flow so that you can understand how this project is coded the way it was. 8 |

9 | 10 | 11 |

Technologies Frameworks

12 | 18 | 19 | 20 |

Features

21 | 34 | 35 | 36 | 37 |

Screenshots

38 |

39 | Music Player App Screenshot 40 |

41 | -------------------------------------------------------------------------------- /Screenshot_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/Screenshot_38.png -------------------------------------------------------------------------------- /lib/jaudiotagger-3.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/jaudiotagger-3.0.1.jar -------------------------------------------------------------------------------- /lib/jlayer-1.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/jlayer-1.0.1.jar -------------------------------------------------------------------------------- /lib/mp3agic-0.9.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/mp3agic-0.9.0.jar -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/App$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/App$1.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/App.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/App.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayer$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer$1.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayer$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer$2.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$1.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$2.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$3.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$4.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$5.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$5.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$6.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$6.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$7.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$7.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI$8.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$8.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlayerGUI.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlaylistDialog$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog$1.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlaylistDialog$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog$2.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/MusicPlaylistDialog.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/Song.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/Song.class -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3 -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/Tropic Fuse - French Fuse.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Tropic Fuse - French Fuse.mp3 -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/Wind Riders - Asher Fulero.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Wind Riders - Asher Fulero.mp3 -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/next.png -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/pause.png -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/play.png -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/playlist.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/playlist2.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/playlist3.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/previous.png -------------------------------------------------------------------------------- /out/production/MP3MusicPlayer/assets/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/record.png -------------------------------------------------------------------------------- /src/App.java: -------------------------------------------------------------------------------- 1 | import javax.swing.*; 2 | 3 | public class App { 4 | public static void main(String[] args) { 5 | SwingUtilities.invokeLater(new Runnable(){ 6 | @Override 7 | public void run(){ 8 | new MusicPlayerGUI().setVisible(true); 9 | 10 | // Song song = new Song("src/assets/Wind Riders - Asher Fulero.mp3"); 11 | // System.out.println(song.getSongTitle()); 12 | // System.out.println(song.getSongArtist()); 13 | } 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MusicPlayer.java: -------------------------------------------------------------------------------- 1 | import javazoom.jl.player.advanced.AdvancedPlayer; 2 | import javazoom.jl.player.advanced.PlaybackEvent; 3 | import javazoom.jl.player.advanced.PlaybackListener; 4 | 5 | import java.io.*; 6 | import java.util.ArrayList; 7 | 8 | public class MusicPlayer extends PlaybackListener { 9 | // this will be used to update isPaused more synchronously 10 | private static final Object playSignal = new Object(); 11 | 12 | // need reference so that we can update the gui in this class 13 | private MusicPlayerGUI musicPlayerGUI; 14 | 15 | // we will need a way to store our song's details, so we will be creating a song class 16 | private Song currentSong; 17 | public Song getCurrentSong(){ 18 | return currentSong; 19 | } 20 | 21 | private ArrayList playlist; 22 | 23 | // we will need to keep track the index we are in the playlist 24 | private int currentPlaylistIndex; 25 | 26 | // use JLayer library to create an AdvancedPlayer obj which will handle playing the music 27 | private AdvancedPlayer advancedPlayer; 28 | 29 | // pause boolean flag used to indicate whether the player has been paused 30 | private boolean isPaused; 31 | 32 | // boolean flag used to tell when the song has finished 33 | private boolean songFinished; 34 | 35 | private boolean pressedNext, pressedPrev; 36 | 37 | // stores in teh last frame when the playback is finished (used for pausing and resuming) 38 | private int currentFrame; 39 | public void setCurrentFrame(int frame){ 40 | currentFrame = frame; 41 | } 42 | 43 | // track how many milliseconds has passed since playing the song (used for updating the slider) 44 | private int currentTimeInMilli; 45 | public void setCurrentTimeInMilli(int timeInMilli){ 46 | currentTimeInMilli = timeInMilli; 47 | } 48 | 49 | // constructor 50 | public MusicPlayer(MusicPlayerGUI musicPlayerGUI){ 51 | this.musicPlayerGUI = musicPlayerGUI; 52 | } 53 | 54 | public void loadSong(Song song){ 55 | currentSong = song; 56 | playlist = null; 57 | 58 | // stop the song if possible 59 | if(!songFinished) 60 | stopSong(); 61 | 62 | // play the current song if not null 63 | if(currentSong != null){ 64 | // reset frame 65 | currentFrame = 0; 66 | 67 | // reset current time in milli 68 | currentTimeInMilli = 0; 69 | 70 | // update gui 71 | musicPlayerGUI.setPlaybackSliderValue(0); 72 | 73 | playCurrentSong(); 74 | } 75 | } 76 | 77 | public void loadPlaylist(File playlistFile){ 78 | playlist = new ArrayList<>(); 79 | 80 | // store the paths from the text file into the playlist array list 81 | try{ 82 | FileReader fileReader = new FileReader(playlistFile); 83 | BufferedReader bufferedReader = new BufferedReader(fileReader); 84 | 85 | // reach each line from the text file and store the text into the songPath variable 86 | String songPath; 87 | while((songPath = bufferedReader.readLine()) != null){ 88 | // create song object based on song path 89 | Song song = new Song(songPath); 90 | 91 | // add to playlist array list 92 | playlist.add(song); 93 | } 94 | }catch(Exception e){ 95 | e.printStackTrace(); 96 | } 97 | 98 | if(playlist.size() > 0){ 99 | // reset playback slider 100 | musicPlayerGUI.setPlaybackSliderValue(0); 101 | currentTimeInMilli = 0; 102 | 103 | // update current song to the first song in the playlist 104 | currentSong = playlist.get(0); 105 | 106 | // start from the beginning frame 107 | currentFrame = 0; 108 | 109 | // update gui 110 | musicPlayerGUI.enablePauseButtonDisablePlayButton(); 111 | musicPlayerGUI.updateSongTitleAndArtist(currentSong); 112 | musicPlayerGUI.updatePlaybackSlider(currentSong); 113 | 114 | // start song 115 | playCurrentSong(); 116 | } 117 | } 118 | 119 | public void pauseSong(){ 120 | if(advancedPlayer != null){ 121 | // update isPaused flag 122 | isPaused = true; 123 | 124 | // then we want to stop the player 125 | stopSong(); 126 | } 127 | } 128 | 129 | public void stopSong(){ 130 | if(advancedPlayer != null){ 131 | advancedPlayer.stop(); 132 | advancedPlayer.close(); 133 | advancedPlayer = null; 134 | } 135 | } 136 | 137 | public void nextSong(){ 138 | // no need to go to the next song if there is no playlist 139 | if(playlist == null) return; 140 | 141 | // check to see if we have reached the end of the playlist, if so then don't do anything 142 | if(currentPlaylistIndex + 1 > playlist.size() - 1) return; 143 | 144 | pressedNext = true; 145 | 146 | // stop the song if possible 147 | if(!songFinished) 148 | stopSong(); 149 | 150 | // increase current playlist index 151 | currentPlaylistIndex++; 152 | 153 | // update current song 154 | currentSong = playlist.get(currentPlaylistIndex); 155 | 156 | // reset frame 157 | currentFrame = 0; 158 | 159 | // reset current time in milli 160 | currentTimeInMilli = 0; 161 | 162 | // update gui 163 | musicPlayerGUI.enablePauseButtonDisablePlayButton(); 164 | musicPlayerGUI.updateSongTitleAndArtist(currentSong); 165 | musicPlayerGUI.updatePlaybackSlider(currentSong); 166 | 167 | // play the song 168 | playCurrentSong(); 169 | } 170 | 171 | public void prevSong(){ 172 | // no need to go to the next song if there is no playlist 173 | if(playlist == null) return; 174 | 175 | // check to see if we can go to the previous song 176 | if(currentPlaylistIndex - 1 < 0) return; 177 | 178 | pressedPrev = true; 179 | 180 | // stop the song if possible 181 | if(!songFinished) 182 | stopSong(); 183 | 184 | // decrease current playlist index 185 | currentPlaylistIndex--; 186 | 187 | // update current song 188 | currentSong = playlist.get(currentPlaylistIndex); 189 | 190 | // reset frame 191 | currentFrame = 0; 192 | 193 | // reset current time in milli 194 | currentTimeInMilli = 0; 195 | 196 | // update gui 197 | musicPlayerGUI.enablePauseButtonDisablePlayButton(); 198 | musicPlayerGUI.updateSongTitleAndArtist(currentSong); 199 | musicPlayerGUI.updatePlaybackSlider(currentSong); 200 | 201 | // play the song 202 | playCurrentSong(); 203 | } 204 | 205 | public void playCurrentSong(){ 206 | if(currentSong == null) return; 207 | 208 | try{ 209 | // read mp3 audio data 210 | FileInputStream fileInputStream = new FileInputStream(currentSong.getFilePath()); 211 | BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); 212 | 213 | // create a new advanced player 214 | advancedPlayer = new AdvancedPlayer(bufferedInputStream); 215 | advancedPlayer.setPlayBackListener(this); 216 | 217 | // start music 218 | startMusicThread(); 219 | 220 | // start playback slider thread 221 | startPlaybackSliderThread(); 222 | 223 | }catch(Exception e){ 224 | e.printStackTrace(); 225 | } 226 | } 227 | 228 | // create a thread that will handle playing the music 229 | private void startMusicThread(){ 230 | new Thread(new Runnable() { 231 | @Override 232 | public void run() { 233 | try{ 234 | if(isPaused){ 235 | synchronized(playSignal){ 236 | // update flag 237 | isPaused = false; 238 | 239 | // notify the other thread to continue (makes sure that isPaused is updated to false properly) 240 | playSignal.notify(); 241 | } 242 | 243 | // resume music from last frame 244 | advancedPlayer.play(currentFrame, Integer.MAX_VALUE); 245 | }else{ 246 | // play music from the beginning 247 | advancedPlayer.play(); 248 | } 249 | }catch(Exception e){ 250 | e.printStackTrace(); 251 | } 252 | } 253 | }).start(); 254 | } 255 | 256 | // create a thread that will handle updating the slider 257 | private void startPlaybackSliderThread(){ 258 | new Thread(new Runnable() { 259 | @Override 260 | public void run() { 261 | if(isPaused){ 262 | try{ 263 | // wait till it gets notified by other thread to continue 264 | // makes sure that isPaused boolean flag updates to false before continuing 265 | synchronized(playSignal){ 266 | playSignal.wait(); 267 | } 268 | }catch(Exception e){ 269 | e.printStackTrace(); 270 | } 271 | } 272 | 273 | while(!isPaused && !songFinished && !pressedNext && !pressedPrev){ 274 | try{ 275 | // increment current time milli 276 | currentTimeInMilli++; 277 | 278 | // calculate into frame value 279 | int calculatedFrame = (int) ((double) currentTimeInMilli * 2.08 * currentSong.getFrameRatePerMilliseconds()); 280 | 281 | // update gui 282 | musicPlayerGUI.setPlaybackSliderValue(calculatedFrame); 283 | 284 | // mimic 1 millisecond using thread.sleep 285 | Thread.sleep(1); 286 | }catch(Exception e){ 287 | e.printStackTrace(); 288 | } 289 | } 290 | } 291 | }).start(); 292 | } 293 | 294 | @Override 295 | public void playbackStarted(PlaybackEvent evt) { 296 | // this method gets called in the beginning of the song 297 | System.out.println("Playback Started"); 298 | songFinished = false; 299 | pressedNext = false; 300 | pressedPrev = false; 301 | } 302 | 303 | @Override 304 | public void playbackFinished(PlaybackEvent evt) { 305 | // this method gets called when the song finishes or if the player gets closed 306 | System.out.println("Playback Finished"); 307 | if(isPaused){ 308 | currentFrame += (int) ((double) evt.getFrame() * currentSong.getFrameRatePerMilliseconds()); 309 | }else{ 310 | // if the user pressed next or prev we don't need to execute the rest of the code 311 | if(pressedNext || pressedPrev) return; 312 | 313 | // when the song ends 314 | songFinished = true; 315 | 316 | if(playlist == null){ 317 | // update gui 318 | musicPlayerGUI.enablePlayButtonDisablePauseButton(); 319 | }else{ 320 | // last song in the playlist 321 | if(currentPlaylistIndex == playlist.size() - 1){ 322 | // update gui 323 | musicPlayerGUI.enablePlayButtonDisablePauseButton(); 324 | }else{ 325 | // go to the next song in the playlist 326 | nextSong(); 327 | } 328 | } 329 | } 330 | } 331 | } 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | -------------------------------------------------------------------------------- /src/MusicPlayerGUI.java: -------------------------------------------------------------------------------- 1 | import javax.imageio.ImageIO; 2 | import javax.swing.*; 3 | import javax.swing.filechooser.FileNameExtensionFilter; 4 | import java.awt.*; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.awt.event.MouseAdapter; 8 | import java.awt.event.MouseEvent; 9 | import java.awt.image.BufferedImage; 10 | import java.io.File; 11 | import java.util.Hashtable; 12 | 13 | public class MusicPlayerGUI extends JFrame { 14 | // color configurations 15 | public static final Color FRAME_COLOR = Color.BLACK; 16 | public static final Color TEXT_COLOR = Color.WHITE; 17 | 18 | private MusicPlayer musicPlayer; 19 | 20 | // allow us to use file explorer in our app 21 | private JFileChooser jFileChooser; 22 | 23 | private JLabel songTitle, songArtist; 24 | private JPanel playbackBtns; 25 | private JSlider playbackSlider; 26 | 27 | public MusicPlayerGUI(){ 28 | // calls JFrame constructor to configure out gui and set the title heaader to "Music Player" 29 | super("Music Player"); 30 | 31 | // set the width and height 32 | setSize(400, 600); 33 | 34 | // end process when app is closed 35 | setDefaultCloseOperation(EXIT_ON_CLOSE); 36 | 37 | // launch the app at the center of the screen 38 | setLocationRelativeTo(null); 39 | 40 | // prevent the app from being resized 41 | setResizable(false); 42 | 43 | // set layout to null which allows us to control the (x, y) coordinates of our components 44 | // and also set the height and width 45 | setLayout(null); 46 | 47 | // change the frame color 48 | getContentPane().setBackground(FRAME_COLOR); 49 | 50 | musicPlayer = new MusicPlayer(this); 51 | jFileChooser = new JFileChooser(); 52 | 53 | // set a default path for file explorer 54 | jFileChooser.setCurrentDirectory(new File("src/assets")); 55 | 56 | // filter file chooser to only see .mp3 files 57 | jFileChooser.setFileFilter(new FileNameExtensionFilter("MP3", "mp3")); 58 | 59 | addGuiComponents(); 60 | } 61 | 62 | private void addGuiComponents(){ 63 | // add toolbar 64 | addToolbar(); 65 | 66 | // load record image 67 | JLabel songImage = new JLabel(loadImage("src/assets/record.png")); 68 | songImage.setBounds(0, 50, getWidth() - 20, 225); 69 | add(songImage); 70 | 71 | // song title 72 | songTitle = new JLabel("Song Title"); 73 | songTitle.setBounds(0, 285, getWidth() - 10, 30); 74 | songTitle.setFont(new Font("Dialog", Font.BOLD, 24)); 75 | songTitle.setForeground(TEXT_COLOR); 76 | songTitle.setHorizontalAlignment(SwingConstants.CENTER); 77 | add(songTitle); 78 | 79 | // song artist 80 | songArtist = new JLabel("Artist"); 81 | songArtist.setBounds(0, 315, getWidth() - 10, 30); 82 | songArtist.setFont(new Font("Dialog", Font.PLAIN, 24)); 83 | songArtist.setForeground(TEXT_COLOR); 84 | songArtist.setHorizontalAlignment(SwingConstants.CENTER); 85 | add(songArtist); 86 | 87 | // playback slider 88 | playbackSlider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0); 89 | playbackSlider.setBounds(getWidth()/2 - 300/2, 365, 300, 40); 90 | playbackSlider.setBackground(null); 91 | playbackSlider.addMouseListener(new MouseAdapter() { 92 | @Override 93 | public void mousePressed(MouseEvent e) { 94 | // when the user is holding the tick we want to the pause the song 95 | musicPlayer.pauseSong(); 96 | } 97 | 98 | @Override 99 | public void mouseReleased(MouseEvent e) { 100 | // when the user drops the tick 101 | JSlider source = (JSlider) e.getSource(); 102 | 103 | // get the frame value from where the user wants to playback to 104 | int frame = source.getValue(); 105 | 106 | // update the current frame in the music player to this frame 107 | musicPlayer.setCurrentFrame(frame); 108 | 109 | // update current time in milli as well 110 | musicPlayer.setCurrentTimeInMilli((int) (frame / (2.08 * musicPlayer.getCurrentSong().getFrameRatePerMilliseconds()))); 111 | 112 | // resume the song 113 | musicPlayer.playCurrentSong(); 114 | 115 | // toggle on pause button and toggle off play button 116 | enablePauseButtonDisablePlayButton(); 117 | } 118 | }); 119 | add(playbackSlider); 120 | 121 | // playback buttons (i.e. previous, play, next) 122 | addPlaybackBtns(); 123 | } 124 | 125 | private void addToolbar(){ 126 | JToolBar toolBar = new JToolBar(); 127 | toolBar.setBounds(0, 0, getWidth(), 20); 128 | 129 | // prevent toolbar from being moved 130 | toolBar.setFloatable(false); 131 | 132 | // add drop down menu 133 | JMenuBar menuBar = new JMenuBar(); 134 | toolBar.add(menuBar); 135 | 136 | // now we will add a song menu where we will place the loading song option 137 | JMenu songMenu = new JMenu("Song"); 138 | menuBar.add(songMenu); 139 | 140 | // add the "load song" item in the songMenu 141 | JMenuItem loadSong = new JMenuItem("Load Song"); 142 | loadSong.addActionListener(new ActionListener() { 143 | @Override 144 | public void actionPerformed(ActionEvent e) { 145 | // an integer is returned to us to let us know what the user did 146 | int result = jFileChooser.showOpenDialog(MusicPlayerGUI.this); 147 | File selectedFile = jFileChooser.getSelectedFile(); 148 | 149 | // this means that we are also checking to see if the user pressed the "open" button 150 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){ 151 | // create a song obj based on selected file 152 | Song song = new Song(selectedFile.getPath()); 153 | 154 | // load song in music player 155 | musicPlayer.loadSong(song); 156 | 157 | // update song title and artist 158 | updateSongTitleAndArtist(song); 159 | 160 | // update playback slider 161 | updatePlaybackSlider(song); 162 | 163 | // toggle on pause button and toggle off play button 164 | enablePauseButtonDisablePlayButton(); 165 | } 166 | } 167 | }); 168 | songMenu.add(loadSong); 169 | 170 | // now we will add the playlist menu 171 | JMenu playlistMenu = new JMenu("Playlist"); 172 | menuBar.add(playlistMenu); 173 | 174 | // then add the items to the playlist menu 175 | JMenuItem createPlaylist = new JMenuItem("Create Playlist"); 176 | createPlaylist.addActionListener(new ActionListener() { 177 | @Override 178 | public void actionPerformed(ActionEvent e) { 179 | // load music playlist dialog 180 | new MusicPlaylistDialog(MusicPlayerGUI.this).setVisible(true); 181 | } 182 | }); 183 | playlistMenu.add(createPlaylist); 184 | 185 | JMenuItem loadPlaylist = new JMenuItem("Load Playlist"); 186 | loadPlaylist.addActionListener(new ActionListener() { 187 | @Override 188 | public void actionPerformed(ActionEvent e) { 189 | JFileChooser jFileChooser = new JFileChooser(); 190 | jFileChooser.setFileFilter(new FileNameExtensionFilter("Playlist", "txt")); 191 | jFileChooser.setCurrentDirectory(new File("src/assets")); 192 | 193 | int result = jFileChooser.showOpenDialog(MusicPlayerGUI.this); 194 | File selectedFile = jFileChooser.getSelectedFile(); 195 | 196 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){ 197 | // stop the music 198 | musicPlayer.stopSong(); 199 | 200 | // load playlist 201 | musicPlayer.loadPlaylist(selectedFile); 202 | } 203 | } 204 | }); 205 | playlistMenu.add(loadPlaylist); 206 | 207 | add(toolBar); 208 | } 209 | 210 | private void addPlaybackBtns(){ 211 | playbackBtns = new JPanel(); 212 | playbackBtns.setBounds(0, 435, getWidth() - 10, 80); 213 | playbackBtns.setBackground(null); 214 | 215 | // previous button 216 | JButton prevButton = new JButton(loadImage("src/assets/previous.png")); 217 | prevButton.setBorderPainted(false); 218 | prevButton.setBackground(null); 219 | prevButton.addActionListener(new ActionListener() { 220 | @Override 221 | public void actionPerformed(ActionEvent e) { 222 | // go to the previous song 223 | musicPlayer.prevSong(); 224 | } 225 | }); 226 | playbackBtns.add(prevButton); 227 | 228 | // play button 229 | JButton playButton = new JButton(loadImage("src/assets/play.png")); 230 | playButton.setBorderPainted(false); 231 | playButton.setBackground(null); 232 | playButton.addActionListener(new ActionListener() { 233 | @Override 234 | public void actionPerformed(ActionEvent e) { 235 | // toggle off play button and toggle on pause button 236 | enablePauseButtonDisablePlayButton(); 237 | 238 | // play or resume song 239 | musicPlayer.playCurrentSong(); 240 | } 241 | }); 242 | playbackBtns.add(playButton); 243 | 244 | // pause button 245 | JButton pauseButton = new JButton(loadImage("src/assets/pause.png")); 246 | pauseButton.setBorderPainted(false); 247 | pauseButton.setBackground(null); 248 | pauseButton.setVisible(false); 249 | pauseButton.addActionListener(new ActionListener() { 250 | @Override 251 | public void actionPerformed(ActionEvent e) { 252 | // toggle off pause button and toggle on play button 253 | enablePlayButtonDisablePauseButton(); 254 | 255 | // pause the song 256 | musicPlayer.pauseSong(); 257 | } 258 | }); 259 | playbackBtns.add(pauseButton); 260 | 261 | // next button 262 | JButton nextButton = new JButton(loadImage("src/assets/next.png")); 263 | nextButton.setBorderPainted(false); 264 | nextButton.setBackground(null); 265 | nextButton.addActionListener(new ActionListener() { 266 | @Override 267 | public void actionPerformed(ActionEvent e) { 268 | // go to the next song 269 | musicPlayer.nextSong(); 270 | } 271 | }); 272 | playbackBtns.add(nextButton); 273 | 274 | add(playbackBtns); 275 | } 276 | 277 | // this will be used to update our slider from the music player class 278 | public void setPlaybackSliderValue(int frame){ 279 | playbackSlider.setValue(frame); 280 | } 281 | 282 | public void updateSongTitleAndArtist(Song song){ 283 | songTitle.setText(song.getSongTitle()); 284 | songArtist.setText(song.getSongArtist()); 285 | } 286 | 287 | public void updatePlaybackSlider(Song song){ 288 | // update max count for slider 289 | playbackSlider.setMaximum(song.getMp3File().getFrameCount()); 290 | 291 | // create the song length label 292 | Hashtable labelTable = new Hashtable<>(); 293 | 294 | // beginning will be 00:00 295 | JLabel labelBeginning = new JLabel("00:00"); 296 | labelBeginning.setFont(new Font("Dialog", Font.BOLD, 18)); 297 | labelBeginning.setForeground(TEXT_COLOR); 298 | 299 | // end will vary depending on the song 300 | JLabel labelEnd = new JLabel(song.getSongLength()); 301 | labelEnd.setFont(new Font("Dialog", Font.BOLD, 18)); 302 | labelEnd.setForeground(TEXT_COLOR); 303 | 304 | labelTable.put(0, labelBeginning); 305 | labelTable.put(song.getMp3File().getFrameCount(), labelEnd); 306 | 307 | playbackSlider.setLabelTable(labelTable); 308 | playbackSlider.setPaintLabels(true); 309 | } 310 | 311 | public void enablePauseButtonDisablePlayButton(){ 312 | // retrieve reference to play button from playbackBtns panel 313 | JButton playButton = (JButton) playbackBtns.getComponent(1); 314 | JButton pauseButton = (JButton) playbackBtns.getComponent(2); 315 | 316 | // turn off play button 317 | playButton.setVisible(false); 318 | playButton.setEnabled(false); 319 | 320 | // turn on pause button 321 | pauseButton.setVisible(true); 322 | pauseButton.setEnabled(true); 323 | } 324 | 325 | public void enablePlayButtonDisablePauseButton(){ 326 | // retrieve reference to play button from playbackBtns panel 327 | JButton playButton = (JButton) playbackBtns.getComponent(1); 328 | JButton pauseButton = (JButton) playbackBtns.getComponent(2); 329 | 330 | // turn on play button 331 | playButton.setVisible(true); 332 | playButton.setEnabled(true); 333 | 334 | // turn off pause button 335 | pauseButton.setVisible(false); 336 | pauseButton.setEnabled(false); 337 | } 338 | 339 | private ImageIcon loadImage(String imagePath){ 340 | try{ 341 | // read the image file from the given path 342 | BufferedImage image = ImageIO.read(new File(imagePath)); 343 | 344 | // returns an image icon so that our component can render the image 345 | return new ImageIcon(image); 346 | }catch(Exception e){ 347 | e.printStackTrace(); 348 | } 349 | 350 | // could not find resource 351 | return null; 352 | } 353 | } 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | -------------------------------------------------------------------------------- /src/MusicPlaylistDialog.java: -------------------------------------------------------------------------------- 1 | import javax.swing.*; 2 | import javax.swing.filechooser.FileNameExtensionFilter; 3 | import java.awt.*; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | import java.io.BufferedWriter; 7 | import java.io.File; 8 | import java.io.FileWriter; 9 | import java.util.ArrayList; 10 | 11 | public class MusicPlaylistDialog extends JDialog { 12 | private MusicPlayerGUI musicPlayerGUI; 13 | 14 | // store all of the paths to be written to a txt file (when we load a playlist) 15 | private ArrayList songPaths; 16 | 17 | public MusicPlaylistDialog(MusicPlayerGUI musicPlayerGUI){ 18 | this.musicPlayerGUI = musicPlayerGUI; 19 | songPaths = new ArrayList<>(); 20 | 21 | // configure dialog 22 | setTitle("Create Playlist"); 23 | setSize(400, 400); 24 | setResizable(false); 25 | getContentPane().setBackground(MusicPlayerGUI.FRAME_COLOR); 26 | setLayout(null); 27 | setModal(true); // this property makes it so that the dialog has to be closed to give focus 28 | setLocationRelativeTo(musicPlayerGUI); 29 | 30 | addDialogComponents(); 31 | } 32 | 33 | private void addDialogComponents(){ 34 | // container to hold each song path 35 | JPanel songContainer = new JPanel(); 36 | songContainer.setLayout(new BoxLayout(songContainer, BoxLayout.Y_AXIS)); 37 | songContainer.setBounds((int)(getWidth() * 0.025), 10, (int)(getWidth() * 0.90), (int) (getHeight() * 0.75)); 38 | add(songContainer); 39 | 40 | // add song button 41 | JButton addSongButton = new JButton("Add"); 42 | addSongButton.setBounds(60, (int) (getHeight() * 0.80), 100, 25); 43 | addSongButton.setFont(new Font("Dialog", Font.BOLD, 14)); 44 | addSongButton.addActionListener(new ActionListener() { 45 | @Override 46 | public void actionPerformed(ActionEvent e) { 47 | // open file explorer 48 | JFileChooser jFileChooser = new JFileChooser(); 49 | jFileChooser.setFileFilter(new FileNameExtensionFilter("MP3", "mp3")); 50 | jFileChooser.setCurrentDirectory(new File("src/assets")); 51 | int result = jFileChooser.showOpenDialog(MusicPlaylistDialog.this); 52 | 53 | File selectedFile = jFileChooser.getSelectedFile(); 54 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){ 55 | JLabel filePathLabel = new JLabel(selectedFile.getPath()); 56 | filePathLabel.setFont(new Font("Dialog", Font.BOLD, 12)); 57 | filePathLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 58 | 59 | // add to the list 60 | songPaths.add(filePathLabel.getText()); 61 | 62 | // add to container 63 | songContainer.add(filePathLabel); 64 | 65 | // refreshes dialog to show newly added JLabel 66 | songContainer.revalidate(); 67 | } 68 | } 69 | }); 70 | add(addSongButton); 71 | 72 | // save playlist button 73 | JButton savePlaylistButton = new JButton("Save"); 74 | savePlaylistButton.setBounds(215, (int) (getHeight() * 0.80), 100, 25); 75 | savePlaylistButton.setFont(new Font("Dialog", Font.BOLD, 14)); 76 | savePlaylistButton.addActionListener(new ActionListener() { 77 | @Override 78 | public void actionPerformed(ActionEvent e) { 79 | try{ 80 | JFileChooser jFileChooser = new JFileChooser(); 81 | jFileChooser.setCurrentDirectory(new File("src/assets")); 82 | int result = jFileChooser.showSaveDialog(MusicPlaylistDialog.this); 83 | 84 | if(result == JFileChooser.APPROVE_OPTION){ 85 | // we use getSelectedFile() to get reference to the file that we are about to save 86 | File selectedFile = jFileChooser.getSelectedFile(); 87 | 88 | // convert to .txt file if not done so already 89 | // this will check to see if the file does not have the ".txt" file extension 90 | if(!selectedFile.getName().substring(selectedFile.getName().length() - 4).equalsIgnoreCase(".txt")){ 91 | selectedFile = new File(selectedFile.getAbsoluteFile() + ".txt"); 92 | } 93 | 94 | // create the new file at the destinated directory 95 | selectedFile.createNewFile(); 96 | 97 | // now we will write all of the song paths into this file 98 | FileWriter fileWriter = new FileWriter(selectedFile); 99 | BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); 100 | 101 | // iterate through our song paths list and write each string into the file 102 | // each song will be written in their own row 103 | for(String songPath : songPaths){ 104 | bufferedWriter.write(songPath + "\n"); 105 | } 106 | bufferedWriter.close(); 107 | 108 | // display success dialog 109 | JOptionPane.showMessageDialog(MusicPlaylistDialog.this, "Successfully Created Playlist!"); 110 | 111 | // close this dialog 112 | MusicPlaylistDialog.this.dispose(); 113 | } 114 | }catch(Exception exception){ 115 | exception.printStackTrace(); 116 | } 117 | } 118 | }); 119 | add(savePlaylistButton); 120 | } 121 | } 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/Song.java: -------------------------------------------------------------------------------- 1 | import com.mpatric.mp3agic.Mp3File; 2 | import org.jaudiotagger.audio.AudioFile; 3 | import org.jaudiotagger.audio.AudioFileIO; 4 | import org.jaudiotagger.tag.FieldKey; 5 | import org.jaudiotagger.tag.Tag; 6 | 7 | import java.io.File; 8 | 9 | // class used to describe a song 10 | public class Song { 11 | private String songTitle; 12 | private String songArtist; 13 | private String songLength; 14 | private String filePath; 15 | private Mp3File mp3File; 16 | private double frameRatePerMilliseconds; 17 | 18 | public Song(String filePath){ 19 | this.filePath = filePath; 20 | try{ 21 | mp3File = new Mp3File(filePath); 22 | frameRatePerMilliseconds = (double) mp3File.getFrameCount() / mp3File.getLengthInMilliseconds(); 23 | songLength = convertToSongLengthFormat(); 24 | 25 | // use the jaudiotagger library to create an audiofile obj to read mp3 file's information 26 | AudioFile audioFile = AudioFileIO.read(new File(filePath)); 27 | 28 | // read through the meta data of the audio file 29 | Tag tag = audioFile.getTag(); 30 | if(tag != null){ 31 | songTitle = tag.getFirst(FieldKey.TITLE); 32 | songArtist = tag.getFirst(FieldKey.ARTIST); 33 | }else{ 34 | // could not read through mp3 file's meta data 35 | songTitle = "N/A"; 36 | songArtist = "N/A"; 37 | } 38 | }catch(Exception e){ 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | private String convertToSongLengthFormat(){ 44 | long minutes = mp3File.getLengthInSeconds() / 60; 45 | long seconds = mp3File.getLengthInSeconds() % 60; 46 | String formattedTime = String.format("%02d:%02d", minutes, seconds); 47 | 48 | return formattedTime; 49 | } 50 | 51 | // getters 52 | public String getSongTitle() { 53 | return songTitle; 54 | } 55 | 56 | public String getSongArtist() { 57 | return songArtist; 58 | } 59 | 60 | public String getSongLength() { 61 | return songLength; 62 | } 63 | 64 | public String getFilePath() { 65 | return filePath; 66 | } 67 | 68 | public Mp3File getMp3File(){return mp3File;} 69 | public double getFrameRatePerMilliseconds(){return frameRatePerMilliseconds;} 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3 -------------------------------------------------------------------------------- /src/assets/Tropic Fuse - French Fuse.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Tropic Fuse - French Fuse.mp3 -------------------------------------------------------------------------------- /src/assets/Wind Riders - Asher Fulero.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Wind Riders - Asher Fulero.mp3 -------------------------------------------------------------------------------- /src/assets/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/next.png -------------------------------------------------------------------------------- /src/assets/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/pause.png -------------------------------------------------------------------------------- /src/assets/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/play.png -------------------------------------------------------------------------------- /src/assets/playlist.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /src/assets/playlist2.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /src/assets/playlist3.txt: -------------------------------------------------------------------------------- 1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3 2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3 3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3 4 | -------------------------------------------------------------------------------- /src/assets/previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/previous.png -------------------------------------------------------------------------------- /src/assets/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/record.png --------------------------------------------------------------------------------