Reworked UI to have horizontal scalability between library and playlist.
This commit is contained in:
parent
fe8c1adb39
commit
6ef92096e9
@ -17,6 +17,10 @@ public class Player {
|
|||||||
private Song currentSong;
|
private Song currentSong;
|
||||||
private PlayerCallbackInterface callbackInterface;
|
private PlayerCallbackInterface callbackInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages GStreamer based playback operations.
|
||||||
|
* @param callbackInterface Interface on which UI updates can be called.
|
||||||
|
*/
|
||||||
public Player(PlayerCallbackInterface callbackInterface) {
|
public Player(PlayerCallbackInterface callbackInterface) {
|
||||||
this.callbackInterface = callbackInterface;
|
this.callbackInterface = callbackInterface;
|
||||||
Gst.init();
|
Gst.init();
|
||||||
@ -36,6 +40,10 @@ public class Player {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a source Song file and start playing it via GStreamer.
|
||||||
|
* @param song Song to play.
|
||||||
|
*/
|
||||||
public void playSong(Song song) {
|
public void playSong(Song song) {
|
||||||
callbackInterface.setSongHighlighting(song);
|
callbackInterface.setSongHighlighting(song);
|
||||||
currentSong = song;
|
currentSong = song;
|
||||||
@ -54,6 +62,9 @@ public class Player {
|
|||||||
callbackInterface.setSeekBarDuration((int) playBin.queryDuration().toSeconds());
|
callbackInterface.setSeekBarDuration((int) playBin.queryDuration().toSeconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop any music currently playing.
|
||||||
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (this.thread != null) {
|
if (this.thread != null) {
|
||||||
playBin.stop();
|
playBin.stop();
|
||||||
@ -62,18 +73,30 @@ public class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume playing a paused song.
|
||||||
|
*/
|
||||||
public void resume() {
|
public void resume() {
|
||||||
playBin.play();
|
playBin.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause the currently playing song.
|
||||||
|
*/
|
||||||
public void pause() {
|
public void pause() {
|
||||||
playBin.pause();
|
playBin.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Song currently being played or ready to be played.
|
||||||
|
*/
|
||||||
public Song getCurrentSong(){
|
public Song getCurrentSong(){
|
||||||
return currentSong;
|
return currentSong;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Current playback position in seconds.
|
||||||
|
*/
|
||||||
public int currentSongPosition(){
|
public int currentSongPosition(){
|
||||||
return playBin.isPlaying() ? (int) (playBin.getClock().getTime().toSeconds() - playBin.getBaseTime().toSeconds()) : 0;
|
return playBin.isPlaying() ? (int) (playBin.getClock().getTime().toSeconds() - playBin.getBaseTime().toSeconds()) : 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="musicplayer.PlayerGUI">
|
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="musicplayer.PlayerGUI">
|
||||||
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<xy x="20" y="20" width="500" height="400"/>
|
<xy x="20" y="20" width="500" height="400"/>
|
||||||
@ -8,37 +8,63 @@
|
|||||||
<properties/>
|
<properties/>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<scrollpane id="2b209">
|
<splitpane id="79ccb">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<preferred-size width="760" height="500"/>
|
||||||
|
</grid>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties>
|
||||||
|
<dividerLocation value="350"/>
|
||||||
|
</properties>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<component id="6b9fd" class="javax.swing.JTree" binding="libraryView">
|
<scrollpane id="2b209">
|
||||||
<constraints/>
|
<constraints>
|
||||||
|
<splitpane position="left"/>
|
||||||
|
</constraints>
|
||||||
<properties/>
|
<properties/>
|
||||||
</component>
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="6b9fd" class="javax.swing.JTree" binding="libraryView">
|
||||||
|
<constraints/>
|
||||||
|
<properties/>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</scrollpane>
|
||||||
|
<scrollpane id="359a1">
|
||||||
|
<constraints>
|
||||||
|
<splitpane position="right"/>
|
||||||
|
</constraints>
|
||||||
|
<properties/>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="c10f" class="javax.swing.JTable" binding="playList">
|
||||||
|
<constraints/>
|
||||||
|
<properties>
|
||||||
|
<rowSelectionAllowed value="true"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</scrollpane>
|
||||||
</children>
|
</children>
|
||||||
</scrollpane>
|
</splitpane>
|
||||||
<scrollpane id="359a1">
|
<component id="98c55" class="javax.swing.JSlider" binding="seekBar">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties>
|
||||||
<border type="none"/>
|
<inverted value="false"/>
|
||||||
<children>
|
<minorTickSpacing value="1"/>
|
||||||
<component id="c10f" class="javax.swing.JTable" binding="playList">
|
<paintTicks value="false"/>
|
||||||
<constraints/>
|
<snapToTicks value="false"/>
|
||||||
<properties>
|
<value value="0"/>
|
||||||
<rowSelectionAllowed value="true"/>
|
<valueIsAdjusting value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
</children>
|
|
||||||
</scrollpane>
|
|
||||||
<toolbar id="56df">
|
<toolbar id="56df">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||||
<preferred-size width="-1" height="20"/>
|
<preferred-size width="-1" height="20"/>
|
||||||
</grid>
|
</grid>
|
||||||
</constraints>
|
</constraints>
|
||||||
@ -67,19 +93,6 @@
|
|||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
<component id="98c55" class="javax.swing.JSlider" binding="seekBar">
|
|
||||||
<constraints>
|
|
||||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<inverted value="false"/>
|
|
||||||
<minorTickSpacing value="1"/>
|
|
||||||
<paintTicks value="false"/>
|
|
||||||
<snapToTicks value="false"/>
|
|
||||||
<value value="0"/>
|
|
||||||
<valueIsAdjusting value="false"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
</form>
|
</form>
|
||||||
|
@ -66,10 +66,17 @@ public class PlayerGUI implements PlayerCallbackInterface{
|
|||||||
seekBarUpdater.start();
|
seekBarUpdater.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of seekBar.
|
||||||
|
* @param position New seekBar value.
|
||||||
|
*/
|
||||||
public void setSeekBarPosition(int position){
|
public void setSeekBarPosition(int position){
|
||||||
SwingUtilities.invokeLater(() -> seekBar.setValue(position));
|
SwingUtilities.invokeLater(() -> seekBar.setValue(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the libraryView to contain nothing.
|
||||||
|
*/
|
||||||
private void resetTree() {
|
private void resetTree() {
|
||||||
libraryView.removeAll();
|
libraryView.removeAll();
|
||||||
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||||
@ -77,6 +84,10 @@ public class PlayerGUI implements PlayerCallbackInterface{
|
|||||||
libraryView.setModel(treeModel);
|
libraryView.setModel(treeModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the library with songs grouped by album.
|
||||||
|
* @param libraryData Map of albums with a lists of associated songs.
|
||||||
|
*/
|
||||||
private void populateLibrary(Map<Album, List<Song>> libraryData) {
|
private void populateLibrary(Map<Album, List<Song>> libraryData) {
|
||||||
resetTree();
|
resetTree();
|
||||||
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) libraryView.getModel().getRoot();
|
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) libraryView.getModel().getRoot();
|
||||||
@ -87,6 +98,10 @@ public class PlayerGUI implements PlayerCallbackInterface{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the library with all songs.
|
||||||
|
* @param libraryData List of songs.
|
||||||
|
*/
|
||||||
private void populateLibrary(List<Song> libraryData) {
|
private void populateLibrary(List<Song> libraryData) {
|
||||||
resetTree();
|
resetTree();
|
||||||
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) libraryView.getModel().getRoot();
|
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) libraryView.getModel().getRoot();
|
||||||
@ -94,6 +109,11 @@ public class PlayerGUI implements PlayerCallbackInterface{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an item to libraryView.
|
||||||
|
* @param parentNode Node that should be the parent of this node.
|
||||||
|
* @param node This node.
|
||||||
|
*/
|
||||||
private void addNodeToTreeModel(DefaultMutableTreeNode parentNode, DefaultMutableTreeNode node) {
|
private void addNodeToTreeModel(DefaultMutableTreeNode parentNode, DefaultMutableTreeNode node) {
|
||||||
DefaultTreeModel libraryModel = (DefaultTreeModel) libraryView.getModel();
|
DefaultTreeModel libraryModel = (DefaultTreeModel) libraryView.getModel();
|
||||||
libraryModel.insertNodeInto(node, parentNode, parentNode.getChildCount());
|
libraryModel.insertNodeInto(node, parentNode, parentNode.getChildCount());
|
||||||
@ -102,27 +122,47 @@ public class PlayerGUI implements PlayerCallbackInterface{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a song to the current playlist.
|
||||||
|
* @param song Song to be added to the playlist.
|
||||||
|
*/
|
||||||
private void addToPlaylist(Song song){
|
private void addToPlaylist(Song song){
|
||||||
playlistTableModel.addSong(song);
|
playlistTableModel.addSong(song);
|
||||||
playList.revalidate();
|
playList.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next song in the playlist.
|
||||||
|
* @param currentSong The song that is currently selected.
|
||||||
|
* @return The next song to be selected.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Song getNextSong(Song currentSong) {
|
public Song getNextSong(Song currentSong) {
|
||||||
return playlistTableModel.nextSong(currentSong);
|
return playlistTableModel.nextSong(currentSong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the highlighted song in the playlist to this song.
|
||||||
|
* @param playingSong Song to be highlighted in the playlist.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setSongHighlighting(Song playingSong) {
|
public void setSongHighlighting(Song playingSong) {
|
||||||
int index = playlistTableModel.getSongIndex(playingSong);
|
int index = playlistTableModel.getSongIndex(playingSong);
|
||||||
playList.setRowSelectionInterval(index, index);
|
playList.setRowSelectionInterval(index, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next song in the playlist and dispatch it to the Player to be played.
|
||||||
|
*/
|
||||||
public void playNextSong(){
|
public void playNextSong(){
|
||||||
SwingUtilities.invokeLater(() -> seekBar.setValue(0));
|
SwingUtilities.invokeLater(() -> seekBar.setValue(0));
|
||||||
player.playSong(getNextSong(player.getCurrentSong()));
|
player.playSong(getNextSong(player.getCurrentSong()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum value of the seekBar.
|
||||||
|
* @param seconds New length of seekBar.
|
||||||
|
*/
|
||||||
public void setSeekBarDuration(int seconds){
|
public void setSeekBarDuration(int seconds){
|
||||||
SwingUtilities.invokeLater(() -> seekBar.setMaximum(seconds));
|
SwingUtilities.invokeLater(() -> seekBar.setMaximum(seconds));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user