Updated Javadoc, tightened some declaration access.

This commit is contained in:
neviyn 2016-08-26 02:12:19 +01:00
parent 007a3845d4
commit 13e0b4d544
22 changed files with 395 additions and 5 deletions

View File

@ -2,14 +2,24 @@ package musicplayer;
import musicplayer.model.Song;
/**
* Exception thrown where there is an error starting playback in an IPlayer implementation.
*/
public class StartPlayingException extends Exception {
private final Song song;
/**
* Exception thrown where there is an error starting playback.
* @param song Song that was trying to be played.
*/
public StartPlayingException(Song song){
this.song = song;
}
/**
* @return The Song that was trying to be played.
*/
public Song getSong() {
return song;
}

View File

@ -16,6 +16,9 @@ import musicplayer.playlist.JTablePlaylist;
import musicplayer.swingui.PlayerGUI;
import musicplayer.util.ConfigManager;
/**
* Dependency injection setup using Swing UI Components.
*/
class SwingUIModule extends AbstractModule {
@Override

View File

@ -1,14 +1,22 @@
package musicplayer.callbacks;
/**
* Callback interface used by IPlayer implementations to inform the front end of the current seek state.
*/
public interface PlayerCallbackInterface {
/**
* Set the seekbar position.
* Set the seekbar duration.
*
* @param seconds Position to set the seekbar to.
*/
void setSeekBarDuration(int seconds);
/**
* Set the seekbar position.
*
* @param position Position to set the seekbar to.
*/
void setSeekBarPosition(int position);
}

View File

@ -11,20 +11,63 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* Interface for interacting with a database.
*/
public abstract class IDatabase {
/**
* @param name Name of the album to find.
* @return Album found with name or Optional.empty()
*/
abstract public Optional<Album> getOneAlbum(String name);
/**
* @param name Name of the artist to find.
* @return Artist found with name or Optional.empty()
*/
abstract public Optional<Artist> getOneArtist(String name);
/**
* @param metadata Metadata of song to find.
* @return Song found with metadata or Optional.empty()
*/
abstract public Optional<Song> getOneSong(ExtractedMetadata metadata);
/**
* Delete all songs that don't have ids in the given list.
* @param validIds List of songs to keep.
*/
abstract public void batchDeleteNot(Long[] validIds);
/**
* List all items in the database of a certain type.
* @param typeClass Class representing the type of items to find.
* @return List of all items in the database of class typeClass.
*/
abstract public <T extends IDBType> Optional<List<T>> listAllT(Class<T> typeClass);
/**
* Add a new song to the database.
* If the song already exists it will be updated instead.
* @param metadata New song information.
* @return Object representing song that was added.
*/
abstract public Song addSong(ExtractedMetadata metadata);
/**
* Add a new song to the database.
* If the song already exists it will be updated instead.
* @param song New song information.
*/
abstract public void addSong(Song song);
private static String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
private static final String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
/**
* Add all songs contained with all paths in rootDirectory to the database.
* @param library Library to inform when database has been updated.
* @param rootDirectory Folder(s) containing music files to index.
*/
public void processSongsWithCallback(ILibrary library, List<Path> rootDirectory){

View File

@ -3,13 +3,38 @@ package musicplayer.library;
import musicplayer.db.IDatabase;
import musicplayer.model.HasSongs;
/**
* Interface for interacting with a library front end element.
*/
public abstract class ILibrary {
IDatabase database;
final IDatabase database;
/**
* Show a list of all songs in the library area.
*/
abstract public void showSongs();
/**
* Show a list of all songs in the library area, grouped by a certain related type.
* @param grouping Type by which songs will be grouped.
* @param <T> Type by which songs will be grouped.
*/
abstract public <T extends HasSongs & Comparable<T>> void showGroupedSongs(Class<T> grouping);
/**
* Set the library to updating mode and start processing songs in library folders.
*/
abstract public void updateLibrary();
/**
* Refresh the content currently displayed in the library view.
*/
abstract public void refreshLibrary();
/**
* Create a new library representation.
* @param database Database that this library represents.
*/
public ILibrary(IDatabase database){
this.database = database;
}

View File

@ -30,6 +30,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* An ILibrary implementation that displays the library in a tree format using a Swing JTree.
*/
public class JTreeLibrary extends ILibrary{
private final IPlaylist playlist;
@ -55,6 +58,10 @@ public class JTreeLibrary extends ILibrary{
return value;
}
/**
* @param database Song database.
* @param playlist Playlist element.
*/
@Inject
public JTreeLibrary(IDatabase database, IPlaylist playlist){
super(database);

View File

@ -20,6 +20,9 @@ import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
/**
* Representation of an Album.
*/
@Entity
@Table(name = "Album")
public class Album implements Comparable<Album>, IDBType, HasSongs {
@ -42,6 +45,10 @@ public class Album implements Comparable<Album>, IDBType, HasSongs {
protected Album() {
}
/**
* Create a new Album.
* @param name Name of the album.
*/
public Album(String name){
this.name = name;
}
@ -73,10 +80,16 @@ public class Album implements Comparable<Album>, IDBType, HasSongs {
return result;
}
/**
* @return The name of this album.
*/
public String getName() {
return name;
}
/**
* @return The id of this album.
*/
public long getId() {
return id;
}

View File

@ -3,6 +3,9 @@ package musicplayer.model;
import javax.persistence.*;
import java.util.Set;
/**
* Representation of an Artist.
*/
@Entity
@Table(name = "Artist")
public class Artist implements Comparable<Artist>, IDBType, HasSongs {
@ -19,6 +22,10 @@ public class Artist implements Comparable<Artist>, IDBType, HasSongs {
protected Artist() {
}
/**
* Create a new Artist.
* @param name Name of the artist.
*/
public Artist(String name) {
this.name = name;
}
@ -50,10 +57,16 @@ public class Artist implements Comparable<Artist>, IDBType, HasSongs {
}
/**
* @return The name of this artist.
*/
public String getName() {
return name;
}
/**
* @return The id of this artist.
*/
public long getId() {
return id;
}

View File

@ -29,18 +29,39 @@ public class ExtractedMetadata {
this.songFile = songFile.getAbsolutePath();
}
/**
* @return Title of this song.
*/
public String getTitle(){ return audioTags.getFirst(FieldKey.TITLE); }
/**
* @return Artist of this song.
*/
public String getArtist(){ return audioTags.getFirst(FieldKey.ARTIST); }
/**
* @return Album this song is in.
*/
public String getAlbum(){ return audioTags.getFirst(FieldKey.ALBUM); }
/**
* @return Track number of this song.
*/
public String getTrackNumber(){ return audioTags.getFirst(FieldKey.TRACK); }
/**
* @return Genre of this song.
*/
public String getGenre(){ return audioTags.getFirst(FieldKey.GENRE); }
/**
* @return Number of the disc this song is on.
*/
public String getDiscNumber(){ return audioTags.getFirst(FieldKey.DISC_NO); }
/**
* @return Path to the file of this song.
*/
public String getSongFile(){ return songFile; }
@Override

View File

@ -2,7 +2,13 @@ package musicplayer.model;
import java.util.Set;
/**
* Identifier for any model class that has an associated list of songs.
*/
public interface HasSongs extends IDBType {
/**
* @return A Set of all songs associated with this item.
*/
Set<Song> getSongs();
}

View File

@ -1,4 +1,7 @@
package musicplayer.model;
/**
* Identifier for any type that is stored in the database.
*/
public interface IDBType {
}

View File

@ -3,6 +3,9 @@ package musicplayer.model;
import javax.persistence.*;
import java.io.File;
/**
* Representation of a Song.
*/
@Entity
@Table(name = "Song")
public class Song implements Comparable<Song>, IDBType {
@ -87,34 +90,58 @@ public class Song implements Comparable<Song>, IDBType {
return result;
}
/**
* @return ID of this song.
*/
public long getId() {
return id;
}
/**
* @return Artist whom created this song.
*/
public Artist getArtist() {
return artist;
}
/**
* @return Genre of this song.
*/
public String getGenre() {
return genre;
}
/**
* @return Title of this song.
*/
public String getTitle() {
return title;
}
/**
* @return Album containing this song.
*/
public Album getAlbum() {
return album;
}
/**
* @return Song file that this Song represents.
*/
public File getSongFile() {
return new File(songFile);
}
/**
* @return Track number of this song on Album.
*/
public Integer getTrackNumber() {
return trackNumber;
}
/**
* @return Number of the disc in Album that this song is on.
*/
public Integer getDiscNumber() { return discNumber; }
@Override
@ -153,6 +180,10 @@ public class Song implements Comparable<Song>, IDBType {
this.songFile = songFile;
}
/**
* Update the data contained in this song.
* @param other Song object to copy new data from.
*/
public void updateData(Song other){
updateData(other.getTrackNumber().toString(), other.getDiscNumber().toString(), other.getTitle(), other.getArtist(), other.getAlbum(), other.getGenre(), other.songFile);
}

View File

@ -15,6 +15,9 @@ import org.gstreamer.elements.PlayBin2;
import java.io.File;
import java.util.Optional;
/**
* Music playback implementation using GStreamer 0.10.
*/
public class GStreamerPlayer implements IPlayer{
private final PlayBin2 playBin;
@ -37,6 +40,12 @@ public class GStreamerPlayer implements IPlayer{
this(callbackInterface, playlist, false);
}
/**
* Manages GStreamer based playback operations.
* @param callbackInterface Interface on which UI updates can be called.
* @param playlist Playlist containing music to play.
* @param testMode Set this player to test mode (disables actual audio output).
*/
public GStreamerPlayer(PlayerCallbackInterface callbackInterface, IPlaylist playlist, boolean testMode) {
this.callbackInterface = callbackInterface;
this.playlist = playlist;
@ -171,10 +180,18 @@ public class GStreamerPlayer implements IPlayer{
playBin.pause();
}
/**
* Start playing the next song in the playlist.
* @throws StartPlayingException Couldn't start playing.
*/
public void next() throws StartPlayingException {
playSong(playlist.getNext(currentSong));
}
/**
* Start playing the previous song in the playlist.
* @throws StartPlayingException Couldn't start playing.
*/
public void previous() throws StartPlayingException{
playSong(playlist.getPrevious(currentSong));
}
@ -231,11 +248,21 @@ public class GStreamerPlayer implements IPlayer{
}
}
/**
* @return Is a song currently playing.
*/
public boolean isPlaying(){
return playBin.isPlaying();
}
/**
* Set whether to loop the current song.
* @param repeatMode True = repeat the current song indefinitely.
*/
public void setRepeat(boolean repeatMode) { this.repeatMode = repeatMode; }
/**
* @return Is the player set to loop one song.
*/
public boolean isRepeating(){ return repeatMode; }
}

View File

@ -5,20 +5,92 @@ import musicplayer.model.Song;
import java.util.Optional;
/**
* Interface for music playback back-ends.
*/
public interface IPlayer {
/**
* Play the currently active song in the playlist.
* @throws StartPlayingException Couldn't start playing.
*/
void play() throws StartPlayingException;
/**
* Play a song
* @param inputSong Song to play.
* @throws StartPlayingException Couldn't start playing.
*/
void playSong(Optional<Song> inputSong) throws StartPlayingException;
/**
* Stop any music currently playing.
*/
void stop();
/**
* Resume playing a paused song.
*/
void resume();
/**
* Pause the currently playing song.
*/
void pause();
/**
* Start playing the next song in the playlist.
* @throws StartPlayingException Couldn't start playing.
*/
void next() throws StartPlayingException;
/**
* Start playing the previous song in the playlist.
* @throws StartPlayingException Couldn't start playing.
*/
void previous() throws StartPlayingException;
/**
* @return The Song currently being played or ready to be played.
*/
Song getCurrentSong();
/**
* @return Current playback position in seconds.
*/
int currentSongPosition();
/**
* Set the player volume.
* @param volume New volume in percent.
*/
void setVolume(int volume);
/**
* @return Current Player volume in percent.
*/
int getVolume();
/**
* Seek to a position in the song.
* @param position Position (in seconds) to seek to.
*/
void seek(int position);
/**
* @return Is a song currently playing.
*/
boolean isPlaying();
/**
* Set whether to loop the current song.
* @param repeatMode True = repeat the current song indefinitely.
*/
void setRepeat(boolean repeatMode);
/**
* @return Is the player set to loop one song.
*/
boolean isRepeating();
}

View File

@ -16,6 +16,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
/**
* Music playback implementation using libVLC.
*/
public class VLCPlayer implements IPlayer {
private final ArrayList<String> libvlcArgs = new ArrayList<>(Collections.singletonList("--vout=dummy"));

View File

@ -14,28 +14,105 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Interface for a playlist implementation.
*/
public interface IPlaylist {
/**
* Add a song to the playlist.
* @param song Song to add.
*/
void addSong(Song song);
/**
* Get the first Song in the playlist.
* @return Song that is first in the playlist, or empty if playlist is empty.
*/
Optional<Song> getFirst();
/**
* Get the next Song in the playlist.
* @param currentSong The song in the playlist to get the "next" song from.
* @return Song that is next in the playlist, or empty if playlist is empty.
*/
Optional<Song> getNext(Song currentSong);
/**
* Get the next Song in the playlist.
* @param currentSong The song in the playlist to get the "previous" song from.
* @return Song that is previous in the playlist, or empty if playlist is empty.
*/
Optional<Song> getPrevious(Song currentSong);
/**
* Get the Song at index in the playlist.
* @param index Index of the song to get.
* @return Song that is at index in the playlist, or empty if playlist is empty or index invalid.
*/
Optional<Song> get(int index);
/**
* @return The Song currently being played or paused/stopped but ready to play, empty if playlist empty or no
* song active.
*/
Optional<Song> getActive();
/**
* @return List of songs in the current playlist.
*/
List<Song> getSongList();
/**
* Get the index of Song in the playlist.
* @param song Song to get the index of.
* @return Index of the song, or -1 if not in playlist.
*/
int getIndex(Song song);
/**
* Delete a song from the playlist.
* @param song Song to delete.
*/
void delete(Song song);
/**
* Delete a song from the playlist.
* @param index Index of song to delete.
*/
void delete(int index);
/**
* Delete songs from the playlist.
* @param index List of indexes of songs to be removed.
*/
void delete(int[] index);
/**
* Delete all songs from the playlist.
*/
void deleteAll();
/**
* @return True = playlist is empty.
*/
boolean isEmpty();
/**
* Set a song as the currently playing song.
* @param song Song currently playing.
*/
void setPlayingSong(Song song);
/**
* Set playlist state to that when playback has stopped.
*/
void setStopped();
/**
* Write a list of songs to a file as an m3u format playlist file.
* @param playlist Playlist of songs to write.
* @param targetFile File to write playlist into.
* @throws IOException
* @throws IOException Failed to write file.
*/
static void writePlaylistToFile(List<Song> playlist, File targetFile) throws IOException {
if(targetFile.exists() || targetFile.createNewFile()) {

View File

@ -8,11 +8,17 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Implementation of a playlist using a JTable to render a playlist.
*/
public class JTablePlaylist extends JScrollPane implements IPlaylist {
private final PlaylistTableModel playlistTableModel;
private final JTable playList;
/**
* Implementation of a playlist using a JTable to render a playlist.
*/
public JTablePlaylist(){
playList = new JTable();
playlistTableModel = new PlaylistTableModel();

View File

@ -7,6 +7,9 @@ import musicplayer.util.Icons;
import javax.swing.*;
import java.awt.*;
/**
* Music control bar using Swing elements.
*/
class ControlBar extends JPanel {
private final IPlayer player;

View File

@ -8,6 +8,9 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* UI for editing config settings.
*/
class LibraryConfigGUI {
private JList<File> listLibraryFolders;
private final LibraryListModel<File> listModel = new LibraryListModel<>();
@ -83,7 +86,7 @@ class LibraryConfigGUI {
}
}
public void removeSelected(){
private void removeSelected(){
List<File> files = listLibraryFolders.getSelectedValuesList();
files.forEach(listModel::removeFile);
saveLibraryList();

View File

@ -30,6 +30,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* Swing based music player UI.
*/
public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
private final IPlaylist playlist;
private JSlider seekBar;
@ -37,6 +40,12 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
private final ILibrary library;
private final AtomicBoolean seeking = new AtomicBoolean(false);
/**
* Swing based music player UI.
* @param player Playback engine.
* @param playlist Playlist UI element.
* @param library Library UI element.
*/
@Inject
public PlayerGUI(IPlayer player, IPlaylist playlist, ILibrary library) {
this.player = player;

View File

@ -10,6 +10,10 @@ import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
/**
* Class to manage config options.
* Stores settings filename and various settings keys.
*/
public final class ConfigManager {
private static final String settingsFilename = "settings.cfg";

View File

@ -2,6 +2,9 @@ package musicplayer.util;
import javax.swing.*;
/**
* References to ImageIcons to use in the UI.
*/
@SuppressWarnings("ConstantConditions")
public final class Icons {