diff --git a/build.gradle b/build.gradle index 4a3fb55..dcd7189 100644 --- a/build.gradle +++ b/build.gradle @@ -9,4 +9,4 @@ * For more details take a look at the Java Quickstart chapter in the Gradle * user guide available at https://docs.gradle.org/4.4.1/userguide/tutorial_java_projects.html */ -ext.defaultPackage = "edu.regis" +ext.defaultPackage = "edu.regis.universe_player" diff --git a/interface/src/main/java/edu/regis/universe_player/data/Album.java b/interface/src/main/java/edu/regis/universe_player/data/Album.java new file mode 100644 index 0000000..2cf0718 --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/data/Album.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.data; + +import java.awt.Image; + +import javax.swing.ImageIcon; + +public class Album implements Comparable +{ + public int id; + public String name; + public String[] artists; + public ImageIcon art; + public int year; + public String[] genres; + public int totalTracks; + + @Override + public int compareTo(Album o) + { + if (o != null) + { + return this.name.compareTo(o.name); + } + else + { + return -1; + } + } +} diff --git a/interface/src/main/java/edu/regis/universe_player/data/CompiledSongProvider.java b/interface/src/main/java/edu/regis/universe_player/data/CompiledSongProvider.java new file mode 100644 index 0000000..3315f49 --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/data/CompiledSongProvider.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.data; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +/** + * A song provider that serves as a central point for any and all song providers, caching the results in memory for quick and easy access. + * + * @author William Hubbard + * @version 0.1 + */ +public class CompiledSongProvider implements SongProvider +{ + /** + * A set of all providers we pull from + */ + private HashMap> providers = new HashMap<>(); + + /** + * A cache of all albums used. + */ + private HashMap> cachedAlbums = new HashMap<>(); + + /** + * A cache of all album names. + */ + private HashMap cachedAlbumNames = new HashMap<>(); + + /** + * A cache of all songs used. + */ + private HashSet cachedSongs = new HashSet<>(); + + /** + * A cache of all song artists used. + */ + private HashMap> cachedArtists = new HashMap<>(); + + /** + * A cache of all album artists used. + */ + private HashMap> cachedAlbumArtists = new HashMap<>(); + + /** + * A cache of all genres used. + */ + private HashMap> cachedGenres = new HashMap<>(); + + /** + * A cache of all years used. + */ + private HashMap> cachedYears = new HashMap<>(); + + /** + * Creates a new CompiledSongProvider containing a set of existing providers. + * + * @param providers - Providers to add. + */ + public CompiledSongProvider(SongProvider... providers) + { + for (SongProvider provider : providers) + { + this.addProvider(provider); + } + } + + /** + * Adds a provider to the list + * + * @param provider - The provider to add. + */ + public void addProvider(SongProvider provider) + { + if (!this.providers.containsKey(provider)) + { + this.providers.put(provider, new HashSet<>(provider.getSongs())); + this.addToCache(provider); + } + } + + /** + * Caches all the songs contained in a provider. + * + * @param provider - The provider to cache. + */ + private void addToCache(SongProvider provider) + { + for (Song song : provider.getSongs()) + { + if (this.cachedSongs.add(song)) + { + this.cachedAlbumNames.put(song.album.name, song.album); + if (!this.cachedAlbums.containsKey(song.album)) + { + this.cachedAlbums.put(song.album, new HashSet<>()); + } + this.cachedAlbums.get(song.album).add(song); + for (String artist : song.artists) + { + if (!this.cachedArtists.containsKey(artist)) + { + this.cachedArtists.put(artist, new HashSet<>()); + } + this.cachedArtists.get(artist).add(song); + } + for (String artist : song.album.artists) + { + if (!this.cachedAlbumArtists.containsKey(artist)) + { + this.cachedAlbumArtists.put(artist, new HashSet<>()); + } + this.cachedAlbumArtists.get(artist).add(song.album); + } + for (String genre : song.album.genres) + { + if (!this.cachedGenres.containsKey(genre)) + { + this.cachedGenres.put(genre, new HashSet<>()); + } + this.cachedGenres.get(genre).add(song.album); + } + if (!this.cachedYears.containsKey(song.album.year)) + { + this.cachedYears.put(song.album.year, new HashSet<>()); + } + this.cachedYears.get(song.album.year).add(song.album); + } + else + { + /* + * If we couldn't add it, then another provider has provided that song already. We + * should remove it from our collection just to ensure that there is no confusion. + */ + this.providers.get(provider).remove(song); + } + } + } + + /** + * Removes a provider from the compilation. + * + * @param provider - The provider to remove. + */ + public void removeProvider(SongProvider provider) + { + this.removeFromCache(provider); + } + + /** + * Removes all songs from a provider from a cache. + * + * @param provider - The provider to move out. + */ + private void removeFromCache(SongProvider provider) + { + Set songs = this.providers.remove(provider); + if (songs != null) + { + for (Song song : songs) + { + this.cachedSongs.remove(song); + this.cachedAlbums.get(song.album).remove(song); + /* + * Remove empty albums + */ + if (this.cachedAlbums.get(song.album).isEmpty()) + { + this.cachedAlbums.remove(song.album); + this.cachedAlbumNames.remove(song.album.name); + } + for (String artist : song.artists) + { + this.cachedArtists.get(artist).remove(song); + if (this.cachedArtists.get(artist).isEmpty()) + { + this.cachedArtists.remove(artist); + } + } + for (String artist : song.album.artists) + { + this.cachedAlbumArtists.get(artist).remove(song.album); + if (this.cachedAlbumArtists.get(artist).isEmpty()) + { + this.cachedAlbumArtists.remove(artist); + } + } + for (String genre : song.album.genres) + { + this.cachedGenres.get(genre).remove(song.album); + if (this.cachedGenres.get(genre).isEmpty()) + { + this.cachedGenres.remove(genre); + } + } + this.cachedYears.get(song.album.year).remove(song.album); + if (this.cachedYears.get(song.album.year).isEmpty()) + { + this.cachedYears.remove(song.album.year); + } + } + } + } + + /** + * Obtains all albums within the collection. + * + * @return A list of albums. + */ + @Override + public Collection getAlbums() + { + return this.cachedAlbums.keySet(); + } + + /** + * Obtains all songs within the collection. + * + * @return A list of songs. + */ + @Override + public Collection getSongs() + { + return this.cachedSongs; + } + + /** + * Obtains a list of all artists. + * + * @return All artists. + */ + @Override + public Collection getArtists() + { + return this.cachedArtists.keySet(); + } + + /** + * Obtains a list of all album artists. + * + * @return All album artists. + */ + @Override + public Collection getAlbumArtists() + { + return this.cachedAlbumArtists.keySet(); + } + + /** + * Obtains a list of all genres. + * + * @return All genres. + */ + @Override + public Collection getGenres() + { + return this.cachedGenres.keySet(); + } + + /** + * Obtains a list of all years that have albums. + * + * @return All years. + */ + @Override + public Collection getYears() + { + return this.cachedYears.keySet(); + } + + /** + * Obtains all songs from an album. + * + * @param album - The album to obtain + * @return All songs from the requested album, or null if that album is not in the database. + */ + @Override + public Collection getSongsFromAlbum(Album album) + { + return this.cachedAlbums.get(album); + } + + /** + * Obtains all songs written by a given artist. + * + * @param artist - The artist to search for + * @return A list of all songs from the specified artist, or null if that artist is not in the + * database. + */ + @Override + public Collection getSongsFromArtist(String artist) + { + return this.cachedArtists.get(artist); + } + + /** + * Obtains an album by a specific name. + * + * @param name - The name to search for. + * @return - The first album that matches the given name, or null if that album name is not in + * the database. + */ + @Override + public Album getAlbumByName(String name) + { + return this.cachedAlbumNames.get(name); + } + + /** + * Obtains all albums that were written by a certain artist. + * + * @param artist - The artist to search for. + * @return - The collection on matching albums. + */ + @Override + public Collection getAlbumsFromArtist(String artist) + { + return this.cachedAlbumArtists.get(artist); + } + + /** + * Obtains all albums that match a certain genre + * + * @param genre - The genre to search for. + * @return - The collection on matching albums. + */ + @Override + public Collection getAlbumsFromGenre(String genre) + { + return this.cachedGenres.get(genre); + } + + /** + * Obtains all albums that were released a certain year. + * + * @param year - The year to search for. + * @return - The collection on matching albums. + */ + @Override + public Collection getAlbumsFromYear(int year) + { + return this.cachedYears.get(year); + } +} diff --git a/interface/src/main/java/edu/regis/universe_player/data/SimpleSongProvider.java b/interface/src/main/java/edu/regis/universe_player/data/SimpleSongProvider.java new file mode 100644 index 0000000..7dfbe05 --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/data/SimpleSongProvider.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * A test song database that automatically generates a handful of songs. + * + * @author William Hubbard + * @version 0.1 + */ +public class SimpleSongProvider implements SongProvider +{ + private ArrayList albums; + private ArrayList songs; + + @Override + public Collection getAlbums() + { + if (albums == null) + { + albums = new ArrayList<>(); + Random random = new Random(); + StringBuilder builder; + String albumName, albumArtist; + Album album; + for (int albumNum = 0, numAlbums = random + .nextInt(5) + 5; albumNum < numAlbums; albumNum++) + { + builder = new StringBuilder(); + for (int i = 0, l = random.nextInt(10) + 10; i < l; i++) + { + builder.append((char) (random.nextInt(26) + 97)); + } + albumName = builder.toString(); + + builder = new StringBuilder(); + for (int i = 0, l = random.nextInt(10) + 10; i < l; i++) + { + builder.append((char) (random.nextInt(26) + 97)); + } + albumArtist = builder.toString(); + + album = new Album() + { + }; + + album.name = albumName; + album.artists = new String[]{albumArtist}; + album.genres = new String[]{"Soundtrack"}; + album.year = 2019; + album.totalTracks = random.nextInt(10) + 10; + album.id = albumNum; + + albums.add(album); + } + } + + return albums; + } + + @Override + public Collection getSongs() + { + if (songs == null) + { + /* + * Generate a list of songs + */ + Random random = new Random(); + StringBuilder builder; + String songTitle; + Song song; + int songNum, numSongs; + songs = new ArrayList<>(); + for (Album album : this.getAlbums()) + { + for (songNum = 0, numSongs = album.totalTracks; songNum < numSongs; songNum++) + { + builder = new StringBuilder(); + for (int i = 0, l = random.nextInt(10) + 10; i < l; i++) + { + builder.append((char) (random.nextInt(26) + 97)); + } + songTitle = builder.toString(); + + song = new Song() + { + }; + song.title = songTitle; + song.disc = 1; + song.trackNum = songNum + 1; + song.artists = album.artists.clone(); + song.album = album; + songs.add(song); + } + album.totalTracks = numSongs; + } + } + return this.songs; + } + + @Override + public Collection getArtists() + { + return this.songs.stream().flatMap(song -> Arrays.stream(song.artists)).sorted() + .collect(Collectors.toList()); + } + + @Override + public Collection getGenres() + { + return this.songs.stream().flatMap(song -> Arrays.stream(song.album.genres)).sorted() + .collect(Collectors.toList()); + } + + @Override + public Collection getAlbumArtists() + { + return this.albums.stream().flatMap(album -> Arrays.stream(album.artists)).sorted() + .collect(Collectors.toList()); + } + + @Override + public Collection getYears() + { + return this.albums.stream().map(album -> album.year).sorted() + .collect(Collectors.toList()); + } + + @Override + public Collection getSongsFromAlbum(Album album) + { + return this.songs.stream().filter(song -> song.album == album).sorted() + .collect(Collectors.toList()); + } + + @Override + public Collection getSongsFromArtist(String artist) + { + return this.songs.stream().filter(song -> Arrays.asList(song.artists).contains(artist)).sorted() + .collect(Collectors.toList()); + } + + @Override + public Album getAlbumByName(String name) + { + return this.albums.stream().filter(album -> album.name.equals(name)).findFirst().orElse(null); + } + + @Override + public Collection getAlbumsFromArtist(String artist) + { + return this.albums.stream().filter(album -> Arrays.asList(album.artists).contains(artist)) + .sorted().collect(Collectors.toList()); + } + + @Override + public Collection getAlbumsFromGenre(String genre) + { + return this.albums.stream().filter(album -> Arrays.asList(album.genres).contains(genre)) + .sorted().collect(Collectors.toList()); + } + + @Override + public Collection getAlbumsFromYear(int year) + { + return this.albums.stream().filter(album -> album.year == year) + .sorted().collect(Collectors.toList()); + } +} diff --git a/interface/src/main/java/edu/regis/universe_player/data/Song.java b/interface/src/main/java/edu/regis/universe_player/data/Song.java new file mode 100644 index 0000000..27fb773 --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/data/Song.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.data; + +/** + * Contains data for a song. + */ +public abstract class Song implements Comparable +{ + public String title; + public String[] artists; + public int trackNum; + public int disc; + /** + * A reference to the album this song is part of. + */ + public Album album; + + @Override + public int compareTo(Song o) + { + if (o != null) + { + int comp = this.album.compareTo(o.album); + if (comp == 0) + { + comp = Integer.compare(this.disc, o.disc); + if (comp == 0) + { + comp = Integer.compare(this.trackNum, o.trackNum); + if (comp == 0) + { + comp = this.title.compareTo(o.title); + } + } + } + return comp; + } + else + { + return -1; + } + } +} diff --git a/interface/src/main/java/edu/regis/universe_player/data/SongProvider.java b/interface/src/main/java/edu/regis/universe_player/data/SongProvider.java new file mode 100644 index 0000000..91b5545 --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/data/SongProvider.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.data; + +import java.util.Collection; + +/** + * The song provider interface serves to give the application access to any form of song database as needed. + * + * @author William Hubbard + * @version 0.1 + */ +public interface SongProvider +{ + /** + * A SongProvider instance designed to + */ + CompiledSongProvider INSTANCE = new CompiledSongProvider(new SimpleSongProvider()); + + /** + * Obtains all albums within the collection. + * + * @return A list of albums. + */ + Collection getAlbums(); + + /** + * Obtains all songs within the collection. + * + * @return A list of songs. + */ + Collection getSongs(); + + /** + * Obtains a list of all artists. + * + * @return All artists. + */ + Collection getArtists(); + + /** + * Obtains a list of all album artists. + * + * @return All album artists. + */ + Collection getAlbumArtists(); + + /** + * Obtains a list of all genres. + * + * @return All genres. + */ + Collection getGenres(); + + /** + * Obtains a list of all years that have albums. + * + * @return All years. + */ + Collection getYears(); + + /** + * Obtains all songs from an album. + * + * @param album - The album to obtain + * @return All songs from the requested album, or null if that album is not in the database. + */ + Collection getSongsFromAlbum(Album album); + + /** + * Obtains all songs written by a given artist. + * + * @param artist - The artist to search for + * @return A list of all songs from the specified artist, or null if that artist is not in the + * database. + */ + Collection getSongsFromArtist(String artist); + + /** + * Obtains an album by a specific name. + * + * @param name - The name to search for. + * @return - The first album that matches the given name, or null if that album name is not in + * the database. + */ + Album getAlbumByName(String name); + + /** + * Obtains all albums that were written by a certain artist. + * + * @param artist - The artist to search for. + * @return - The collection on matching albums. + */ + Collection getAlbumsFromArtist(String artist); + + /** + * Obtains all albums that match a certain genre + * + * @param genre - The genre to search for. + * @return - The collection on matching albums. + */ + Collection getAlbumsFromGenre(String genre); + + /** + * Obtains all albums that were released a certain year. + * + * @param year - The year to search for. + * @return - The collection on matching albums. + */ + Collection getAlbumsFromYear(int year); +} diff --git a/interface/src/main/java/edu/regis/universe_player/player/AlbumInfo.java b/interface/src/main/java/edu/regis/universe_player/player/AlbumInfo.java new file mode 100644 index 0000000..fd81e3c --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/player/AlbumInfo.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.player; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SpringLayout; + +import edu.regis.universe_player.data.Album; + +/** + * This panel will display information on an album. + */ +public class AlbumInfo extends JPanel +{ + private Album album; + private JLabel artLabel; + private JLabel albumName; + private JLabel artists; + private JLabel genres; + private JLabel year; + + public AlbumInfo() + { + SpringLayout infoLayout = new SpringLayout(); + this.setLayout(infoLayout); + + this.artLabel = new JLabel(); + this.add(this.artLabel); + this.albumName = new JLabel("Album"); + this.add(this.albumName); + this.artists = new JLabel("Artists"); + this.add(this.artists); + this.genres = new JLabel("Genres"); + this.add(this.genres); + this.year = new JLabel("20XX"); + this.add(this.year); + + /* + * Set the layout information + */ + infoLayout.putConstraint(SpringLayout.NORTH, artLabel, 5, SpringLayout.NORTH, this); + infoLayout.putConstraint(SpringLayout.WEST, artLabel, 5, SpringLayout.WEST, this); + infoLayout.putConstraint(SpringLayout.NORTH, albumName, 5, SpringLayout.NORTH, this); + infoLayout.putConstraint(SpringLayout.WEST, albumName, 5, SpringLayout.EAST, artLabel); + infoLayout.putConstraint(SpringLayout.NORTH, artists, 5, SpringLayout.SOUTH, albumName); + infoLayout.putConstraint(SpringLayout.WEST, artists, 5, SpringLayout.EAST, artLabel); + infoLayout.putConstraint(SpringLayout.NORTH, genres, 5, SpringLayout.SOUTH, artists); + infoLayout.putConstraint(SpringLayout.WEST, genres, 5, SpringLayout.EAST, artLabel); + infoLayout.putConstraint(SpringLayout.NORTH, year, 5, SpringLayout.SOUTH, genres); + infoLayout.putConstraint(SpringLayout.WEST, year, 5, SpringLayout.EAST, artLabel); +// infoLayout.putConstraint(SpringLayout.EAST, this, 0, SpringLayout.EAST, albumName); + infoLayout.putConstraint(SpringLayout.EAST, this, 0, SpringLayout.EAST, artists); +// infoLayout.putConstraint(SpringLayout.EAST, this, 0, SpringLayout.EAST, genres); +// infoLayout.putConstraint(SpringLayout.EAST, this, 0, SpringLayout.EAST, year); + infoLayout.putConstraint(SpringLayout.SOUTH, this, 5, SpringLayout.EAST, artLabel); + } + + public AlbumInfo(Album album) + { + this(); + this.updateInfo(album); + } + + public void updateInfo(Album album) + { + final int ART_SIZE = 128; + ImageIcon icon; + StringBuilder builder; + + this.album = album; + + if (album.art != null) + { + icon = album.art; + } + else + { + icon = new ImageIcon(this.getClass() + .getResource("/gui/icons/defaultart.png"), "Default"); + } + icon.setImage(icon.getImage().getScaledInstance(ART_SIZE, ART_SIZE, 0)); + this.artLabel.setIcon(icon); + + this.albumName.setText(album.name); + + builder = new StringBuilder(); + if (album.artists != null && album.artists.length >= 1) + { + builder.append(album.artists[0]); + for (int i = 1, l = album.artists.length - 1; i < l; i++) + { + builder.append(", "); + builder.append(album.artists[i]); + } + if (album.artists.length > 1) + { + builder.append(" & "); + builder.append(album.artists[album.artists.length - 1]); + } + } + this.artists.setText(builder.toString()); + + builder = new StringBuilder(); + if (album.genres != null && album.genres.length >= 1) + { + builder.append(album.genres[0]); + for (int i = 1, l = album.genres.length - 1; i < l; i++) + { + builder.append(", "); + builder.append(album.genres[i]); + } + if (album.genres.length > 1) + { + builder.append(" & "); + builder.append(album.genres[album.genres.length - 1]); + } + } + this.genres.setText(builder.toString()); + + this.year.setText(String.valueOf(album.year)); + } +} diff --git a/interface/src/main/java/edu/regis/universe_player/player/Interface.java b/interface/src/main/java/edu/regis/universe_player/player/Interface.java index 5bebc79..d4b0370 100644 --- a/interface/src/main/java/edu/regis/universe_player/player/Interface.java +++ b/interface/src/main/java/edu/regis/universe_player/player/Interface.java @@ -7,6 +7,7 @@ package edu.regis.universe_player.player; import java.awt.BorderLayout; import javax.swing.JFrame; +import javax.swing.JScrollPane; /** * The Interface class serves as the primary GUI that the player interacts with. @@ -29,6 +30,10 @@ public class Interface extends JFrame this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add(new Collections(), BorderLayout.LINE_START); this.getContentPane().add(new PlayerControls(), BorderLayout.PAGE_END); + + JScrollPane songList = new JScrollPane(new SongList()); + this.getContentPane().add(songList, BorderLayout.CENTER); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } \ No newline at end of file diff --git a/interface/src/main/java/edu/regis/universe_player/player/SongList.java b/interface/src/main/java/edu/regis/universe_player/player/SongList.java new file mode 100644 index 0000000..931757f --- /dev/null +++ b/interface/src/main/java/edu/regis/universe_player/player/SongList.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 William Hubbard. All Rights Reserved. + */ + +package edu.regis.universe_player.player; + +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SpringLayout; + +import edu.regis.universe_player.data.Album; +import edu.regis.universe_player.data.SimpleSongProvider; +import edu.regis.universe_player.data.Song; +import edu.regis.universe_player.data.SongProvider; + +/** + * This panel will list all the songs that are to be currently displayed. + */ +public class SongList extends JPanel +{ + private Map> currentAlbums; + private Map labelMap = new HashMap<>(); + private Map artMap = new HashMap<>(); + + public SongList() + { + super(); + + GridBagLayout layout = new GridBagLayout(); + this.setLayout(layout); + + SongProvider provider = SongProvider.INSTANCE; + this.listAlbums(provider.getSongs()); + } + + /** + * Updates the songs currently listed, sorted by album. + * + * @param songs - The songs to display. + */ + public void listAlbums(Collection songs) + { + Map> albums = songs.stream().sorted().collect(Collectors + .groupingBy(song -> song.album, Collectors + .mapping(song -> song, Collectors.toList()))); + GridBagConstraints c = new GridBagConstraints(), c2 = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.insets = new Insets(0, 0, 20, 0); + int i = 0, j; + AlbumInfo albumInfo; + List songCollection; + JPanel songList; + JLabel songNum, songTitle; + + this.labelMap.clear(); + this.artMap.clear(); + this.removeAll(); + this.currentAlbums = albums; + + for (Album album : albums.keySet()) + { + songCollection = albums.get(album); + + albumInfo = new AlbumInfo(album); + c.gridx = 0; + c.gridy = i; + c.anchor = GridBagConstraints.WEST; + this.add(albumInfo, c); + this.artMap.put(albumInfo, album); + + songList = new JPanel(new GridBagLayout()); + j = 0; + for (Song song : songCollection) + { + songNum = new JLabel(String.valueOf(song.trackNum)); + c2.gridx = 0; + c2.gridy = j; + c2.anchor = GridBagConstraints.EAST; + c2.insets = new Insets(0, 0, 0, 0); + songList.add(songNum, c2); + this.labelMap.put(songNum, song); + + songTitle = new JLabel(song.title); + c2.gridx = 1; + c2.gridy = j; + c2.anchor = GridBagConstraints.WEST; + c2.insets = new Insets(0, 10, 0, 0); + songList.add(songTitle, c2); + this.labelMap.put(songTitle, song); + // TODO - Add song length or something + + j++; + } + c.gridx = 1; + c.anchor = GridBagConstraints.WEST; + this.add(songList, c); +// this.add(new JLabel(new ImageIcon(this.getClass().getResource("/gui/icons/defaultart.png"), "Default")), c); + + i++; + } + } +} diff --git a/interface/src/main/resources/gui/icons/defaultart.png b/interface/src/main/resources/gui/icons/defaultart.png new file mode 100755 index 0000000..a6a4583 Binary files /dev/null and b/interface/src/main/resources/gui/icons/defaultart.png differ