package instantbach.gui.tab;
// Standard GUI
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// Custom GUI
import instantbach.gui.MainFrame;
import instantbach.gui.tab.progression.MusicPanel;
import instantbach.gui.tab.progression.SymbolButton;
// Custom Data
import instantbach.data.SymbolList;
import instantbach.data.chord.Symbol;
import instantbach.data.Chord;
// Standard Data
import java.util.ArrayList;
/**
* <p>Title: Progression Panel</p>
*
* <p>Description: Represents the panel used to generate a progression and
* display the result</p>
*
* <p>Copyright: Copyright (c) 2007</p>
*
* <p>Company: </p>
*
* @author John Valentino II
* @version 1.0
*/
public class ProgressionPanel extends JPanel implements ActionListener {
/** Reference to the parent frame */
private MainFrame parent;
/** Represents the panel used to write the music */
private MusicPanel musicPanel;
/** Represents the label used to display the current progression */
private JLabel progressionLabel;
/** Represents the current progression */
private SymbolList progression;
/** Represents the list of butons on this panel */
private ArrayList<SymbolButton> buttonList;
/** The button used to voice a computer generated progression */
private JButton computerButton = new JButton("Voice a Computer Generated");
/** The button used to voice the current progression */
private JButton humanButton = new JButton("Voice User Specified");
/** The button to clear the current progression */
private JButton clearButton = new JButton("CLEAR");
/**
* Creates the progression panel
* @param parent MainFrame
* @param availableSymbols SymbolList
*/
public ProgressionPanel(MainFrame parent, SymbolList availableSymbols) {
this.parent = parent;
this.buttonList = new ArrayList<SymbolButton>();
this.progression = new SymbolList();
this.musicPanel = new MusicPanel(this);
this.setLayout(new BorderLayout());
add(musicPanel, BorderLayout.CENTER);
add(createButtonPanel(availableSymbols), BorderLayout.SOUTH);
}
/**
* Creates the button panel
* @param availableSymbols SymbolList
* @return JPanel
*/
public JPanel createButtonPanel(SymbolList availableSymbols) {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = c.HORIZONTAL;
c.insets = new Insets(1,1,1,1);
int column_limit = 8;
int col = 0;
int row = 0;
//for each available symbol..
for (int i = 0; i < availableSymbols.size(); i++) {
Symbol symbol = availableSymbols.get(i);
SymbolButton button = new SymbolButton(symbol);
button.addActionListener(this);
buttonList.add(button);
c.gridx = col;
c.gridy = row;
panel.add(button, c);
col = (col + 1) % column_limit;
if (col == 0) {
row++;
}
}
c.gridx = col;
c.gridy = row;
panel.add(clearButton, c);
clearButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clearButtonPressed();
}
});
row++;
c.gridx = 0;
c.gridy = row;
c.gridwidth = column_limit+1;
progressionLabel = new JLabel("Current Progression: (None)");
panel.add(progressionLabel, c);
row++;
c.gridx = 0;
c.gridy = row;
c.gridwidth = column_limit;
JPanel buttonPanel = new JPanel();
buttonPanel.add(computerButton);
buttonPanel.add(humanButton);
panel.add(buttonPanel, c);
computerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
computerButtonPressed();
}
});
humanButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
humanButtonPressed();
}
});
return panel;
}
/**
* Handles when the clear button is pressed
*/
private void clearButtonPressed() {
parent.clearArea();
progression.clear();
progressionLabel.setText("Current Progression: (None)");
//clear the chords being displayed
musicPanel.displayChords(null, null);
this.setButtonsEnabled(true);
}
/**
* Handles when the user presses the button to generate a progression and voice it
*/
private void computerButtonPressed() {
parent.generateAndVoiceProgression();
this.setButtonsEnabled(false);
}
/**
* Voices the user specified progression
*/
private void humanButtonPressed() {
parent.voiceProgression(progression);
this.setButtonsEnabled(false);
}
/**
* Displays the given progression ane chords
* @param prog SymbolList
* @param chords Chord[]
*/
public void displayChords(SymbolList prog, Chord[] chords) {
//if this was a computer generated progression...
if (progression.size() == 0) { //add the given chords to this interface
for (int i = 0; i < prog.size(); i++) {
progression.add(prog.get(i));
}
}
musicPanel.displayChords(prog, chords);
this.updateProgressionLabel();
}
/**
* Handles when a symbol button is pressed
* @param e ActionEvent
*/
public void actionPerformed(ActionEvent e) {
SymbolButton button = (SymbolButton) e.getSource();
//add this symbol to the current progression
progression.add(button.getSymbol());
//update the progression label
this.updateProgressionLabel();
}
/**
* Sets the state of being able to use the buttons on this interface
* @param state boolean
*/
public synchronized void setButtonsEnabled(final boolean state) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
humanButton.setEnabled(state);
computerButton.setEnabled(state);
for (int i = 0; i < buttonList.size(); i++) {
SymbolButton button = buttonList.get(i);
button.setEnabled(state);
}
}
});
}
/**
* Updates the progression label
*/
private void updateProgressionLabel() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
String label = "";
for (int i = 0; i < progression.size(); i++) {
String text = progression.getDisplayed(i);
if (i != progression.size() - 1)
label += text + ", ";
else
label += text;
}
progressionLabel.setText("Progression: " + label);
}
});
}
}