diff --git a/projects/robodj/src/java/robodj/chooser/EntryController.java b/projects/robodj/src/java/robodj/chooser/EntryController.java
index 2eeccfbd..c0bc6b08 100644
--- a/projects/robodj/src/java/robodj/chooser/EntryController.java
+++ b/projects/robodj/src/java/robodj/chooser/EntryController.java
@@ -169,6 +169,9 @@ public abstract class EntryController extends ItemController
plist = new PlaylistEntry[0];
}
for (int i = 0; i < songs.length; i++) {
+ if (songs[i].isHated()) {
+ continue;
+ }
PlaylistEntry entry = new PlaylistEntry(
songs[i].entryid, songs[i].songid, songs[i].title);
plist = (PlaylistEntry[])ArrayUtil.append(plist, entry);
diff --git a/projects/robodj/src/java/robodj/chooser/ItemController.java b/projects/robodj/src/java/robodj/chooser/ItemController.java
index 990f4add..21bf7bca 100644
--- a/projects/robodj/src/java/robodj/chooser/ItemController.java
+++ b/projects/robodj/src/java/robodj/chooser/ItemController.java
@@ -32,23 +32,20 @@ public abstract class ItemController extends Controller
public boolean handleAction (ActionEvent e)
{
String cmd = e.getActionCommand();
- if (cmd.equals(SongItem.ADD_VOTE)) {
+ if (cmd.equals(SongItem.TOGGLE_VOTE)) {
JButton button = (JButton)e.getSource();
SongItem item = (SongItem)button.getParent();
_song = item.getSong();
- if (_song.addVote(Chooser.frame.getUser(true))) {
- item.update();
- TaskMaster.invokeMethodTask("updateSong", this, this);
- }
- } else if (cmd.equals(SongItem.CLEAR_VOTE)) {
- JButton button = (JButton)e.getSource();
- SongItem item = (SongItem)button.getParent();
- _song = item.getSong();
- if (_song.clearVote(Chooser.frame.getUser(true))) {
- item.update();
- TaskMaster.invokeMethodTask("updateSong", this, this);
+ String who = Chooser.frame.getUser(true);
+ switch (_song.hasVoted(who)) {
+ case -1: _song.addVote(who, true); break;
+ case 1: _song.clearVote(who); break;
+ default:
+ case 0: _song.addVote(who, false); break;
}
+ item.update();
+ TaskMaster.invokeMethodTask("updateSong", this, this);
} else {
Log.warning("Unknown action event: " + cmd);
diff --git a/projects/robodj/src/java/robodj/chooser/SongItem.java b/projects/robodj/src/java/robodj/chooser/SongItem.java
index f3d2f619..4e91fc56 100644
--- a/projects/robodj/src/java/robodj/chooser/SongItem.java
+++ b/projects/robodj/src/java/robodj/chooser/SongItem.java
@@ -33,8 +33,7 @@ public class SongItem extends Item
public static final String PLAY = "song:play";
// ubiquitous actions
- public static final String ADD_VOTE = "song:add_vote";
- public static final String CLEAR_VOTE = "song:clear_vote";
+ public static final String TOGGLE_VOTE = "song:toggle_vote";
/** Used depending on where this song is being displayed. */
public Object extra;
@@ -85,7 +84,7 @@ public class SongItem extends Item
// add a vote button
_voteButton = ButtonUtil.createControlButton(
- ADD_VOTE_TIP, ADD_VOTE, _addVoteIcon, true);
+ TOGGLE_VOTE_TIP, TOGGLE_VOTE, _noVoteIcon, true);
_voteButton.putClientProperty(SONG_PROP, song);
add(_voteButton, HGroupLayout.FIXED);
@@ -106,22 +105,22 @@ public class SongItem extends Item
{
if (!StringUtil.blank(_song.votes)) {
_trackLabel.setFont(_hasVotesFont);
- _trackLabel.setToolTipText("" + _song.title +
- "
Votes: " + _song.votes);
+ _trackLabel.setToolTipText(
+ "
| " + _song.title + " |
" +
+ "| Votes: " + _song.votes + " |
" +
+ "
");
} else {
_trackLabel.setFont(_nameFont);
_trackLabel.setToolTipText(_song.title);
}
- if (_song.hasVoted(Chooser.frame.getUser(false))) {
- _voteButton.setIcon(_clearVoteIcon);
- _voteButton.setActionCommand(CLEAR_VOTE);
- _voteButton.setToolTipText(CLEAR_VOTE_TIP);
- } else {
- _voteButton.setIcon(_addVoteIcon);
- _voteButton.setActionCommand(ADD_VOTE);
- _voteButton.setToolTipText(ADD_VOTE_TIP);
+ switch (_song.hasVoted(Chooser.frame.getUser(false))) {
+ case -1: _voteButton.setIcon(_nayVoteIcon); break;
+ case 1: _voteButton.setIcon(_yeaVoteIcon); break;
+ default:
+ case 0: _voteButton.setIcon(_noVoteIcon); break;
}
+
repaint();
}
@@ -149,18 +148,18 @@ public class SongItem extends Item
protected static final String PLAY_SONG_TIP =
"Append this song to the playlist";
- protected static final String ADD_VOTE_TIP =
- "Add your vote for this song";
- protected static final String CLEAR_VOTE_TIP =
- "Remove your vote for this song";
+ protected static final String TOGGLE_VOTE_TIP =
+ "Toggle your vote for this song";
protected static ImageIcon _skipToIcon =
ButtonUtil.getIcon(ICON_ROOT + "skip.png");
protected static ImageIcon _removeIcon =
ButtonUtil.getIcon(ICON_ROOT + "remove_song.png");
- protected static ImageIcon _addVoteIcon =
- ButtonUtil.getIcon(ICON_ROOT + "add_vote.png");
- protected static ImageIcon _clearVoteIcon =
- ButtonUtil.getIcon(ICON_ROOT + "clear_vote.png");
+ protected static ImageIcon _yeaVoteIcon =
+ ButtonUtil.getIcon(ICON_ROOT + "yea_vote.png");
+ protected static ImageIcon _nayVoteIcon =
+ ButtonUtil.getIcon(ICON_ROOT + "nay_vote.png");
+ protected static ImageIcon _noVoteIcon =
+ ButtonUtil.getIcon(ICON_ROOT + "no_vote.png");
}
diff --git a/projects/robodj/src/java/robodj/chooser/images/add_vote.png b/projects/robodj/src/java/robodj/chooser/images/add_vote.png
deleted file mode 100644
index 1f6d2b50..00000000
Binary files a/projects/robodj/src/java/robodj/chooser/images/add_vote.png and /dev/null differ
diff --git a/projects/robodj/src/java/robodj/chooser/images/clear_vote.png b/projects/robodj/src/java/robodj/chooser/images/clear_vote.png
deleted file mode 100644
index 6888f317..00000000
Binary files a/projects/robodj/src/java/robodj/chooser/images/clear_vote.png and /dev/null differ
diff --git a/projects/robodj/src/java/robodj/chooser/images/nay_vote.png b/projects/robodj/src/java/robodj/chooser/images/nay_vote.png
new file mode 100644
index 00000000..667e10c9
Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/nay_vote.png differ
diff --git a/projects/robodj/src/java/robodj/chooser/images/no_vote.png b/projects/robodj/src/java/robodj/chooser/images/no_vote.png
new file mode 100644
index 00000000..7a046635
Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/no_vote.png differ
diff --git a/projects/robodj/src/java/robodj/chooser/images/yea_vote.png b/projects/robodj/src/java/robodj/chooser/images/yea_vote.png
new file mode 100644
index 00000000..777c38ef
Binary files /dev/null and b/projects/robodj/src/java/robodj/chooser/images/yea_vote.png differ
diff --git a/projects/robodj/src/java/robodj/repository/Song.java b/projects/robodj/src/java/robodj/repository/Song.java
index 62e63884..ed5c99a1 100644
--- a/projects/robodj/src/java/robodj/repository/Song.java
+++ b/projects/robodj/src/java/robodj/repository/Song.java
@@ -49,25 +49,36 @@ public class Song
* Adds a voter to the votes string for this entry, not including a
* voter that already exists in the voter set.
*
+ * @param yea true if this is a positive vote, false if it is a
+ * negative vote.
+ *
* @return true if the voter set was changed as a result of this
* addition, false if not.
*/
- public boolean addVote (String voter)
+ public boolean addVote (String voter, boolean yea)
{
- // handle our first vote separately
- if (StringUtil.blank(votes)) {
- votes = voter;
- _votes = null; // clear our cached votes
- return true;
+ if (voter.indexOf("-") != -1) {
+ throw new IllegalArgumentException("Voter must not contain '-'.");
}
// make sure this voter has not already cast their ballot
- if (hasVoted(voter)) {
- return false;
+ clearVote(voter);
+
+ // mark the vote as nay if appropriate
+ if (!yea) {
+ voter = "-" + voter;
+ }
+
+ // clear our cached votes
+ _votes = null;
+
+ // handle our first vote separately
+ if (StringUtil.blank(votes)) {
+ votes = voter;
+ return true;
}
votes = (votes + "," + voter);
- _votes = null; // clear our cached votes
return true;
}
@@ -79,11 +90,13 @@ public class Song
*/
public boolean clearVote (String voter)
{
+ String nvoter = "-" + voter;
String[] votes = getVotes();
StringBuffer nvotes = new StringBuffer();
boolean saw = false;
for (int ii = 0; ii < votes.length; ii++) {
- if (votes[ii].equalsIgnoreCase(voter)) {
+ if (votes[ii].equalsIgnoreCase(voter) ||
+ votes[ii].equalsIgnoreCase(nvoter)) {
saw = true;
} else {
if (nvotes.length() > 0) {
@@ -116,19 +129,51 @@ public class Song
}
/**
- * Returns true if the specified user has voted.
+ * Returns true if this song has at least one positive vote.
*/
- public boolean hasVoted (String voter)
+ public boolean isLoved ()
{
String[] votes = getVotes();
for (int ii = 0; ii < votes.length; ii++) {
- if (votes[ii].equalsIgnoreCase(voter)) {
+ if (!votes[ii].startsWith("-")) {
return true;
}
}
return false;
}
+ /**
+ * Returns true if this song has at least one negative vote.
+ */
+ public boolean isHated ()
+ {
+ String[] votes = getVotes();
+ for (int ii = 0; ii < votes.length; ii++) {
+ if (votes[ii].startsWith("-")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns +1, -1, or 0 to indicate whether the specified user has
+ * voted positively, negatively or not at all.
+ */
+ public int hasVoted (String voter)
+ {
+ String nvoter = "-" + voter;
+ String[] votes = getVotes();
+ for (int ii = 0; ii < votes.length; ii++) {
+ if (votes[ii].equals(voter)) {
+ return 1;
+ } else if (votes[ii].equals(nvoter)) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
/**
* Returns a string representation of this instance.
*/