Created simple prototype music chooser (playlist manager).
git-svn-id: https://samskivert.googlecode.com/svn/trunk@143 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// $Id: Chooser.java,v 1.1 2001/06/05 16:42:38 mdb Exp $
|
||||||
|
|
||||||
|
package robodj.chooser;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.samskivert.util.PropertiesUtil;
|
||||||
|
|
||||||
|
import robodj.Log;
|
||||||
|
import robodj.repository.Repository;
|
||||||
|
import robodj.util.ServerControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The chooser is the GUI-based application for browsing the music
|
||||||
|
* collection and managing the playlist.
|
||||||
|
*/
|
||||||
|
public class Chooser
|
||||||
|
{
|
||||||
|
public static Properties config;
|
||||||
|
|
||||||
|
public static Repository repository;
|
||||||
|
|
||||||
|
public static ServerControl scontrol;
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
// set up our configuration by hand for now
|
||||||
|
config = new Properties();
|
||||||
|
config.setProperty("repository.db.driver", "org.gjt.mm.mysql.Driver");
|
||||||
|
config.setProperty("repository.db.username", "www");
|
||||||
|
config.setProperty("repository.db.password", "Il0ve2PL@Y");
|
||||||
|
config.setProperty("repository.db.url",
|
||||||
|
"jdbc:mysql://depravity:3306/robodj");
|
||||||
|
config.setProperty("repository.basedir", "/export/robodj/repository");
|
||||||
|
|
||||||
|
// create an interface to the database repository
|
||||||
|
try {
|
||||||
|
Properties dbprops =
|
||||||
|
PropertiesUtil.getSubProperties(config, "repository.db");
|
||||||
|
repository = new Repository(dbprops);
|
||||||
|
} catch (SQLException sqe) {
|
||||||
|
Log.warning("Unable to establish communication with music " +
|
||||||
|
"database: " + sqe);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// establish a connection with the music server
|
||||||
|
scontrol = new ServerControl("depravity", 2500);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Log.warning("Unable to establish communication with music " +
|
||||||
|
"server: " + ioe);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create our primary user interface frame, center the frame in
|
||||||
|
// the screen and show it
|
||||||
|
ChooserFrame frame = new ChooserFrame();
|
||||||
|
Toolkit tk = frame.getToolkit();
|
||||||
|
Dimension ss = tk.getScreenSize();
|
||||||
|
int width = 550, height = 500;
|
||||||
|
frame.setBounds((ss.width-width)/2, (ss.height-height)/2,
|
||||||
|
width, height);
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
//
|
||||||
|
// $Id: ChooserFrame.java,v 1.1 2001/06/05 16:42:38 mdb Exp $
|
||||||
|
|
||||||
|
package robodj.chooser;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import com.samskivert.swing.*;
|
||||||
|
|
||||||
|
public class ChooserFrame
|
||||||
|
extends JFrame
|
||||||
|
implements ActionListener
|
||||||
|
{
|
||||||
|
public ChooserFrame ()
|
||||||
|
{
|
||||||
|
super("RoboDJ Chooser");
|
||||||
|
|
||||||
|
// we create a top-level panel to manage everything
|
||||||
|
JPanel top = new JPanel();
|
||||||
|
GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||||
|
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||||
|
top.setLayout(gl);
|
||||||
|
|
||||||
|
// give ourselves a wee bit of a border
|
||||||
|
top.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
|
|
||||||
|
// the top of the UI is the playlist manager section
|
||||||
|
JTabbedPane tpane = new JTabbedPane();
|
||||||
|
Component elist = new EntryList();
|
||||||
|
tpane.addTab("Browse", null, elist, "Browse music database.");
|
||||||
|
tpane.setSelectedIndex(0);
|
||||||
|
top.add(tpane);
|
||||||
|
|
||||||
|
// the bottom is the control bar
|
||||||
|
GroupLayout bgl = new HGroupLayout(GroupLayout.NONE);
|
||||||
|
bgl.setJustification(GroupLayout.RIGHT);
|
||||||
|
JPanel cbar = new JPanel(bgl);
|
||||||
|
|
||||||
|
// add some fake control buttons for now
|
||||||
|
cbar.add(createControlButton("Play", "play"));
|
||||||
|
cbar.add(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
|
||||||
|
top.add(cbar, GroupLayout.FIXED);
|
||||||
|
|
||||||
|
// now add our top-level panel (we'd not use this if we could set
|
||||||
|
// a border on the content pane returned by the frame... alas)
|
||||||
|
getContentPane().add(top, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("exit")) {
|
||||||
|
System.exit(0);
|
||||||
|
|
||||||
|
} else if (cmd.equals("pause")) {
|
||||||
|
Chooser.scontrol.pause();
|
||||||
|
|
||||||
|
} else if (cmd.equals("play")) {
|
||||||
|
Chooser.scontrol.play();
|
||||||
|
|
||||||
|
} else if (cmd.equals("clear")) {
|
||||||
|
Chooser.scontrol.clear();
|
||||||
|
|
||||||
|
} else if (cmd.equals("stop")) {
|
||||||
|
Chooser.scontrol.stop();
|
||||||
|
|
||||||
|
} else if (cmd.equals("skip")) {
|
||||||
|
Chooser.scontrol.skip();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Unknown action event: " + cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Component makeTextPanel (String text)
|
||||||
|
{
|
||||||
|
JPanel panel = new JPanel(false);
|
||||||
|
JLabel filler = new JLabel(text);
|
||||||
|
filler.setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
panel.setLayout(new GridLayout(1, 1));
|
||||||
|
panel.add(filler);
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
//
|
||||||
|
// $Id: EntryList.java,v 1.1 2001/06/05 16:42:38 mdb Exp $
|
||||||
|
|
||||||
|
package robodj.chooser;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import com.samskivert.swing.*;
|
||||||
|
import com.samskivert.swing.util.*;
|
||||||
|
|
||||||
|
import robodj.Log;
|
||||||
|
import robodj.repository.*;
|
||||||
|
|
||||||
|
public class EntryList
|
||||||
|
extends JPanel
|
||||||
|
implements TaskObserver, ActionListener
|
||||||
|
{
|
||||||
|
public EntryList ()
|
||||||
|
{
|
||||||
|
GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||||
|
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||||
|
setLayout(gl);
|
||||||
|
|
||||||
|
// create the pane that will hold the buttons
|
||||||
|
gl = new VGroupLayout(GroupLayout.NONE);
|
||||||
|
gl.setOffAxisPolicy(GroupLayout.EQUALIZE);
|
||||||
|
_bpanel = new JPanel(gl);
|
||||||
|
|
||||||
|
// give ourselves a wee bit of a border
|
||||||
|
_bpanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
|
|
||||||
|
// put it into a scrolling pane
|
||||||
|
JScrollPane bscroll = new JScrollPane(_bpanel);
|
||||||
|
add(bscroll);
|
||||||
|
|
||||||
|
// add our navigation button
|
||||||
|
_upbut = new JButton("Up");
|
||||||
|
_upbut.setActionCommand("up");
|
||||||
|
_upbut.addActionListener(this);
|
||||||
|
add(_upbut, GroupLayout.FIXED);
|
||||||
|
|
||||||
|
// start up the task that reads the CD info from the database
|
||||||
|
TaskMaster.invokeMethodTask("readEntries", this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void taskCompleted (String name, Object result)
|
||||||
|
{
|
||||||
|
if (name.equals("readEntries")) {
|
||||||
|
// the result should be an array of entry objects with which
|
||||||
|
// we can populate our button list
|
||||||
|
_entries = (Entry[])result;
|
||||||
|
populateEntries(_entries);
|
||||||
|
|
||||||
|
} else if (name.equals("readAndPlay")) {
|
||||||
|
for (int i = 0; i < _entry.songs.length; i++) {
|
||||||
|
Chooser.scontrol.append(_entry.songs[i].location);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (name.equals("readSongs")) {
|
||||||
|
populateSong(_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the entries from the database.
|
||||||
|
*/
|
||||||
|
public Entry[] readEntries ()
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
return Chooser.repository.getEntries("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the entries from the database.
|
||||||
|
*/
|
||||||
|
public void readSongs ()
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
Chooser.repository.populateSongs(_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the entries from the database and plays them all.
|
||||||
|
*/
|
||||||
|
public void readAndPlay ()
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
Chooser.repository.populateSongs(_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the proper buttons, etc. for each entry.
|
||||||
|
*/
|
||||||
|
protected void populateEntries (Entry[] entries)
|
||||||
|
{
|
||||||
|
// disable the up button because we're at the top level
|
||||||
|
_upbut.setEnabled(false);
|
||||||
|
|
||||||
|
// clear out any existing children
|
||||||
|
_bpanel.removeAll();
|
||||||
|
|
||||||
|
// sort our entries
|
||||||
|
Comparator ecomp = new Comparator() {
|
||||||
|
public int compare (Object o1, Object o2) {
|
||||||
|
Entry e1 = (Entry)o1, e2 = (Entry)o2;
|
||||||
|
int rv = e1.artist.compareTo(e2.artist);
|
||||||
|
return rv == 0 ? e1.title.compareTo(e2.title) : rv;
|
||||||
|
}
|
||||||
|
public boolean equals (Object o1) {
|
||||||
|
return o1.equals(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Arrays.sort(entries, ecomp);
|
||||||
|
|
||||||
|
// and add buttons for every entry
|
||||||
|
String artist = null;
|
||||||
|
for (int i = 0; i < entries.length; i++) {
|
||||||
|
if (!entries[i].artist.equals(artist)) {
|
||||||
|
artist = entries[i].artist;
|
||||||
|
JLabel label = new JLabel(entries[i].artist);
|
||||||
|
_bpanel.add(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a browse and a play button
|
||||||
|
JPanel hpanel = new JPanel();
|
||||||
|
GroupLayout gl = new HGroupLayout(GroupLayout.NONE);
|
||||||
|
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||||
|
gl.setJustification(GroupLayout.LEFT);
|
||||||
|
hpanel.setLayout(gl);
|
||||||
|
|
||||||
|
JButton button;
|
||||||
|
|
||||||
|
button = new JButton("Play");
|
||||||
|
button.setActionCommand("playall");
|
||||||
|
button.addActionListener(this);
|
||||||
|
button.putClientProperty("entry", entries[i]);
|
||||||
|
hpanel.add(button);
|
||||||
|
|
||||||
|
button = new JButton(entries[i].title);
|
||||||
|
button.setActionCommand("browse");
|
||||||
|
button.addActionListener(this);
|
||||||
|
button.putClientProperty("entry", entries[i]);
|
||||||
|
hpanel.add(button);
|
||||||
|
|
||||||
|
_bpanel.add(hpanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void populateSong (Entry entry)
|
||||||
|
{
|
||||||
|
// enable the up button because we're looking at a song
|
||||||
|
_upbut.setEnabled(true);
|
||||||
|
|
||||||
|
// clear out any existing children
|
||||||
|
_bpanel.removeAll();
|
||||||
|
|
||||||
|
// add a label for the title
|
||||||
|
JLabel label = new JLabel(entry.title);
|
||||||
|
_bpanel.add(label);
|
||||||
|
|
||||||
|
// sort the songs by position
|
||||||
|
Comparator scomp = new Comparator() {
|
||||||
|
public int compare (Object o1, Object o2) {
|
||||||
|
Song s1 = (Song)o1, s2 = (Song)o2;
|
||||||
|
return s1.position - s2.position;
|
||||||
|
}
|
||||||
|
public boolean equals (Object o1) {
|
||||||
|
return o1.equals(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Arrays.sort(entry.songs, scomp);
|
||||||
|
|
||||||
|
// and add buttons for every song
|
||||||
|
for (int i = 0; i < entry.songs.length; i++) {
|
||||||
|
JButton button = new JButton(entry.songs[i].title);
|
||||||
|
button.setActionCommand("play");
|
||||||
|
button.addActionListener(this);
|
||||||
|
button.putClientProperty("song", entry.songs[i]);
|
||||||
|
_bpanel.add(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed (ActionEvent e)
|
||||||
|
{
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("browse")) {
|
||||||
|
JButton src = (JButton)e.getSource();
|
||||||
|
_entry = (Entry)src.getClientProperty("entry");
|
||||||
|
// start up the task that reads this CDs songs from the database
|
||||||
|
TaskMaster.invokeMethodTask("readSongs", this, this);
|
||||||
|
|
||||||
|
} else if (cmd.equals("playall")) {
|
||||||
|
JButton src = (JButton)e.getSource();
|
||||||
|
_entry = (Entry)src.getClientProperty("entry");
|
||||||
|
// start up the task that reads this CDs songs from the database
|
||||||
|
TaskMaster.invokeMethodTask("readAndPlay", this, this);
|
||||||
|
|
||||||
|
} else if (cmd.equals("play")) {
|
||||||
|
JButton src = (JButton)e.getSource();
|
||||||
|
Song song = (Song)src.getClientProperty("song");
|
||||||
|
Chooser.scontrol.append(song.location);
|
||||||
|
|
||||||
|
} else if (cmd.equals("up")) {
|
||||||
|
populateEntries(_entries);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Unknown action event: " + cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JPanel _bpanel;
|
||||||
|
protected JButton _upbut;
|
||||||
|
|
||||||
|
protected Entry[] _entries;
|
||||||
|
protected Entry _entry;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user