Created new UI element that allows for multiple playlists in a tabbed format.

This commit is contained in:
neviyn 2016-08-27 19:39:31 +01:00
parent 13e0b4d544
commit 337ed9c076
3 changed files with 232 additions and 3 deletions

View File

@ -12,7 +12,7 @@ import musicplayer.player.GStreamerPlayer;
import musicplayer.player.IPlayer; import musicplayer.player.IPlayer;
import musicplayer.player.VLCPlayer; import musicplayer.player.VLCPlayer;
import musicplayer.playlist.IPlaylist; import musicplayer.playlist.IPlaylist;
import musicplayer.playlist.JTablePlaylist; import musicplayer.playlist.TabbedJTablePlaylist;
import musicplayer.swingui.PlayerGUI; import musicplayer.swingui.PlayerGUI;
import musicplayer.util.ConfigManager; import musicplayer.util.ConfigManager;
@ -24,7 +24,7 @@ class SwingUIModule extends AbstractModule {
@Override @Override
protected void configure() { protected void configure() {
bind(IDatabase.class).to(HibernateDatabase.class).in(Singleton.class); bind(IDatabase.class).to(HibernateDatabase.class).in(Singleton.class);
bind(IPlaylist.class).to(JTablePlaylist.class).in(Singleton.class); bind(IPlaylist.class).to(TabbedJTablePlaylist.class).in(Singleton.class);
bind(ILibrary.class).to(JTreeLibrary.class).in(Singleton.class); bind(ILibrary.class).to(JTreeLibrary.class).in(Singleton.class);
bind(PlayerCallbackInterface.class).to(PlayerGUI.class); bind(PlayerCallbackInterface.class).to(PlayerGUI.class);
} }

View File

@ -0,0 +1,229 @@
package musicplayer.playlist;
import musicplayer.model.Song;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* UI element containing tabbed instances of JTablePlaylist.
*/
public class TabbedJTablePlaylist extends JTabbedPane implements IPlaylist {
private List<JTablePlaylist> playlists = new ArrayList<>();
/**
* UI element containing tabbed instances of JTablePlaylist.
*/
public TabbedJTablePlaylist(){
JPanel newTabCreationComponent = new JPanel(new BorderLayout());
newTabCreationComponent.setOpaque(false);
JButton addButton = new JButton("+");
addButton.setBorderPainted(false);
addButton.setFocusPainted(false);
addButton.setContentAreaFilled(false);
newTabCreationComponent.add(addButton);
addTab("+", null);
setTabComponentAt(0, newTabCreationComponent);
addButton.addActionListener(e -> addPlaylistTab());
addPlaylistTab();
}
/**
* @return The playlist in the currently active tab.
*/
private Optional<JTablePlaylist> getActivePlaylist(){
//Pane components should only be JTablePlaylist or null
//noinspection SuspiciousMethodCalls
int playlistIndex = playlists.indexOf(getSelectedComponent());
if(playlistIndex != -1){
return Optional.of(playlists.get(playlistIndex));
}
return Optional.empty();
}
/**
* Create a new JTablePlaylist in a new tab.
*/
private void addPlaylistTab(){
JTablePlaylist playlist = new JTablePlaylist();
playlists.add(playlist);
int newIndex = getTabCount() - 1;
insertTab("", null, playlist, null, newIndex);
setTabComponentAt(newIndex, new PlaylistTabComponent(this, "Playlist"));
setSelectedIndex(newIndex);
}
/**
* Remove a playlist tab.
* @param i Index of tab to remove.
*/
public void removePlaylistTab(int i){
if(i != -1 && getComponentAt(i) != null) {
JTablePlaylist tabbedPane = (JTablePlaylist) getComponentAt(i);
playlists.remove(tabbedPane);
remove(i);
}
if(playlists.isEmpty()){
addPlaylistTab();
}
}
/**
* Add a song to the currently active playlist.
* @param song Song to add.
*/
@Override
public void addSong(Song song) {
getActivePlaylist().ifPresent(x -> x.addSong(song));
}
/**
* @return The first song in the currently active playlist.
*/
@Override
public Optional<Song> getFirst() {
return getActivePlaylist().flatMap(JTablePlaylist::getFirst);
}
/**
* Get the next song in the playlist, relative to a given song.
* @param currentSong The song in the playlist to get the "next" song from.
* @return Next song.
*/
@Override
public Optional<Song> getNext(Song currentSong) {
return getActivePlaylist().flatMap(x -> x.getNext(currentSong));
}
/**
* Get the previous song in the playlist, relative to a given song.
* @param currentSong The song in the playlist to get the "previous" song from.
* @return Previous song.
*/
@Override
public Optional<Song> getPrevious(Song currentSong) {
return getActivePlaylist().flatMap(x -> x.getPrevious(currentSong));
}
/**
* Get a song from a playlist based on index.
* @param index Index of the song to get.
* @return Song at index.
*/
@Override
public Optional<Song> get(int index) {
return getActivePlaylist().flatMap(x -> x.get(index));
}
/**
* @return The currently active (i.e. playing) song in the playlist.
*/
@Override
public Optional<Song> getActive() {
return getActivePlaylist().flatMap(JTablePlaylist::getActive);
}
/**
* @return List of songs in the current playlist.
*/
@Override
public List<Song> getSongList() {
return getActivePlaylist().map(JTablePlaylist::getSongList).orElse(new ArrayList<>());
}
/**
* Get the index of a given song in a playlist.
* @param song Song to get the index of.
* @return Index of song.
*/
@Override
public int getIndex(Song song) {
return getActivePlaylist().map(x -> x.getIndex(song)).orElse(-1);
}
/**
* Delete a song from the active playlist.
* @param song Song to delete.
*/
@Override
public void delete(Song song) {
getActivePlaylist().ifPresent(x -> x.delete(song));
}
/**
* Delete a song from the active playlist.
* @param index Index of song to delete.
*/
@Override
public void delete(int index) {
getActivePlaylist().ifPresent(x -> x.delete(index));
}
/**
* Delete a number of songs from the playlist.
* @param index List of indexes of songs to be removed.
*/
@Override
public void delete(int[] index) {
getActivePlaylist().ifPresent(x -> x.delete(index));
}
/**
* Delete all songs from the active playlist.
*/
@Override
public void deleteAll() {
getActivePlaylist().ifPresent(JTablePlaylist::deleteAll);
}
/**
* @return True if the active playlist is currently empty.
*/
@Override
public boolean isEmpty() {
return getActivePlaylist().map(JTablePlaylist::isEmpty).orElse(true);
}
/**
* Set a song as the currently active song (i.e. currently playing)
* @param song Song currently playing.
*/
@Override
public void setPlayingSong(Song song) {
playlists.parallelStream().forEach(x -> x.setPlayingSong(song));
}
/**
* Set the playlist to show the state when playback has stopped.
*/
@Override
public void setStopped() {
playlists.parallelStream().forEach(JTablePlaylist::setStopped);
}
/**
* Component used in the actual top of the tab to show playlist name and allow closing.
*/
private class PlaylistTabComponent extends JPanel{
private final TabbedJTablePlaylist pane;
public PlaylistTabComponent(final TabbedJTablePlaylist pane, final String tabName){
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.pane = pane;
JLabel tabLabel = new JLabel(tabName);
tabLabel.setOpaque(false);
add(tabLabel);
tabLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
JButton closeButton = new JButton("x");
closeButton.addActionListener(e -> pane.removePlaylistTab(pane.indexOfTabComponent(this)));
closeButton.setFocusPainted(false);
closeButton.setContentAreaFilled(false);
add(closeButton);
}
}
}

View File

@ -123,7 +123,7 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
this.setLayout(new BorderLayout(0, 0)); this.setLayout(new BorderLayout(0, 0));
final JSplitPane libraryAndPlaylistPane = new JSplitPane(); final JSplitPane libraryAndPlaylistPane = new JSplitPane();
libraryAndPlaylistPane.setDividerLocation(240); libraryAndPlaylistPane.setDividerLocation(240);
libraryAndPlaylistPane.setRightComponent((JScrollPane) playlist); libraryAndPlaylistPane.setRightComponent((Component) playlist);
this.add(libraryAndPlaylistPane, BorderLayout.CENTER); this.add(libraryAndPlaylistPane, BorderLayout.CENTER);
libraryAndPlaylistPane.setLeftComponent(((JTreeLibrary)library).getLibraryPanel()); libraryAndPlaylistPane.setLeftComponent(((JTreeLibrary)library).getLibraryPanel());
final JPanel controlPane = new JPanel(); final JPanel controlPane = new JPanel();