/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package moppydesk.ui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.Transmitter;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.TableColumnModel;
import moppydesk.Constants;
import moppydesk.MoppyStatusConsumer;
import moppydesk.MoppyUI;
import moppydesk.inputs.MoppySequencer;
import moppydesk.playlist.MoppyPlaylist;
/**
*
* @author Sam/AJ (MrSolidSnake745)
*
*/
public class PlaylistControls extends InputPanel implements MoppyStatusConsumer {
MoppySequencer seq;
MoppyControlWindow controlWindow;
MoppyUI app;
final JFileChooser sequenceChooser = new JFileChooser();
final FileNameExtensionFilter MIDIFilter = new FileNameExtensionFilter("MIDI Files (*.mid, *.midi)", "mid", "midi");
final FileNameExtensionFilter MPLFilter = new FileNameExtensionFilter("Moppy Playlist Files", "mpl");
Timer progressTimer;
private boolean isConnected = false;
private boolean fileLoaded = false;
private boolean interruptNextSong = false;
MoppyPlaylist playlist = new MoppyPlaylist();
/**
* Creates new form PlaylistControls
*/
public PlaylistControls(MoppyUI app, MoppyControlWindow mcw, MoppySequencer newSequencer) {
this.seq = newSequencer;
this.app = app;
this.controlWindow = mcw;
initComponents();
progressTimer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateProgressDisplay();
}
});
setupPlaylistTable();
sequenceChooser.addChoosableFileFilter(MIDIFilter);
sequenceChooser.addChoosableFileFilter(MPLFilter);
}
@Override
public void savePreferences() {
//Nothing to do here! All prefs are saved upon UI actions currently
}
@Override
public void loadPreferences() {
loadLastListCheckbox.setSelected(app.prefs.getBoolean(Constants.PREF_LOAD_MPL_ON_START, false));
String previouslyLoaded = app.prefs.get(Constants.PREF_LOADED_MPL, null);
if (previouslyLoaded != null && !previouslyLoaded.isEmpty() && loadLastListCheckbox.isSelected()) {
//Try to load the last MPL, if it fails, clear out the preference
if (!loadPlaylist(new File(previouslyLoaded))) { app.prefs.put(Constants.PREF_LOADED_MPL, ""); }
}
}
private void updateProgressDisplay() {
long currentSeconds = seq.getSecondsPosition();
sequenceProgressSlider.setValue((int) (currentSeconds));
String currentPosition = String.format("%d:%02d",
TimeUnit.SECONDS.toMinutes(currentSeconds),
currentSeconds % 60);
String totalPosition = String.format("%d:%02d",
TimeUnit.SECONDS.toMinutes(seq.getSecondsLength()),
seq.getSecondsLength() % 60);
currentPositionLabel.setText(currentPosition);
totalPositionLabel.setText(totalPosition);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
sequenceNameLabel = new javax.swing.JLabel();
bpmLabel = new javax.swing.JLabel();
clearButton = new javax.swing.JButton();
loadButton = new javax.swing.JButton();
sequenceProgressSlider = new javax.swing.JSlider();
currentPositionLabel = new javax.swing.JLabel();
totalPositionLabel = new javax.swing.JLabel();
resetListButton = new javax.swing.JButton();
resetDrivesCheckbox = new javax.swing.JCheckBox();
loadListButton = new javax.swing.JButton();
saveListButton = new javax.swing.JButton();
playlistScrollPane = new javax.swing.JScrollPane();
playlistTable = new javax.swing.JTable();
jPanel1 = new javax.swing.JPanel();
previousButton = new javax.swing.JButton();
startButton = new javax.swing.JButton();
stopButton = new javax.swing.JButton();
nextButton = new javax.swing.JButton();
loadDirectoryButton = new javax.swing.JButton();
randomizeButton = new javax.swing.JButton();
loadLastListCheckbox = new javax.swing.JCheckBox();
setMaximumSize(new java.awt.Dimension(529, 240));
setMinimumSize(new java.awt.Dimension(0, 0));
setName(""); // NOI18N
setOpaque(false);
setPreferredSize(new java.awt.Dimension(524, 240));
setRequestFocusEnabled(false);
sequenceNameLabel.setText("<None loaded>");
bpmLabel.setText("? bpm");
bpmLabel.setAlignmentX(1.0F);
clearButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
clearButton.setText("Clear List");
clearButton.setToolTipText("");
clearButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
clearButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
clearButtonstopResetClicked(evt);
}
});
loadButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
loadButton.setLabel("Load MIDI");
loadButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
loadButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadButtonloadSequence(evt);
}
});
sequenceProgressSlider.setToolTipText("");
sequenceProgressSlider.setValue(0);
sequenceProgressSlider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
sequenceProgressDragged(evt);
}
});
sequenceProgressSlider.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
sequenceProgressDragged(evt);
}
});
currentPositionLabel.setText("00:00");
totalPositionLabel.setText("00:00");
resetListButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
resetListButton.setText("Reset List");
resetListButton.setToolTipText("");
resetListButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
resetListButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
resetListButtonstopResetClicked(evt);
}
});
resetDrivesCheckbox.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
resetDrivesCheckbox.setText("Reset drives");
resetDrivesCheckbox.setToolTipText("If selected, will reset the drives to the intial position between songs");
resetDrivesCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
resetDrivesCheckboxActionPerformed(evt);
}
});
loadListButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
loadListButton.setText("Load List");
loadListButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
loadListButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadListButtonActionPerformed(evt);
}
});
saveListButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
saveListButton.setText("Save List");
saveListButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
saveListButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveListButtonActionPerformed(evt);
}
});
playlistTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
playlistTable.getTableHeader().setReorderingAllowed(false);
playlistScrollPane.setViewportView(playlistTable);
previousButton.setText("◄◄");
previousButton.setToolTipText("Previous");
previousButton.setEnabled(false);
previousButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
previousButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
previousButtonActionPerformed(evt);
}
});
jPanel1.add(previousButton);
startButton.setText(" ► ");
startButton.setToolTipText("Start/Pause");
startButton.setEnabled(false);
startButton.setMargin(new java.awt.Insets(2, 3, 2, 3));
startButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startButtonActionPerformed(evt);
}
});
jPanel1.add(startButton);
stopButton.setText("■");
stopButton.setToolTipText("Stop/Reset - Click while stopped to reset drives");
stopButton.setMargin(new java.awt.Insets(2, 7, 2, 7));
stopButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
stopButtonActionPerformed(evt);
}
});
jPanel1.add(stopButton);
nextButton.setText("►►");
nextButton.setToolTipText("Next");
nextButton.setEnabled(false);
nextButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
nextButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextButtonActionPerformed(evt);
}
});
jPanel1.add(nextButton);
loadDirectoryButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
loadDirectoryButton.setText("Load Directory");
loadDirectoryButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
loadDirectoryButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadDirectoryButtonloadSequence(evt);
}
});
randomizeButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
randomizeButton.setText("Randomize");
randomizeButton.setMargin(new java.awt.Insets(2, 2, 2, 2));
randomizeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
randomizeButtonActionPerformed(evt);
}
});
loadLastListCheckbox.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
loadLastListCheckbox.setText("Load last MPL on startup");
loadLastListCheckbox.setToolTipText("If selected, will load the last successfully loaded MPL file");
loadLastListCheckbox.setActionCommand("Load last MPL on startup");
loadLastListCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadLastListCheckboxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(2, 2, 2)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(currentPositionLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sequenceProgressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(totalPositionLabel))
.addGroup(layout.createSequentialGroup()
.addComponent(loadListButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(saveListButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(randomizeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(loadLastListCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(sequenceNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bpmLabel))
.addGroup(layout.createSequentialGroup()
.addComponent(playlistScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 425, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(2, 2, 2)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(loadButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(resetDrivesCheckbox, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
.addComponent(loadDirectoryButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(resetListButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addGap(2, 2, 2))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(2, 2, 2)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(loadButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(loadDirectoryButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(resetListButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(clearButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(resetDrivesCheckbox))
.addComponent(playlistScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(loadListButton)
.addComponent(saveListButton)
.addComponent(randomizeButton)
.addComponent(loadLastListCheckbox))
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(sequenceNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sequenceProgressSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(bpmLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(currentPositionLabel)
.addComponent(totalPositionLabel))))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void playSequencer() {
if(!(fileLoaded) && !(playlist.isFinished())) {
loadSequenceFile(playlist.getNextSong());
}
seq.startSequencer();
controlWindow.setStatus("Playing!");
startButton.setText("▐ ▌");
}
private void pauseSequencer() {
seq.stopSequencer();
startButton.setText(" ► ");
controlWindow.setStatus("...Paused");
}
private void stopResetSequencer() {
if (seq.isRunning()) {
controlWindow.setStatus("Stopping...");
seq.stopSequencer();
seq.resetSequencer();
startButton.setText(" ► ");
controlWindow.setStatus("Stopped.");
} else {
app.rm.reset();
controlWindow.setStatus("Reset.");
}
}
private void clearButtonstopResetClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonstopResetClicked
clearPlaylist();
}//GEN-LAST:event_clearButtonstopResetClicked
private void loadButtonloadSequence(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonloadSequence
String previouslyLoaded = app.prefs.get(Constants.PREF_LOADED_LIST, null);
if (previouslyLoaded != null) {
sequenceChooser.setCurrentDirectory(new File(previouslyLoaded));
}
sequenceChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
sequenceChooser.setFileFilter(MIDIFilter);
int returnVal = sequenceChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
app.prefs.put(Constants.PREF_LOADED_LIST, sequenceChooser.getSelectedFile().getPath());
playlist.addSong(sequenceChooser.getSelectedFile());
if (isConnected && !(playlist.isFinished())) {
startButton.setEnabled(true);
}
} else {
//Cancelled
}
}//GEN-LAST:event_loadButtonloadSequence
private void sequenceProgressDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sequenceProgressDragged
int seconds = ((JSlider) evt.getSource()).getValue();
seq.setSecondsPosition(seconds);
currentPositionLabel.setText(String.format("%d:%02d",
TimeUnit.SECONDS.toMinutes(seconds),
seconds % 60));
}//GEN-LAST:event_sequenceProgressDragged
private void resetListButtonstopResetClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetListButtonstopResetClicked
resetPlaylist();
}//GEN-LAST:event_resetListButtonstopResetClicked
private void loadListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadListButtonActionPerformed
loadPlaylist(getPlaylistFile(true));
}//GEN-LAST:event_loadListButtonActionPerformed
private void saveListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveListButtonActionPerformed
savePlaylist(getPlaylistFile(false));
}//GEN-LAST:event_saveListButtonActionPerformed
private void resetDrivesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetDrivesCheckboxActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_resetDrivesCheckboxActionPerformed
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed
if (startButton.getText().equals(" ► ")) {
interruptNextSong = false;
playSequencer();
} else {
pauseSequencer();
}
}//GEN-LAST:event_startButtonActionPerformed
private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopButtonActionPerformed
stopResetSequencer();
}//GEN-LAST:event_stopButtonActionPerformed
private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
if(!playlist.isLastSong()) {
try {
loadSequenceFile(playlist.getNextSong());
if(isConnected) {Thread.sleep(1000); playSequencer();}
} catch (InterruptedException ex) {
Logger.getLogger(PlaylistControls.class.getName()).log(Level.SEVERE, null, ex);
controlWindow.setStatus("Error playing next song!");
JOptionPane.showMessageDialog(this.getRootPane(), ex);
}
}
}//GEN-LAST:event_nextButtonActionPerformed
private void previousButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousButtonActionPerformed
if(!playlist.isFirstSong()) {
try {
loadSequenceFile(playlist.getPreviousSong());
if(isConnected) {Thread.sleep(1000); playSequencer();}
} catch (InterruptedException ex) {
Logger.getLogger(PlaylistControls.class.getName()).log(Level.SEVERE, null, ex);
controlWindow.setStatus("Error playing previous song!");
JOptionPane.showMessageDialog(this.getRootPane(), ex);
}
}
}//GEN-LAST:event_previousButtonActionPerformed
private void loadDirectoryButtonloadSequence(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadDirectoryButtonloadSequence
String previouslyLoaded = app.prefs.get(Constants.PREF_LOADED_LIST, null);
if (previouslyLoaded != null) {
sequenceChooser.setCurrentDirectory(new File(previouslyLoaded));
}
sequenceChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
sequenceChooser.setFileFilter(sequenceChooser.getAcceptAllFileFilter());
int returnVal = sequenceChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
app.prefs.put(Constants.PREF_LOADED_LIST, sequenceChooser.getSelectedFile().getPath());
for (File file : sequenceChooser.getSelectedFile().listFiles()) {
String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length());
if("mid".equals(extension) || "midi".equals(extension)) {playlist.addSong(file);}
}
sequenceChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (isConnected && !(playlist.isFinished())) {startButton.setEnabled(true);}
} else {
//Cancelled
}
sequenceChooser.setAcceptAllFileFilterUsed(true);
}//GEN-LAST:event_loadDirectoryButtonloadSequence
private void randomizeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_randomizeButtonActionPerformed
playlist.randomize();
}//GEN-LAST:event_randomizeButtonActionPerformed
private void loadLastListCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadLastListCheckboxActionPerformed
app.prefs.putBoolean(Constants.PREF_LOAD_MPL_ON_START, loadLastListCheckbox.isSelected());
}//GEN-LAST:event_loadLastListCheckboxActionPerformed
@Override
public void tempoChanged(int newTempo) {
bpmLabel.setText(newTempo + " bpm");
}
@Override
public void sequenceEnded() {
try {
playlist.currentSongFinished();
if (!(playlist.isFinished())) {
loadSequenceFile(playlist.getNextSong());
if(resetDrivesCheckbox.isSelected()) {Thread.sleep(500); app.rm.reset(); Thread.sleep(500);}
Thread.sleep(3000);
if(interruptNextSong) {interruptNextSong = false;}
else {playSequencer();}
}
else {
playlistEnded();
}
}
catch (InterruptedException ex) {
Logger.getLogger(MoppyControlWindow.class.getName()).log(Level.SEVERE, null, ex);
controlWindow.setStatus("Error playing next song!");
JOptionPane.showMessageDialog(this.getRootPane(), ex);
}
}
private void loadSequenceFile(File sequenceFile) {
try {
controlWindow.setStatus("Loading file...");
seq.loadFile(sequenceFile.getPath());
sequenceNameLabel.setText(playlist.getCurrentSongName());
sequenceProgressSlider.setMaximum((int) (seq.getSecondsLength()));
controlWindow.setStatus("Loaded " + sequenceFile.getName());
updateProgressDisplay();
fileLoaded = true;
} catch (Exception ex) {
Logger.getLogger(MoppyControlWindow.class.getName()).log(Level.SEVERE, null, ex);
controlWindow.setStatus("File loading error!");
JOptionPane.showMessageDialog(this.getRootPane(), ex);
fileLoaded = false;
}
enableNextPrev();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel bpmLabel;
private javax.swing.JButton clearButton;
private javax.swing.JLabel currentPositionLabel;
private javax.swing.JPanel jPanel1;
private javax.swing.JButton loadButton;
private javax.swing.JButton loadDirectoryButton;
private javax.swing.JCheckBox loadLastListCheckbox;
private javax.swing.JButton loadListButton;
private javax.swing.JButton nextButton;
private javax.swing.JScrollPane playlistScrollPane;
private javax.swing.JTable playlistTable;
private javax.swing.JButton previousButton;
private javax.swing.JButton randomizeButton;
private javax.swing.JCheckBox resetDrivesCheckbox;
private javax.swing.JButton resetListButton;
private javax.swing.JButton saveListButton;
private javax.swing.JLabel sequenceNameLabel;
private javax.swing.JSlider sequenceProgressSlider;
private javax.swing.JButton startButton;
private javax.swing.JButton stopButton;
private javax.swing.JLabel totalPositionLabel;
// End of variables declaration//GEN-END:variables
@Override
public Transmitter getTransmitter() {
return seq;
}
@Override
public void connected() {
progressTimer.start();
isConnected = true;
if (!(playlist.isFinished())) {startButton.setEnabled(true);}
}
@Override
public void disconnected() {
startButton.setEnabled(false);
pauseSequencer();
isConnected = false;
progressTimer.stop();
seq.setReceiver(null); //Clear receiver so there's no connection here.
}
// <editor-fold defaultstate="collapsed" desc="Playlist specific functions">
private void enableNextPrev() {
previousButton.setEnabled(!playlist.isFirstSong());
nextButton.setEnabled(!playlist.isLastSong());
}
private void playlistEnded() {
interruptNextSong = false;
controlWindow.setStatus("Stopping...");
seq.resetSequencer();
startButton.setText(" ► ");
startButton.setEnabled(false);
sequenceProgressSlider.setValue(0);
fileLoaded = false;
controlWindow.setStatus("Stopped.");
}
private void clearPlaylist() {
interruptNextSong = true;
if (seq.isRunning()) {stopResetSequencer();} //I know this seems redundant, but I did not want to rewrite code and only wanted that part of the function
playlist.clear();
playlistEnded();
if (isConnected) {startButton.setEnabled(true);}
}
private void resetPlaylist() {
interruptNextSong = true;
if (seq.isRunning()) {stopResetSequencer();} //Same as above comment
playlist.reset();
playlistEnded();
if (isConnected) {startButton.setEnabled(true);}
}
private File getPlaylistFile(boolean direction) {
String previouslyLoaded = app.prefs.get(Constants.PREF_LOADED_LIST, null);
if (previouslyLoaded != null) {
sequenceChooser.setCurrentDirectory(new File(previouslyLoaded));
}
sequenceChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
sequenceChooser.setFileFilter(MPLFilter);
int returnVal;
if(direction) {returnVal = sequenceChooser.showOpenDialog(this);}
else {returnVal = sequenceChooser.showSaveDialog(this);}
if (returnVal == JFileChooser.APPROVE_OPTION) {
File returnFile = sequenceChooser.getSelectedFile();
app.prefs.put(Constants.PREF_LOADED_LIST, sequenceChooser.getSelectedFile().getPath());
if(!direction) { //Make sure file ends in appropriate extension
if(!returnFile.getAbsolutePath().endsWith(".mpl")) {returnFile = new File(sequenceChooser.getSelectedFile() + ".mpl");}
}
return returnFile;
}
return null;
}
private boolean savePlaylist(File f) {
if(playlist.savePlaylistFile(f)) {}
else {return false;}
return true;
}
private boolean loadPlaylist(File f) {
if(playlist.loadPlaylistFile(f)) {
app.prefs.put(Constants.PREF_LOADED_MPL, f.getPath());
if (isConnected && !playlist.isEmpty()) {startButton.setEnabled(true);}
}
else {return false;}
return true;
}
private void setupPlaylistTable() {
playlistTable.setModel(playlist);
playlistTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
TableColumnModel ColumnModel = playlistTable.getColumnModel();
ColumnModel.getColumn(0).setResizable(false);
ColumnModel.getColumn(1).setResizable(false);
ColumnModel.getColumn(0).setPreferredWidth(25);
ColumnModel.getColumn(0).setMaxWidth(25);
ColumnModel.getColumn(1).setPreferredWidth(55);
ColumnModel.getColumn(1).setMaxWidth(55);
}// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Key Events">
@Override
public boolean enterKeyAction(KeyEvent e) {
//Simulate clicking the start button
startButtonActionPerformed(null);
return true;
}
@Override
public boolean tabKeyAction(KeyEvent e) {
//Simulate clicking the stop button
stopButtonActionPerformed(null);
return true;
}
@Override
public boolean upKeyAction(KeyEvent e) {
//Simulate clicking the next button
nextButtonActionPerformed(null);
return true;
}
@Override
public boolean downKeyAction(KeyEvent e) {
//Simulate clicking the previous button
previousButtonActionPerformed(null);
return true;
}
// </editor-fold>
}