From b1e4100d63a9a510036a047d13815ddd2496af63 Mon Sep 17 00:00:00 2001 From: mdb Date: Fri, 13 Jul 2001 00:11:05 +0000 Subject: [PATCH] More and better playlist management. git-svn-id: https://samskivert.googlecode.com/svn/trunk@177 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../src/java/robodj/chooser/ChooserFrame.java | 14 +- .../java/robodj/chooser/PlaylistPanel.java | 213 +++++++++++++++++- 2 files changed, 212 insertions(+), 15 deletions(-) diff --git a/projects/robodj/src/java/robodj/chooser/ChooserFrame.java b/projects/robodj/src/java/robodj/chooser/ChooserFrame.java index dd137f10..2bc23d68 100644 --- a/projects/robodj/src/java/robodj/chooser/ChooserFrame.java +++ b/projects/robodj/src/java/robodj/chooser/ChooserFrame.java @@ -1,5 +1,5 @@ // -// $Id: ChooserFrame.java,v 1.4 2001/07/12 23:06:55 mdb Exp $ +// $Id: ChooserFrame.java,v 1.5 2001/07/13 00:11:05 mdb Exp $ package robodj.chooser; @@ -33,13 +33,13 @@ public class ChooserFrame // the top of the UI is the browser and the playlist manager JTabbedPane tpane = new JTabbedPane(); - BrowsePanel bpanel = new BrowsePanel(); - String tip = "Browse and select tunes to play."; - tpane.addTab("Browse", null, bpanel, tip); - PlaylistPanel ppanel = new PlaylistPanel(); - tip = "View and manipulate the playlist."; + String tip = "View and manipulate the playlist."; tpane.addTab("Playlist", null, ppanel, tip); + + BrowsePanel bpanel = new BrowsePanel(); + tip = "Browse and select tunes to play."; + tpane.addTab("Browse", null, bpanel, tip); top.add(tpane); // the bottom is the control bar @@ -50,8 +50,6 @@ public class ChooserFrame // add some fake control buttons for now cbar.add(_pause = createControlButton("Pause", "pause")); cbar.add(createControlButton("Stop", "stop")); - cbar.add(createControlButton("Skip", "skip")); - cbar.add(createControlButton("Clear", "clear")); cbar.add(createControlButton("Exit", "exit")); // stick it into the frame diff --git a/projects/robodj/src/java/robodj/chooser/PlaylistPanel.java b/projects/robodj/src/java/robodj/chooser/PlaylistPanel.java index a1e3d651..896516f6 100644 --- a/projects/robodj/src/java/robodj/chooser/PlaylistPanel.java +++ b/projects/robodj/src/java/robodj/chooser/PlaylistPanel.java @@ -1,17 +1,26 @@ // -// $Id: PlaylistPanel.java,v 1.1 2001/07/12 23:06:55 mdb Exp $ +// $Id: PlaylistPanel.java,v 1.2 2001/07/13 00:11:05 mdb Exp $ package robodj.chooser; +import java.awt.Color; +import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.sql.SQLException; +import java.util.ArrayList; import javax.swing.*; import com.samskivert.swing.*; +import com.samskivert.swing.util.*; +import com.samskivert.util.StringUtil; + +import robodj.Log; +import robodj.repository.*; public class PlaylistPanel extends JPanel - implements ActionListener + implements TaskObserver, ActionListener { public PlaylistPanel () { @@ -31,11 +40,29 @@ public class PlaylistPanel JScrollPane bscroll = new JScrollPane(_bpanel); add(bscroll); - // add our navigation button - _clearbut = new JButton("Clear"); - _clearbut.setActionCommand("clear"); - _clearbut.addActionListener(this); - add(_clearbut, GroupLayout.FIXED); + GroupLayout bgl = new HGroupLayout(GroupLayout.NONE); + bgl.setJustification(GroupLayout.RIGHT); + JPanel cbar = new JPanel(bgl); + + // add our control buttons + cbar.add(_clearbut = createControlButton("Clear", "clear")); + cbar.add(createControlButton("Skip", "skip")); + cbar.add(createControlButton("Refresh", "refresh")); + add(cbar, GroupLayout.FIXED); + + // use a special font for our name buttons + _nameFont = new Font("Helvetica", Font.PLAIN, 10); + + // load up the playlist + refreshPlaylist(); + } + + protected JButton createControlButton (String label, String action) + { + JButton cbut = new JButton(label); + cbut.setActionCommand(action); + cbut.addActionListener(this); + return cbut; } public void actionPerformed (ActionEvent e) @@ -45,9 +72,181 @@ public class PlaylistPanel } else if (cmd.equals("clear")) { Chooser.scontrol.clear(); + + } else if (cmd.equals("skip")) { + Chooser.scontrol.skip(); + + } else if (cmd.equals("refresh")) { + refreshPlaylist(); + + } else if (cmd.equals("skipto")) { + JButton src = (JButton)e.getSource(); + PlaylistEntry entry = + (PlaylistEntry)src.getClientProperty("entry"); + Chooser.scontrol.skipto(entry.song.songid); + refreshPlaylist(); + + } else if (cmd.equals("remove")) { + JButton src = (JButton)e.getSource(); + PlaylistEntry entry = + (PlaylistEntry)src.getClientProperty("entry"); + Chooser.scontrol.remove(entry.song.songid); + refreshPlaylist(); + } + } + + protected void refreshPlaylist () + { + // stick a "loading" label in the list to let the user know + // what's up + _bpanel.removeAll(); + _bpanel.add(new JLabel("Loading...")); + + // start up the task that reads the CD info from the database + TaskMaster.invokeMethodTask("readPlaylist", this, this); + } + + public void readPlaylist () + throws SQLException + { + // clear out any previous playlist + _plist.clear(); + + // find out what's currently playing + String playing = Chooser.scontrol.getPlaying(); + playing = StringUtil.split(playing, ":")[1].trim(); + _playid = -1; + if (!playing.equals("")) { + try { + _playid = Integer.parseInt(playing); + } catch (NumberFormatException nfe) { + Log.warning("Unable to parse currently playing id '" + + playing + "'."); + } + } + + // get the playlist from the music daemon + String[] plist = Chooser.scontrol.getPlaylist(); + + // parse it into playlist entries + for (int i = 0; i < plist.length; i++) { + String[] toks = StringUtil.split(plist[i], "\t"); + int eid, sid; + try { + eid = Integer.parseInt(toks[0]); + sid = Integer.parseInt(toks[1]); + } catch (NumberFormatException nfe) { + Log.warning("Bogus playlist record: '" + plist[i] + "'."); + continue; + } + Entry entry = Chooser.model.getEntry(eid); + Song song = entry.getSong(sid); + _plist.add(new PlaylistEntry(entry, song)); + } + } + + public void taskCompleted (String name, Object result) + { + if (name.equals("readPlaylist")) { + populatePlaylist(); + } + } + + public void taskFailed (String name, Throwable exception) + { + String msg; + if (Exception.class.equals(exception.getClass())) { + msg = exception.getMessage(); + } else { + msg = exception.toString(); + } + JOptionPane.showMessageDialog(this, msg, "Error", + JOptionPane.ERROR_MESSAGE); + Log.logStackTrace(exception); + } + + protected void populatePlaylist () + { + // clear out any existing children + _bpanel.removeAll(); + + // adjust our layout policy + GroupLayout gl = (GroupLayout)_bpanel.getLayout(); + gl.setOffAxisPolicy(GroupLayout.EQUALIZE); + gl.setOffAxisJustification(GroupLayout.LEFT); + + // add buttons for every entry + String title = null; + for (int i = 0; i < _plist.size(); i++) { + PlaylistEntry entry = (PlaylistEntry)_plist.get(i); + + // add record/artist indicators when the record and artist + // changes + if (!entry.entry.title.equals(title)) { + title = entry.entry.title; + JLabel label = new JLabel(entry.entry.title + " - " + + entry.entry.artist); + _bpanel.add(label); + } + + // create a browse and a play button + JPanel hpanel = new JPanel(); + gl = new HGroupLayout(GroupLayout.NONE); + gl.setOffAxisPolicy(GroupLayout.STRETCH); + gl.setJustification(GroupLayout.LEFT); + hpanel.setLayout(gl); + + entry.label = new JLabel(entry.song.title); + if (entry.song.songid == _playid) { + entry.label.setForeground(Color.red); + } + entry.label.setFont(_nameFont); + hpanel.add(entry.label); + + JButton button; + button = new JButton("Skip to"); + button.setFont(_nameFont); + button.setActionCommand("skipto"); + button.addActionListener(this); + button.putClientProperty("entry", entry); + hpanel.add(button); + + button = new JButton("Remove"); + button.setActionCommand("remove"); + button.setFont(_nameFont); + button.addActionListener(this); + button.putClientProperty("entry", entry); + hpanel.add(button); + + _bpanel.add(hpanel); + } + + // if there were no entries, stick a label in to that effect + if (_plist.size() == 0) { + _bpanel.add(new JLabel("Nothing playing.")); + } + } + + protected static class PlaylistEntry + { + public Entry entry; + + public Song song; + + public JLabel label; + + public PlaylistEntry (Entry entry, Song song) + { + this.entry = entry; + this.song = song; } } protected JPanel _bpanel; protected JButton _clearbut; + + protected ArrayList _plist = new ArrayList(); + protected int _playid; + + protected Font _nameFont; }