Results 1 to 6 of 6
Thread: JFileChooser Problem
- 04-29-2011, 01:19 PM #1
Member
- Join Date
- Sep 2010
- Posts
- 24
- Rep Power
- 0
JFileChooser Problem
I am busy trying to learn Java using the book Head First Java and I am trying to use JFileChooser so beats can be saved from a music box program (it is in the above book but only uses serialization). Everything compiles OK, even with the added new JFileChooser code, but when I click the 'Save Beat' button, no dialog box appears. The coding is shown below:
Java Code:/* The BeatBox GUI coding */ import java.io.*; import java.awt.*; import javax.swing.*; import javax.sound.midi.*; import java.util.*; import java.awt.event.*; public class BeatBox { JPanel mainPanel; ArrayList<JCheckBox> checkboxList; //We store checkboxes in an ArrayList Sequencer sequencer; Sequence sequence; Track track; JFrame theFrame; String[] instrumentNames = {"Bass Drum", "Closed Hi-Hat", "Open Hi-Hat", "Acoustic Snare", "Crash Cymbal", "Hand Clap", "High Tom", "Hi Bongo", "Maracas", "Whistle", "Low Conga", "Cowbell", "Vibraslap", "Low-mid Tom", "High Agogo", "Open Hi Conga"}; //These are the names of the instruments, as a String array, //for building the GUI labels on each row int[] instruments = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63}; //These represent the actual drum 'keys'. The drum channel is like a piano, except each 'key' //on the piano is a different drum. So the number '35' is the key for the Bass drum, 42 //is Closed Hi-Hat, etc. public static void main(String[] args) { new BeatBox().buildGUI(); } public void buildGUI() { theFrame = new JFrame("Cyber BeatBox"); theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); BorderLayout layout = new BorderLayout(); JPanel background = new JPanel(layout); background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); //EmptyBorder gives us a margin between the edges of the panel and where the //components are placed. Purely aesthetic. checkboxList = new ArrayList<JCheckBox>(); Box buttonBox = new Box(BoxLayout.Y_AXIS); //Create a Box object called buttonBox for a vertical list JButton start = new JButton("Start"); //. start.addActionListener(new MyStartListener()); //. buttonBox.add(start); //. //. JButton stop = new JButton("Stop"); //. stop.addActionListener(new MyStopListener()); //. buttonBox.add(stop); //. //. JButton upTempo = new JButton("Tempo Up"); //. upTempo.addActionListener(new MyUpTempoListener()); // These lines of code is GUI set-up code for creating 5 buttons buttonBox.add(upTempo); //. //. JButton downTempo = new JButton("Tempo Down"); //. downTempo.addActionListener(new MyDownTempoListener()); //. buttonBox.add(downTempo); //. //. JButton saveBeat = new JButton("Save Beat"); //. downTempo.addActionListener(new OpenChooser()); //. buttonBox.add(saveBeat); //. Box nameBox = new Box(BoxLayout.Y_AXIS); for(int i = 0; i < 16; i++) { nameBox.add(new Label(instrumentNames[i])); //This creates 16 labels with for() loop } background.add(BorderLayout.EAST, buttonBox); //These two lines of code is more GUI set-up code which places the Box objects (buttonBox and background.add(BorderLayout.WEST, nameBox); //nameBox) where you want them. theFrame.getContentPane().add(background); GridLayout grid = new GridLayout(16,16); grid.setVgap(1); grid.setHgap(2); mainPanel = new JPanel(grid); background.add(BorderLayout.CENTER, mainPanel); for(int i = 0; i < 256; i++) { JCheckBox c = new JCheckBox(); //. c.setSelected(false); // Make the checkboxes, set them to false (so they aren't checked) and add them to checkboxList.add(c); // the ArrayList AND to the GUI panel. mainPanel.add(c); //. } setUpMidi(); theFrame.setBounds(50,50,300,300); theFrame.pack(); theFrame.setVisible(true); } public void setUpMidi() { try { sequencer = MidiSystem.getSequencer(); //. sequencer.open(); //. sequence = new Sequence(Sequence.PPQ,4); // Midi set-up for getting the Sequencer, Sequence, and the Track track = sequence.createTrack(); //. sequencer.setTempoInBPM(120); //. } catch(Exception e) { e.printStackTrace(); } } //The coding from this point is where it all happens! Where we turn the checkbox state into MIDI events, and add them to the Track public void buildTrackAndStart() { int[] trackList = null; //We'll make a 16 element array to hold the values of one instrument, across all 16 beats. If the instrument is supposed to //play on that beat, the value of that element will be the key. If the instrument is NOT supposed to play on that beat, put in a zero sequence.deleteTrack(track); //Get rid of the old track, track = sequence.createTrack(); //make a fresh one for(int i = 0; i < 16; i++) //Do this for each of the 16 ROWS (i.e. Bass, Congo etc) { trackList = new int[16]; int key = instruments[i]; //Set the 'key' that represents which instrument this is. The instruments array holds the actual MIDI numbers //for each instrument for(int j = 0; j < 16; j++) //For each of the BEATS for this row { JCheckBox jc = (JCheckBox) checkboxList.get(j + (16 * i)); if(jc.isSelected()) //. { //. trackList[j] = key; // Is the checkbox at this beat selected? If yes, put the key value } // in this slot in the array (the slot that represents this beat). Otherwise, else // the instrument is NOT supposed to play at this beat so set it to zero. { //. trackList[j] = 0; //. } //. } makeTracks(trackList); //For this instrument, and for all 16 beats, make events and add them to the track. track.add(makeEvent(176,1,127,0,16)); } track.add(makeEvent(192,9,1,0,15)); //We always want to make sure that there IS an event at beat 16 (0 to 15). otherwise the BeatBox might not // go the full 16 beats before it starts over. try { sequencer.setSequence(sequence); sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY); //Lets you specify the number of loop iterations or in this case Continuous looping. sequencer.start(); sequencer.setTempoInBPM(120); } catch(Exception e) { e.printStackTrace(); } } public class MyStartListener implements ActionListener //. { //. public void actionPerformed(ActionEvent a) //. { // First of the inner classes (listener for Start button) buildTrackAndStart(); //. } //. } //. public class MyStopListener implements ActionListener { public void actionPerformed(ActionEvent a) { sequencer.stop(); } } public class MyUpTempoListener implements ActionListener { public void actionPerformed(ActionEvent a) { float tempoFactor = sequencer.getTempoFactor(); sequencer.setTempoFactor((float)(tempoFactor * 1.03)); //Default is 1.0 so this increases the default by 3% per click } } public class MyDownTempoListener implements ActionListener { public void actionPerformed(ActionEvent a) { float tempoFactor = sequencer.getTempoFactor(); sequencer.setTempoFactor((float)(tempoFactor * .97)); //Default is 1.0 so this decreases the default by 3% per click } } //START OF EDIT public class OpenChooser implements ActionListener //this class is created so a pattern of beats can be saved { public void actionPerformed(ActionEvent a) //User clicks button and the ActionEvent fires { JFileChooser saveIt = new JFileChooser(); //Hopefully brings up a dialog box saveIt.showSaveDialog(theFrame); //and waits for the user to click 'Save' saveFile(saveIt.getSelectedFile()); //from the dialog box } } private void saveFile(File file) //Hopefully this method() will write out the file and save it { boolean[] checkboxState = new boolean[256]; //Make a boolean array to hold the state of each checkbox (may work) for(int i = 0; i < 256; i++) { JCheckBox check = (JCheckBox) checkboxList.get(i); //. if(check.isSelected()) //. { // Walk through the checkboxList (ArrayList of checkboxes and get the state checkboxState[i] = true; // of each one and add it to the boolean array } //. } //End of may work try { BufferedWriter writer = new BufferedWriter(new FileWriter(file)); writer.close(); } catch(IOException ex) { System.out.println("Cannot Save file"); ex.printStackTrace(); } } //END OF EDIT public void makeTracks(int[] list) //This makes events for one instrument at a time for all 16 beats. So, it might get an int[] for the Bass drum, { //and each index in the array will hold either the key for that instrument, or a zero. If it's a zero, the instrument isn't //supposed to play at that beat. Otherwise, make an event and add it to the track. for(int i = 0; i < 16; i++) { int key = list[i]; if(key != 0) { track.add(makeEvent(144,9,key, 100, i)); //Make the NOTE ON and NOTE OFF events, track.add(makeEvent(128,9,key, 100, i+1)); //and add them to the Track } } } public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) { MidiEvent event = null; try { ShortMessage a = new ShortMessage(); a.setMessage(comd, chan, one, two); event = new MidiEvent(a, tick); } catch(Exception e) { e.printStackTrace(); } return event; } }
- 04-29-2011, 01:22 PM #2
Senior Member
- Join Date
- Jun 2008
- Posts
- 339
- Rep Power
- 5
You're adding the file chooser action listener to downTempo instead of saveBeat. A copy/paste error?
- 04-29-2011, 01:42 PM #3
Member
- Join Date
- Sep 2010
- Posts
- 24
- Rep Power
- 0
Thank you.:)
That was worked out quick. Is there a way of checking mistakes like this without scouring every character in the coding?
- 04-29-2011, 01:56 PM #4
Yes, there is. Test functionality at every step as you write your code. That way, you know any problem you encounter is likely to be in the last bit of code you added.
db
- 04-29-2011, 01:59 PM #5
Senior Member
- Join Date
- Jun 2008
- Posts
- 339
- Rep Power
- 5
These things happen however careful you think you are. Debugging is the art of working out what's gone wrong and where. Java error messages & exceptions generally tell you the basic what and where, but if you don't get any errors you need to take a logical, stepwise approach to identify what the problem is and where it is happening. Like many things in life, it becomes quicker and easier with experience.
If you push a button and nothing happens, the obvious place to look is the ActionListener for the button. It's one of those things that's easy to forget to add or implement.
Try googling for "java debugging techniques" for detailed debugging help.
- 04-29-2011, 02:08 PM #6
Senior Member
- Join Date
- Jun 2008
- Posts
- 339
- Rep Power
- 5
Good point.
Time spent learning how to use a unit testing tool like JUnit or TestNG can repay itself 100-fold.
Test-first and test-driven development are interesting techniques/philosophies - I never had the patience to go the whole hog, and they're no substitute for preparatory design work, but the principles are seductive.
Similar Threads
-
Problem with saving from JFileChooser
By fireshadow4126 in forum AWT / SwingReplies: 2Last Post: 11-24-2010, 08:21 PM -
Problem with JFileChooser and BufferedImage Class
By toro1984 in forum AWT / SwingReplies: 3Last Post: 11-03-2010, 10:09 AM -
JFileChooser problem
By jperson in forum New To JavaReplies: 2Last Post: 02-06-2010, 07:31 PM -
jfilechooser and jtextarea problem
By kostinio in forum AWT / SwingReplies: 7Last Post: 10-07-2009, 08:46 AM -
JFileChooser horizontal scrollbar problem
By nenadm in forum AWT / SwingReplies: 4Last Post: 11-12-2008, 11:16 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks