/* * kproUI.java * * Created on Aug 1, 2012, 8:46:00 PM * * This Java applet is designed as a demonstration of how to drive a Korg Kaossilator Pro using a PC. * The primary purpose is to supply a gate arpeggiator function to enhance the one built into the K-Pro. * Secondary purposes include potentially adding a Roland A300 Pro keyboard controller as a main input device, * and using the gate arp for driving the default Java software synthesizer. * * It was written under Netbeans. * * riemann96@yahoo.com * */ package my.kpro; import java.awt.Color; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; import javax.sound.midi.Instrument; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Receiver; import javax.sound.midi.ShortMessage; import javax.sound.midi.Soundbank; import javax.sound.midi.Synthesizer; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; /** * * @author Curtis Hoffmann * All rights reserved. Please do not use this program for commercial purposes without my permission. */ public class kproUI extends javax.swing.JFrame { // Hold the settings for my metronome. private class metronome { int bpm; // Beats Per Minute int tmr; // Metronome timer int cntr; // Counter, from 1 to 4. int bpmTotal; // BPM * 1000 ms boolean state; // Metronome On/Off button state metronome(int b, int c, boolean s) { tmr = -1; bpm = b; cntr = c; state = s; } } // Store the settings for the MIDI channels for the Kaossilator Pro, some keyboard to be determined later // and the starting channel for the Java software synth (using 12 channels). private class portSettings { int kProChannelNo; int keyboardChannelNo; int defaultChannelNo; portSettings(int kp, int kb, int ds) { kProChannelNo = kp; keyboardChannelNo = kb; defaultChannelNo = ds; } private void setKProChannel(int i) { if((i >= 0 && i <4) || (i >=12 && i <=15)) { // Edit K-Pro Channel No. kProChannelNo = i; checkChannelConflict(); } else { jTextArea1.append("ERROR: |" + i + "| is out of range (0-3)\n"); } } private void setKeyboardChannel(int i) { if((i >= 0 && i <4) || (i >=12 && i <=15)) { // Edit keyboard Channel No. keyboardChannelNo = i; checkChannelConflict(); } else { jTextArea1.append("ERROR: |" + i + "| is out of range (0-3)\n"); } } private void setDefaultSynthChannel(int i) { if(i < 0 || i > 3) { jTextArea1.append("ERROR: |" + i + "| is out of range (2-4)\n"); // Edit Default Synth Starting Channel No. } else { defaultChannelNo = i; checkChannelConflict(); } } private void checkChannelConflict() { // Check for duplicated channel numbers. if(kProChannelNo == keyboardChannelNo) { jTextArea1.append("CAUTION: K-Pro and Keyboard both have the same MIDI channel number.\n"); } if((kProChannelNo >= defaultChannelNo) && (kProChannelNo <= defaultChannelNo + 11)) { jTextArea1.append("CAUTION: K-Pro MIDI channel number overlaps default synth channels.\n"); } if((keyboardChannelNo >= defaultChannelNo) && (keyboardChannelNo <= defaultChannelNo + 11)) { jTextArea1.append("CAUTION: keyboard MIDI channel number overlaps default synth channels.\n"); } } } // Hold the settings for the gate arpeggiator. private class gateArp { boolean state; // gateArp turned on or off int rate; // Seconds per note int ratio; // Ratio of note on to note off boolean onOff; // Toggle for note on and off int onTime; // Number of milliseconds for note on int offTime; // Number of milliseconds for note off int arpTime; // Contains either onTime or offTime when arpeggiator is running int arpTmr; // Number of milliseconds since timer started int currentNote; // Note currently being played from the arp pattern list int calcNote; // Calculated note to play based on bottom note, pattern and step size int patPtr; // Which note within the pattern is currently being played int currentPat; // Which pattern is currently being played int patLength; // Number of notes in the current pattern int stepSize; // Size of steps to take based on the pattern contents gateArp(int r1, int r2, int o1, int o2, int s1) { state = false; // Default to arpeggiator off rate = r1; ratio = r2; onOff = false; onTime = o1; offTime = o2; patPtr = 0; patLength = 4; // Set a default for the starting size and HOPE it matches reality stepSize = s1; arpTmr = -1; // Deactivate the timer so arpeggiator doesn't play } private void calc(){ // Calculate the number of milliseconds for both note on and off times onTime = (rate * ratio) / 100; if(onTime < 1) { // Avoid setting the timer to 0ms. onTime = 1; } if(onTime > rate - 1) { // No point to having an arpeggiator that has a 100% on time onTime = rate - 1; } offTime = rate - onTime; } private void nextNote(int b) { // Calculate the next note based on the pattern and step size if(patPtr >= arpPatternsList.get(currentPat).size()) { // Error check when switching patches with arp turned on. patPtr = 0; patLength = arpPatternsList.get(currentPat).size(); } calcNote = b + ((Integer) arpPatternsList.get(currentPat).get(patPtr)) * stepSize; if(calcNote < 0) calcNote = 0; // Keep note between 0 and 127 if(calcNote > 127) calcNote = 127; patPtr = (patPtr < patLength - 1) ? patPtr+1 : 0; } } // Hold all of the program screen settings, to allow reading and writing them to file and individual patch objects. private class patch { String name; int kProChannel; int keyboardChannel; int defaultChannel; int [] pkProVoices = new int[8]; int [] pdefaultVoices = new int[12]; int selectedVoice; int volume; int bpm; int keyboardBaseNote; int keyboardNoteSpacing; String arpPatternFile; int arpRate; int arpRatio; int arpNoteSpacing; int arpPattern; private void gatherPatch() { // Read settings to object from GUI components. name = jTextField7.getText(); kProChannel = midiPorts.kProChannelNo; keyboardChannel = midiPorts.keyboardChannelNo; defaultChannel = midiPorts.defaultChannelNo; selectedVoice = lastButtonSelected - 1; System.arraycopy(kProVoices, 0, pkProVoices, 0, 8); // source, sourcePosition, dest, destPosition, length System.arraycopy(defaultVoices, 0, pdefaultVoices, 0, 12); volume = keyboardVolume; bpm = met.bpm; keyboardBaseNote = keyboardBottomNote; keyboardNoteSpacing = keyboardSpacing; arpPatternFile = selectedArpFile; arpRate = jSlider2.getValue(); arpRatio = jSlider3.getValue(); arpNoteSpacing = arp.stepSize; arpPattern = arp.currentPat; } private void loadPatch(){ // Transfer object settings to GUI components. jTextField7.setText(name); midiPorts.kProChannelNo = kProChannel; midiPorts.keyboardChannelNo = keyboardChannel; midiPorts.defaultChannelNo = defaultChannel; System.arraycopy(pkProVoices, 0, kProVoices, 0, 8); System.arraycopy(pdefaultVoices, 0, defaultVoices, 0, 12); if(kProDevice != null) { for(int i=0; i<8; i++) { kSaveTo = setVoice(pkProVoices[i], kProInstruments[pkProVoices[i]], midiPorts.kProChannelNo, 4+i, i, true); } } for(int i=0; i< 12; i++) { dSaveTo = setVoice(pdefaultVoices[i], kProInstruments[pdefaultVoices[i]], midiPorts.defaultChannelNo+i, 14+i, 0, true); } jSlider1.setValue(volume); // keyboardVolume = volume; jTextField1.setText(Integer.toString(bpm)); // need to find a way to auto trigger textfield events met.bpm = bpm; jTextField3.setText(Integer.toString(keyboardBaseNote)); keyboardBottomNote = keyboardBaseNote; jTextField4.setText(Integer.toString(keyboardNoteSpacing)); keyboardSpacing = keyboardNoteSpacing; selectedArpFile = arpPatternFile; jSlider2.setValue(arpRate); // arp.rate = arpRate; jSlider3.setValue(arpRatio); // arp.ratio = arpRatio; jTextField5.setText(Integer.toString(arpNoteSpacing)); arp.stepSize = arpNoteSpacing; jComboBox2.setSelectedIndex(arpPattern); // arp.currentPat = arpPattern; dSaveTo = false; kSaveTo = false; jBList.get(selectedVoice).doClick(); } // I still can't get object serializing to work for file saving, so brute-force it. private String makeString() { // Put all settings into a string. String ret = ""; ret += name + "~"; ret += kProChannel + "~"; ret += keyboardChannel +"~"; ret += defaultChannel + "~"; for(int i=0; i<8; i++) { ret += pkProVoices[i] + "~"; } for(int i=0; i<12; i++) { ret += pdefaultVoices[i] + "~"; } ret += selectedVoice + "~"; ret += volume + "~"; ret += bpm + "~"; ret += keyboardBaseNote + "~"; ret += keyboardNoteSpacing + "~"; ret += arpPatternFile + "~"; ret += arpRate + "~"; ret += arpRatio + "~"; ret += arpNoteSpacing + "~"; ret += arpPattern; return(ret); } private void parseFromFile(String s) { // Read a string from a file and parse into the current object. String [] str = s.split("~"); name = str[0]; kProChannel = Integer.parseInt(str[1]); keyboardChannel = Integer.parseInt(str[2]); defaultChannel = Integer.parseInt(str[3]); for(int i = 0; i<8; i++) { pkProVoices[i] = Integer.parseInt(str[4 + i]); } for(int i = 0; i<12; i++) { pdefaultVoices[i] = Integer.parseInt(str[12 + i]); } selectedVoice = Integer.parseInt(str[24]); volume = Integer.parseInt(str[25]); bpm = Integer.parseInt(str[26]); keyboardBaseNote = Integer.parseInt(str[27]); keyboardNoteSpacing = Integer.parseInt(str[28]); arpPatternFile = str[29]; arpRate = Integer.parseInt(str[30]); arpRatio = Integer.parseInt(str[31]); arpNoteSpacing = Integer.parseInt(str[32]); arpPattern = Integer.parseInt(str[33]); } } gateArp arp = new gateArp(1000, 50, 500, 500, 4); // rate, ratio, on time, off time, arp step size metronome met = new metronome(120, 1, false); // bpm, counter, metronome off portSettings midiPorts = new portSettings(0, 1, 4); // K-Pro, keyboard, default Synth starting channel ArrayList patchList = new ArrayList(); ArrayList arpPatternsList = new ArrayList(); // Create the timer that handles both executing the metronome and the gate arp. class timerExec extends TimerTask { // The heart of the timer public void run() { if(met.tmr > -1) { // Code for metronome met.tmr++; if(met.tmr >= met.bpmTotal) { met.tmr = 0; // Need to restart the metronome timer each time jButton12.setText(Integer.toString(met.cntr)); met.cntr = (met.cntr < 4) ? met.cntr + 1: 1; } } if(arp.arpTmr > -1) { arp.arpTmr++; if(arp.arpTmr >= arp.arpTime) { playArp(arp.calcNote); // arpeggiator timer reset automatically in playArp() } } } } /** Creates new form kproUI */ public kproUI() { initComponents(); initJButtonList(); initMidiDevices(); readSoundBank(); initSliders(); } boolean debug = false; timerExec ttd = new timerExec(); Timer masterTimer = new Timer(); MidiDevice kProDevice = null; int channelNo = 0; boolean kSaveTo = false; boolean dSaveTo = false; boolean suppressUpdate = true; // Used to prevent "Add Patch" from inputting patch twice. int lastButtonSelected = 1; int lastPatternSel = 0; Soundbank soundbank = null; Synthesizer synth = null; MidiChannel [] channels = null; Instrument[] aInstruments = null; int keyboardBottomNote = 0; // Replace this line when keyboard plugged in int keyboardSpacing = 1; int keyboardVolume = 50; int keyboardKey = 5; String selectedArpFile = ""; String lastSavedPatchFile = ""; int [] kProVoices = {0, 0, 0, 0, 0, 0, 0, 0}; // For storing 8 instrument voices from the K-Pro. int [] defaultVoices = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // For storing 12 instrument voices from the default synth ArrayList jBList = new ArrayList(); // The K-Pro driver isn't implemented as an instance of the synthesizer class, so there's no way to query it directly to // get the instrument list. The only alternative is to hand-load it here. String kProInstruments[] = {"L.000 Synth Lead", "L.001 Sync", "L.002 Sine Portamt", "L.003 LFO Squ Lead", "L.004 PWM Lead", "L.005 Micro Lead", "L.006 Mini Lead", "L.007 Crazy Lead", "L.008 Syn Decay", "L.009 5th Lead", "L.010 Basic Arp", "L.011 Unison Lead", "L.012 XMod Decay", "L.013 Soft Lead", "L.014 Deci X Lead", "L.015 Talk", "L.016 Syn Brass", "L.017 5th Decay", "L.018 MS20 Lead", "L.019 Saw Lead", "L.020 Fe-Voice", "L.021 Ring Detune", "L.022 Orange Lead", "L.023 Dist Lead", "L.024 5th Brass", "L.025 Belec", "L.026 Ambient", "L.027 LR 5th Lead", "L.028 Tell Min", "L.029 FeedbackLead", "L.030 Sync Lead", "L.031 Square Bell", "L.032 Square Lead", "L.033 Unison Sweep", "L.034 3octave Lead", "L.035 XY Scale", "L.036 Digital Talk", "L.037 LFO Lead", "L.038 XMod SawLead", "L.039 Pitch Mod", "A.040 Vibraphone", "A.041 Trumpet", "A.042 Piano", "A.043 Tape Flute", "A.044 Dist Guitar", "A.045 E.Piano", "A.046 Glass Bell", "A.047 Phase Clav", "A.048 Digerido", "A.049 Elec Sitar", "A.050 Duo Strings", "A.051 Jazz Guitar", "A.052 Tenor Sax", "A.053 Harmonica", "A.054 Flute", "B.055 House Bass", "B.056 Slap Bass", "B.057 Bad Bass", "B.058 Disco Bass", "B.059 Attack Bass", "B.060 Hoover Bass", "B.061 Talk Bass", "B.062 AcousticBass", "B.063 Simple Bass", "B.064 Fat Bass", "B.065 Elec Bass", "B.066 Big Bass", "B.067 Synth Bass", "B.068 Sexy Bass", "B.069 Kick Bass", "B.070 Reso Bass", "B.071 Acid Bass", "B.072 Unison Bass", "B.073 Boost Bass", "B.074 XMod Bass", "B.075 Fall Bass", "B.076 Zap Bass", "B.077 Ring Bass", "B.078 Square Bass", "B.079 DistSawBass", "B.080 MG Bass", "B.081 Bit Bass", "B.082 Stereo Bass", "B.083 Valve Bass", "B.084 Organ Bass", "C.085 Filter Chord", "C.086 Side Chain", "C.087 ArpeggioSine", "C.088 Wurly Chord", "C.089 Guitar Chord", "C.090 E.Guitar Hit", "C.091 Pad Chord 1", "C.092 UM Sequence", "C.093 2039", "C.094 Filter Mod", "C.095 Decay Chord", "C.096 ArpeggioDown", "C.097 Electro Stab", "C.098 Synth Chord", "C.099 Motion Chord", "C.100 ArpeggioPuls", "C.101 Phaser Chord", "C.102 EL Chord", "C.103 Chord Seq", "C.104 FilterMod5th", "C.105 Pad Chord 2", "C.106 DecaySynChod", "C.107 Trance Chord", "C.108 Sine Chord", "C.109 Organ Chord", "C.110 Sweep Chord", "C.111 Power Chord", "C.112 BPF Chord", "C.113 E.Piano Chod", "C.114 Chord Hit", "S.115 Resonate", "S.116 Helicopter", "S.117 Orch Hit", "S.118 Rise/Fall", "S.119 IndustrySFX", "S.120 Infinity", "S.121 XY Cat", "S.122 8bit Noise", "S.123 HPF Square", "S.124 Kaoss Drone", "S.125 Quiz Show", "S.126 Game SFX", "S.127 Sync Random", "S.128 Noise Filter", "S.129 8bit Game", "S.130 Metal", "S.131 Siren", "S.132 Missile", "S.133 Random", "S.134 Beam Saber", "S.135 Synth Looper", "S.136 Ring Mod", "S.137 Voice Looper", "S.138 Sweep", "S.139 Drop", "D.140 Conga", "D.141 Rock Kit", "D.142 Tom", "D.143 House Kit 1", "D.144 House Kit 2", "D.145 Techno Kit", "D.146 Disco Kit", "D.147 Hip Hop Kit", "D.148 Standard Kit", "D.149 80's Kit", "D.150 Cymbal-Revb", "D.151 Cymbal-Filt", "D.152 Clap", "D.153 Percussion", "D.154 Zap/Hit", "D.155 Phone/Clap", "D.156 BD/SD", "D.157 Filter Snare", "D.158 Timpani", "D.159 XMod Perc", "P.160 Hip Hop 1", "P.161 House 1", "P.162 Jam Guitar", "P.163 House 2", "P.164 Conga Loop", "P.165 Techno", "P.166 House 3", "P.167 Electro", "P.168 Dubstep", "P.169 Reggaeton", "P.170 Hip Hop 2", "P.171 Disco", "P.172 Rock", "P.173 Breakbeats", "P.174 Drum'n'Bass", "P.175 Bossa Nova", "P.176 Lo-Fi Breaks", "P.177 Zap Beat", "P.178 XY Drum", "P.179 Deci Beat", "P.180 Beat Box", "P.181 Grain Beat", "P.182 Call Me", "P.183 Taiko", "P.184 Robo", "V.185 Vocod-Unison", "V.186 Vocod-Pulse", "V.187 Vocod-Chord1", "V.188 Vocod-Detune", "V.189 Vocod-Deci", "V.190 Vocod-5th", "V.191 Vocod-Chord2", "V.192 Vocod-Saw", "V.193 Vocod-Echo", "V.194 Vocod-Formnt", "V.195 Audio-Pitch", "V.196 Audio-Grain", "V.197 Audio-Delay", "V.198 Audio-Filter", "V.199 Audio-Looper"}; private void initkProInstrumentList(){ // Add list of Kaossilator Pro instruments to combo box for(int i=0; i al = new ArrayList() String [] str = null; try { BufferedReader reader = new BufferedReader(new FileReader(fname)); String line = ""; while((line = reader.readLine()) != null) { str = line.split(" "); for(int i = 0; i< str.length; i++) { al.add(Integer.parseInt(str[i])); } arpPatternsList.add(al); al = new ArrayList(); } reader.close(); } catch (Exception ex) { jTextArea1.append("\nCouldn't open |" + fname.getName() + "|.\n"); jTextArea1.append(ex.toString()); } String s = ""; // Add arpeggiator patterns to combo box for (int j=0; j -1) { try { kProDevice = MidiSystem.getMidiDevice(infos[kProDeviceNo]); } catch (MidiUnavailableException e) { JOptionPane.showMessageDialog(this, "Couldn't Get Device:" + kProDeviceNo, "Device Open Error", JOptionPane.PLAIN_MESSAGE); } if (!(kProDevice.isOpen())) { try { kProDevice.open(); } catch (MidiUnavailableException e) { JOptionPane.showMessageDialog(this, "Couldn't Open Device:" + kProDeviceNo, "Device Open Error", JOptionPane.PLAIN_MESSAGE); } } initkProInstrumentList(); } else { jComboBox1.setEnabled(false); // Deactivate K-Pro related buttons if no K-Pro for(int i=0; i<11; i++) { jBList.get(i).setEnabled(false); } } } private void readSoundBank() { // Load the default Java software synth try { synth = MidiSystem.getSynthesizer(); synth.open(); soundbank = synth.getDefaultSoundbank(); synth.loadAllInstruments(soundbank); channels = synth.getChannels(); } catch (Exception ex) { JOptionPane.showMessageDialog(this, "Couldn't Open Soundbank:\n" + ex, "Soundbank Open Error", JOptionPane.PLAIN_MESSAGE); } if (soundbank == null){ jTextArea1.setText("no soundbank"); } else { aInstruments = soundbank.getInstruments(); for (int i = 0; i < aInstruments.length; i++) { jComboBox3.addItem(aInstruments[i].getName()); } } } // Even without an external keyboard plugged in, this program can make music by running arpeggiator patterns. // Thus, playArp() is the heart of the app right now. private void playArp(int n) { // Driver code for arpeggiating either default synth or K-Pro arp.arpTmr = -1; // Turn off timer so don't get double-noting if(n != arp.currentNote) { // If playing a different note, force previous note off if(channelNo == midiPorts.kProChannelNo) { kProNote(midiPorts.kProChannelNo, arp.currentNote / 128, arp.currentNote % 128, 0); } else { channels[channelNo].noteOff(arp.currentNote); } arp.currentNote = n; // Load new note } if(arp.onOff) { // Arpeggiating when note is off based on rate and ratio arp.arpTime = arp.offTime; if(channelNo == midiPorts.kProChannelNo) { kProNote(midiPorts.kProChannelNo, n / 128, n % 128, 0); } else { channels[channelNo].noteOff(arp.currentNote); } } else { // Arpeggiating when note is on based on rate and ratio arp.nextNote(keyboardBottomNote + keyboardSpacing * keyboardKey); // Get the next note in the arp pattern based on current keyboard key pressed arp.arpTime = arp.onTime; if(channelNo == midiPorts.kProChannelNo) { kProNote(midiPorts.kProChannelNo, arp.calcNote / 128, arp.calcNote % 128, 1); } else { channels[channelNo].noteOn(arp.currentNote, keyboardVolume); } } arp.onOff = (! arp.onOff); // Switch from arp note on to off and vice versa arp.arpTmr = 0; // Turn arp timer back on } private void kProProgram(int no) { // Change K-Pro instrument int bank = 0; int nbank = 0; int ch = 0; ShortMessage myMsg = new ShortMessage(); Receiver rcvr = null; long timeStamp = -1; if(kProDevice != null) { try { rcvr = kProDevice.getReceiver(); } catch (MidiUnavailableException e) { } try { bank = (no < 127) ? 0 : 1; nbank = (bank == 1) ? 0 : 1; ch = (no < 127) ? no : no - 128; myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 0, nbank); rcvr.send(myMsg, timeStamp); myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 32, bank); rcvr.send(myMsg, timeStamp); myMsg.setMessage(ShortMessage.PROGRAM_CHANGE, midiPorts.kProChannelNo, ch, 0); rcvr.send(myMsg, timeStamp); } catch (javax.sound.midi.InvalidMidiDataException e) { } } } // The Korg K-Pro uses an x-y touchpad for playing music. In order to control it via software, we need to // send 3 MIDI CC (change control) messages. One to set the row, one to set the column, and one to specify the // note as on or off (1 or 0). private void kProNote(int ch, int col, int row, int onOff) { // Change K-Pro note (x-y pad) ShortMessage myMsg = new ShortMessage(); Receiver rcvr = null; long timeStamp = -1; if(kProDevice != null) { try { rcvr = kProDevice.getReceiver(); } catch (MidiUnavailableException e) { } try { myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 12, row); rcvr.send(myMsg, timeStamp); myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 13, col); rcvr.send(myMsg, timeStamp); myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 92, onOff); rcvr.send(myMsg, timeStamp); } catch (javax.sound.midi.InvalidMidiDataException e) { } } } private void kProAllOff() { // Brute-force method to ensure current note is turned off kProNote(midiPorts.kProChannelNo, 0, 0, 0); } // When the user selects an instrument from the screen, there's two choices. They can either click "SaveTo" first, to save // an instrument from the pull down combo box to one of the voice preset buttons, or they can just click the preset and // play the voice previously assigned to that button. setVoice takes the item number from the combo box, the name of the // instrument, the channel number, the K-Pro instrument number (if any) and a flag indicating whether SaveTo was selected // first. If the Java software synth is being played, there's no K-Pro ID number, just a channel number (0-11). If it's // the K-Pro, then we'll get a number 0-7 for the desired preset button. // // setVoice returns the SaveTo flag value. // Regardless of the purpose, the idea is to toggle one of the preset buttons on and off, change the background color // of the button, possibly change the button text to display the instrument name, and to select the channel to play. private boolean setVoice(int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) { boolean retSave = voiceSave; channelNo = ch; jBList.get(lastButtonSelected - 1).setBackground(Color.LIGHT_GRAY); // Return previous button to Gray. lastButtonSelected = buttonId; jBList.get(buttonId - 1).setBackground(Color.red); // Turn current intrument button red. if(voiceSave) { retSave = false; jBList.get(buttonId - 1).setText(voiceName); // Display instrument name on button if(ch == midiPorts.kProChannelNo) { kProVoices[kProId] = voiceNum; kProProgram(kProVoices[kProId]); } else { defaultVoices[ch - midiPorts.defaultChannelNo] = voiceNum; channels[channelNo].programChange(aInstruments[voiceNum].getPatch().getBank(), aInstruments[voiceNum].getPatch().getProgram()); } } else { if(ch == midiPorts.kProChannelNo) { kProProgram(kProVoices[kProId]); } } return(retSave); } // Java doesn't have a built-in function for testing if a string contains a valid integer. So, try to convert the string // to an integer and return false if it throws an exception. private boolean isInt(String s) { boolean ret = false; try { Integer.parseInt(s); ret = true; } catch(NumberFormatException nfe) { } return ret; } private void savePatchFile(String fName) { JFileChooser fileSave = new JFileChooser(); // Save arpeggiator patch file FileFilter ft = new FileNameExtensionFilter("Patch Patterns", "ptc"); fileSave.setFileFilter(ft); boolean done = false; int userChoice = JFileChooser.APPROVE_OPTION; File fileSaveName = null; if(fName.trim().isEmpty()) { while (! done) { userChoice = fileSave.showSaveDialog(this); fileSaveName = fileSave.getSelectedFile(); if(userChoice == JFileChooser.CANCEL_OPTION) { // User cancelled save option done = true; } else { if(fileSave.getSelectedFile().exists()) { // User selected file to save to. userChoice = JOptionPane.showConfirmDialog(this, "File already exists.\nOverwrite it?", "Patch File Save", JOptionPane.YES_NO_OPTION); if(userChoice == JFileChooser.APPROVE_OPTION) { // User wants to overwrite existing file. done = true; } } else { // Writing to new file. done = true; } } } } else { // Saving changes back to previous file. fileSaveName = new File(fName); } if(userChoice == JFileChooser.APPROVE_OPTION) { for(patch p : patchList) { String s = p.makeString(); } try { BufferedWriter writer = new BufferedWriter(new FileWriter(fileSaveName)); for(patch p : patchList) { writer.write(p.makeString() + "\n"); } lastSavedPatchFile = fileSaveName.getPath(); writer.flush(); writer.close(); JOptionPane.showMessageDialog(this, "File Saved."); } catch(IOException ex) { System.err.println("Couldn't save file"); JOptionPane.showMessageDialog(this, "Couldn't Save File.\n" + ex); } } } // Ok, we're going to get a huge block of Netbeans-generated muck that is only useful if you plan on copying this file into a // Netbeans project. To get to the rest of my code, jump down to the line with the dashes in it ("-<><><><><><><>-"). Try // using the find function in your text editor. /** 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") // //GEN-BEGIN:initComponents private void initComponents() { jPanel1 = new javax.swing.JPanel(); jComboBox1 = new javax.swing.JComboBox(); jButton1 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); jButton3 = new javax.swing.JButton(); jButton4 = new javax.swing.JButton(); jButton5 = new javax.swing.JButton(); jButton6 = new javax.swing.JButton(); jButton8 = new javax.swing.JButton(); jButton9 = new javax.swing.JButton(); jButton10 = new javax.swing.JButton(); jButton11 = new javax.swing.JButton(); jButton7 = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); jPanel3 = new javax.swing.JPanel(); jButton13 = new javax.swing.JButton(); jSlider2 = new javax.swing.JSlider(); jLabel2 = new javax.swing.JLabel(); jSlider3 = new javax.swing.JSlider(); jLabel3 = new javax.swing.JLabel(); jComboBox2 = new javax.swing.JComboBox(); jButton29 = new javax.swing.JButton(); jButton30 = new javax.swing.JButton(); jButton31 = new javax.swing.JButton(); jButton32 = new javax.swing.JButton(); jLabel6 = new javax.swing.JLabel(); jTextField2 = new javax.swing.JTextField(); jLabel7 = new javax.swing.JLabel(); jTextField5 = new javax.swing.JTextField(); jTextField6 = new javax.swing.JTextField(); jButton33 = new javax.swing.JButton(); jButton34 = new javax.swing.JButton(); jPanel4 = new javax.swing.JPanel(); jSlider1 = new javax.swing.JSlider(); jLabel1 = new javax.swing.JLabel(); jButton12 = new javax.swing.JButton(); jTextField1 = new javax.swing.JTextField(); jLabel4 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); jLabel8 = new javax.swing.JLabel(); jTextField3 = new javax.swing.JTextField(); jLabel9 = new javax.swing.JLabel(); jTextField4 = new javax.swing.JTextField(); jLabel10 = new javax.swing.JLabel(); jTextField7 = new javax.swing.JTextField(); jComboBox4 = new javax.swing.JComboBox(); jButton35 = new javax.swing.JButton(); jButton36 = new javax.swing.JButton(); jPanel5 = new javax.swing.JPanel(); jComboBox3 = new javax.swing.JComboBox(); jButton26 = new javax.swing.JButton(); jButton27 = new javax.swing.JButton(); jButton28 = new javax.swing.JButton(); jButton14 = new javax.swing.JButton(); jButton15 = new javax.swing.JButton(); jButton16 = new javax.swing.JButton(); jButton17 = new javax.swing.JButton(); jButton18 = new javax.swing.JButton(); jButton19 = new javax.swing.JButton(); jButton20 = new javax.swing.JButton(); jButton21 = new javax.swing.JButton(); jButton22 = new javax.swing.JButton(); jButton23 = new javax.swing.JButton(); jButton24 = new javax.swing.JButton(); jButton25 = new javax.swing.JButton(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); jMenuItem1 = new javax.swing.JMenuItem(); jMenuItem2 = new javax.swing.JMenuItem(); jMenuItem3 = new javax.swing.JMenuItem(); jMenuItem4 = new javax.swing.JMenuItem(); jMenuItem8 = new javax.swing.JMenuItem(); jMenuItem9 = new javax.swing.JMenuItem(); jMenuItem5 = new javax.swing.JMenuItem(); jMenu2 = new javax.swing.JMenu(); jMenuItem6 = new javax.swing.JMenuItem(); jMenuItem10 = new javax.swing.JMenuItem(); jMenuItem11 = new javax.swing.JMenuItem(); jMenuItem12 = new javax.swing.JMenuItem(); jMenu3 = new javax.swing.JMenu(); jMenuItem7 = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(250, 0, 0))); jButton1.setText("U"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); jButton2.setText("D"); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); jButton3.setText("Save to"); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } }); jButton4.setText("Pattern 1"); jButton4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton4ActionPerformed(evt); } }); jButton5.setText("Pattern 2"); jButton5.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton5ActionPerformed(evt); } }); jButton6.setText("Pattern 3"); jButton6.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton6ActionPerformed(evt); } }); jButton8.setText("Pattern 5"); jButton8.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton8ActionPerformed(evt); } }); jButton9.setText("Pattern 6"); jButton9.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton9ActionPerformed(evt); } }); jButton10.setText("Pattern 7"); jButton10.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton10ActionPerformed(evt); } }); jButton11.setText("Pattern 8"); jButton11.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton11ActionPerformed(evt); } }); jButton7.setText("Pattern 4"); jButton7.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton7ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton3) .addGap(27, 27, 27) .addComponent(jButton8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jButton9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton5, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jButton10, javax.swing.GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE) .addComponent(jButton6, javax.swing.GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jButton7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton11, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)) .addGap(484, 484, 484)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButton4) .addComponent(jButton5) .addComponent(jButton6) .addComponent(jButton7)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton1) .addComponent(jButton2) .addComponent(jButton3) .addComponent(jButton8) .addComponent(jButton9) .addComponent(jButton11) .addComponent(jButton10)) .addGap(181, 181, 181)) ); jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 0, 0))); jTextArea1.setColumns(20); jTextArea1.setRows(5); jScrollPane1.setViewportView(jTextArea1); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 1242, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(46, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE) .addContainerGap()) ); jPanel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 0, 0))); jButton13.setText("Gate Arp"); jButton13.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton13ActionPerformed(evt); } }); jSlider2.setMaximum(10); jSlider2.setValue(2); jSlider2.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jSlider2StateChanged(evt); } }); jLabel2.setText("Rate: 1 sec."); jSlider3.setMaximum(99); jSlider3.setMinimum(1); jSlider3.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jSlider3StateChanged(evt); } }); jLabel3.setText("Ratio: 50%"); jComboBox2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jComboBox2ActionPerformed(evt); } }); jButton29.setText("L"); jButton29.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton29ActionPerformed(evt); } }); jButton30.setText("R"); jButton30.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton30ActionPerformed(evt); } }); jButton31.setText("L"); jButton31.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton31ActionPerformed(evt); } }); jButton32.setText("R"); jButton32.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton32ActionPerformed(evt); } }); jLabel6.setText("Base Note:"); jTextField2.setText("60"); jTextField2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField2ActionPerformed(evt); } }); jLabel7.setText("Note Spacing:"); jTextField5.setText("4"); jTextField5.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField5ActionPerformed(evt); } }); jButton33.setText("Append Pattern"); jButton33.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton33ActionPerformed(evt); } }); jButton34.setText("Delete Pattern"); jButton34.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton34ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jButton13, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(313, 313, 313)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jButton29, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton30)) .addGroup(jPanel3Layout.createSequentialGroup() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() .addComponent(jButton31, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton32, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jTextField2) .addComponent(jTextField5, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE))) .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jSlider3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel3)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jButton33) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton34)) .addComponent(jTextField6, javax.swing.GroupLayout.PREFERRED_SIZE, 304, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel2) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jButton13, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton29) .addComponent(jButton30)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jSlider3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton31) .addComponent(jButton32))) .addComponent(jLabel3)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel6) .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel7) .addComponent(jTextField5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jTextField6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton33) .addComponent(jButton34)) .addContainerGap(40, Short.MAX_VALUE)) ); jPanel4.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 0, 0))); jSlider1.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jSlider1StateChanged(evt); } }); jLabel1.setFont(new java.awt.Font("MS UI Gothic", 1, 12)); jLabel1.setText("Volume"); jButton12.setText(" "); jButton12.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton12ActionPerformed(evt); } }); jTextField1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField1ActionPerformed(evt); } }); jLabel4.setText("Metronome"); jLabel5.setText("BPM"); jLabel8.setText("Base Note:"); jTextField3.setText("10"); jTextField3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField3ActionPerformed(evt); } }); jLabel9.setText("Note Spacing:"); jTextField4.setText("1"); jTextField4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField4ActionPerformed(evt); } }); jLabel10.setText("Patch Name:"); jTextField7.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField7ActionPerformed(evt); } }); jComboBox4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jComboBox4ActionPerformed(evt); } }); jButton35.setText("Add Patch"); jButton35.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton35ActionPerformed(evt); } }); jButton36.setText("Delete Patch"); jButton36.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton36ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jLabel4) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jComboBox4, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jLabel10, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel9, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel8, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton12, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jTextField3) .addComponent(jTextField4) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel5)) .addComponent(jTextField7, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(jButton35, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton36))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jSlider1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton12, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel5)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel4) .addGap(18, 18, 18) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel8) .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel9) .addComponent(jTextField4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel10) .addComponent(jTextField7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jComboBox4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton35) .addComponent(jButton36)) .addContainerGap(70, Short.MAX_VALUE)) ); jPanel5.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 0, 0))); jButton26.setText("U"); jButton26.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton26ActionPerformed(evt); } }); jButton27.setText("D"); jButton27.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton27ActionPerformed(evt); } }); jButton28.setText("Save to"); jButton28.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton28ActionPerformed(evt); } }); jButton14.setText("Channel 2"); jButton14.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton14ActionPerformed(evt); } }); jButton15.setText("Channel 3"); jButton15.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton15ActionPerformed(evt); } }); jButton16.setText("Channel 4"); jButton16.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton16ActionPerformed(evt); } }); jButton17.setText("Channel 5"); jButton17.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton17ActionPerformed(evt); } }); jButton18.setText("Channel 6"); jButton18.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton18ActionPerformed(evt); } }); jButton19.setText("Channel 7"); jButton19.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton19ActionPerformed(evt); } }); jButton20.setText("Channel 8"); jButton20.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton20ActionPerformed(evt); } }); jButton21.setText("Channel 9"); jButton21.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton21ActionPerformed(evt); } }); jButton22.setText("Channel 10"); jButton22.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton22ActionPerformed(evt); } }); jButton23.setText("Channel 11"); jButton23.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton23ActionPerformed(evt); } }); jButton24.setText("Channel 12"); jButton24.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton24ActionPerformed(evt); } }); jButton25.setText("Channel 13"); jButton25.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton25ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); jPanel5.setLayout(jPanel5Layout); jPanel5Layout.setHorizontalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel5Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jButton23, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton20, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton17, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton14, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jComboBox3, 0, 192, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel5Layout.createSequentialGroup() .addComponent(jButton26) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton27) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton28)) .addGroup(jPanel5Layout.createSequentialGroup() .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jButton24, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton21, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton18, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton15, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jButton25, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton22, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton19, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton16, javax.swing.GroupLayout.PREFERRED_SIZE, 234, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addContainerGap(55, Short.MAX_VALUE)) ); jPanel5Layout.setVerticalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel5Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButton26) .addComponent(jButton27) .addComponent(jButton28)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton14) .addComponent(jButton16) .addComponent(jButton15)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton17) .addComponent(jButton18) .addComponent(jButton19)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton20) .addComponent(jButton21) .addComponent(jButton22)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton23) .addComponent(jButton24) .addComponent(jButton25)) .addContainerGap(216, Short.MAX_VALUE)) ); jMenu1.setText("File"); jMenuItem1.setText("New"); jMenu1.add(jMenuItem1); jMenuItem2.setText("Open Patch File"); jMenuItem2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem2ActionPerformed(evt); } }); jMenu1.add(jMenuItem2); jMenuItem3.setText("Save Patch File"); jMenuItem3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem3ActionPerformed(evt); } }); jMenu1.add(jMenuItem3); jMenuItem4.setText("SaveAs Patch File"); jMenuItem4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem4ActionPerformed(evt); } }); jMenu1.add(jMenuItem4); jMenuItem8.setText("Read Arp Patterns"); jMenuItem8.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem8ActionPerformed(evt); } }); jMenu1.add(jMenuItem8); jMenuItem9.setText("Save Arp Patterns"); jMenuItem9.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem9ActionPerformed(evt); } }); jMenu1.add(jMenuItem9); jMenuItem5.setText("Close"); jMenuItem5.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem5ActionPerformed(evt); } }); jMenu1.add(jMenuItem5); jMenuBar1.add(jMenu1); jMenu2.setText("Edit"); jMenuItem6.setText("K-Pro Channel"); jMenuItem6.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem6ActionPerformed(evt); } }); jMenu2.add(jMenuItem6); jMenuItem10.setText("Keyboard Channel"); jMenuItem10.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem10ActionPerformed(evt); } }); jMenu2.add(jMenuItem10); jMenuItem11.setText("Default Synth Channel"); jMenuItem11.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem11ActionPerformed(evt); } }); jMenu2.add(jMenuItem11); jMenuItem12.setText("Retry K-Pro Read"); jMenuItem12.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem12ActionPerformed(evt); } }); jMenu2.add(jMenuItem12); jMenuBar1.add(jMenu2); jMenu3.setText("About"); jMenuItem7.setText("About"); jMenuItem7.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem7ActionPerformed(evt); } }); jMenu3.add(jMenuItem7); jMenuBar1.add(jMenu3); setJMenuBar(jMenuBar1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 323, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void jMenuItem5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem5ActionPerformed masterTimer.cancel(); // File -> Exit Program kProAllOff(); if(kProDevice != null) { kProDevice.close(); } synth.close(); System.exit(0); }//GEN-LAST:event_jMenuItem5ActionPerformed // -<><><><><><><>- // // We're back in my code again. // // -<><><><><><><>- // Do clean-up before exiting app. private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing masterTimer.cancel(); // Clicked on Close Window stop timer and close MIDi devices. kProAllOff(); if(kProDevice != null) { kProDevice.close(); } synth.close(); }//GEN-LAST:event_formWindowClosing // Change synth volume. private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSlider1StateChanged ShortMessage myMsg = new ShortMessage(); // Changing volume with slider control Receiver rcvr = null; if(kProDevice != null) { try { rcvr = kProDevice.getReceiver(); } catch (MidiUnavailableException e) { } try { long timeStamp = -1; myMsg.setMessage(ShortMessage.CONTROL_CHANGE, midiPorts.kProChannelNo, 94, jSlider1.getValue()); rcvr.send(myMsg, timeStamp); } catch (javax.sound.midi.InvalidMidiDataException e) { } } else { keyboardVolume = jSlider1.getValue(); } }//GEN-LAST:event_jSlider1StateChanged // Select previous item in K-Pro instrument list combo box. private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed int sel = jComboBox1.getSelectedIndex(); // Go up one in the instrument list if(sel > 0) { sel--; jComboBox1.setSelectedIndex(sel); } }//GEN-LAST:event_jButton1ActionPerformed // Select next item in K-Pro instrument list combo box. private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed int sel = jComboBox1.getSelectedIndex(); // Go down one in the instrument list if(sel < jComboBox1.getItemCount() - 1) { sel++; jComboBox1.setSelectedIndex(sel); } }//GEN-LAST:event_jButton2ActionPerformed // User clicked on SaveTo button for K-Pro preset buttons. private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed kSaveTo = true; // Save Instrument selection to pattern button }//GEN-LAST:event_jButton3ActionPerformed // The next 8 functions are all the same. The user clicked on one of the K-Pro preset instrument buttons. Call setVoice() to // toggle the specified button and play that instrument. private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed // Selected K-Pro instrument button 1 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 4, 0, kSaveTo); }//GEN-LAST:event_jButton4ActionPerformed private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed // // Selected K-Pro instrument button 2 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 5, 1, kSaveTo); }//GEN-LAST:event_jButton5ActionPerformed private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton6ActionPerformed // // Selected K-Pro instrument button 3 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 6, 2, kSaveTo); }//GEN-LAST:event_jButton6ActionPerformed private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton7ActionPerformed // // Selected K-Pro instrument button 4 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 7, 3, kSaveTo); }//GEN-LAST:event_jButton7ActionPerformed private void jButton8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton8ActionPerformed // // Selected K-Pro instrument button 5 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 8, 4, kSaveTo); }//GEN-LAST:event_jButton8ActionPerformed private void jButton9ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton9ActionPerformed // // Selected K-Pro instrument button 6 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 9, 5, kSaveTo); }//GEN-LAST:event_jButton9ActionPerformed private void jButton10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton10ActionPerformed // // Selected K-Pro instrument button 7 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 10, 6, kSaveTo); }//GEN-LAST:event_jButton10ActionPerformed private void jButton11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton11ActionPerformed // setPatternButtonColor(7); // Selected K-Pro instrument button 8 // (int voiceNum, String voiceName, int ch, int buttonId, int kProId, boolean voiceSave) kSaveTo = setVoice(jComboBox1.getSelectedIndex(), (String) jComboBox1.getSelectedItem(), midiPorts.kProChannelNo, 11, 7, kSaveTo); }//GEN-LAST:event_jButton11ActionPerformed // User turned the metronome on or off. private void jButton12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton12ActionPerformed if(met.state) { // Turn metronome on and off met.tmr = -1; met.cntr = 1; jButton12.setText(" "); } else { met.bpmTotal = 1000 * 60 / met.bpm; met.tmr = 0; } met.state = (! met.state); }//GEN-LAST:event_jButton12ActionPerformed // User entered a Beats Per Minute value to the textfield for the metronome. private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed int timerState = met.tmr; if(isInt(jTextField1.getText())) { met.tmr = -1; // Change metronome BPM met.bpm = Integer.parseInt(jTextField1.getText()); met.bpmTotal = 1000 * 60 / met.bpm; met.cntr = 1; jButton12.setText(" "); met.state = false; met.tmr = timerState; } else { jTextArea1.append(jTextField1.getText() + " is not a number.\n"); } }//GEN-LAST:event_jTextField1ActionPerformed // User turned the gate arpeggiator on or off. private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton13ActionPerformed if(arpPatternsList.size() > 0) { if(arp.state) { // Gate Arp ON/Off Button pressed arp.arpTmr = -1; jButton13.setBackground(Color.lightGray); kProAllOff(); } else { arp.arpTmr = 0; jButton13.setBackground(Color.red); } arp.state = (! arp.state); } else { jTextArea1.append("No apreggiator patterns loaded yet.\n"); } }//GEN-LAST:event_jButton13ActionPerformed // User moved the slider for the gate arp rate setting. private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSlider2StateChanged String s[] = {"4 sec.", "2 sec.", "1 sec.", "3/4", "2/3 sec.", "1/2 sec.", "1/3 sec.", "1/4 sec.", "1/8 sec.", "1/16 sec.", "1/32 sec."}; int i[] = {4000, 2000, 1000, 750, 666, 500, 333, 250, 125, 62, 31}; jLabel2.setText("Rate: " + s[jSlider2.getValue()]); if(arp.state) { arp.arpTmr = -1; kProAllOff(); } arp.rate = i[jSlider2.getValue()]; arp.onOff = true; arp.calc(); arp.arpTime = arp.onTime; if(arp.state) { arp.arpTmr = 0; } }//GEN-LAST:event_jSlider2StateChanged // User moved the slider for the gate arp ratio setting. private void jSlider3StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSlider3StateChanged if(arp.state) { // Gate Arp Ratio arp.arpTmr = -1; kProAllOff(); } jLabel3.setText("Ratio: " + jSlider3.getValue() + "%"); arp.onOff = true; arp.ratio = jSlider3.getValue(); arp.calc(); arp.arpTime = arp.onTime; if(arp.state) { arp.arpTmr = 0; } }//GEN-LAST:event_jSlider3StateChanged // User clicked on the down button to select the next instrument from the combo box for the Java default software synthesizer. private void jButton26ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton26ActionPerformed int sel = jComboBox3.getSelectedIndex(); // Built-in Synth instrument Down select if(sel > 0) { sel--; jComboBox3.setSelectedIndex(sel); } }//GEN-LAST:event_jButton26ActionPerformed // User clicked on the up button to select the previous instrument from the combo box for the Java default software synthesizer. private void jButton27ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton27ActionPerformed int sel = jComboBox3.getSelectedIndex(); // Built-in Synth instrument Up select if(sel < jComboBox3.getItemCount() - 1) { sel++; jComboBox3.setSelectedIndex(sel); } }//GEN-LAST:event_jButton27ActionPerformed // User clicked on SaveTo for the Java default software synthesizer. private void jButton28ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton28ActionPerformed dSaveTo = true; // Built-in Synth instrument Save to }//GEN-LAST:event_jButton28ActionPerformed // Ok, the next 12 buttons are going to all be the same agin. This time, they're for the preset buttons for the // Java default software synthesizer. private void jButton14ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton14ActionPerformed // Selected default synth channel 1 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo, 14, 0, dSaveTo); }//GEN-LAST:event_jButton14ActionPerformed private void jButton15ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton15ActionPerformed // Selected default synth channel 2 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+1, 15, 0, dSaveTo); }//GEN-LAST:event_jButton15ActionPerformed private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton16ActionPerformed // Selected default synth channel 3 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+2, 16, 0, dSaveTo); }//GEN-LAST:event_jButton16ActionPerformed private void jButton17ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton17ActionPerformed // Selected default synth channel 4 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+3, 17, 0, dSaveTo); }//GEN-LAST:event_jButton17ActionPerformed private void jButton18ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton18ActionPerformed // Selected default synth channel 5 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+4, 18, 0, dSaveTo); }//GEN-LAST:event_jButton18ActionPerformed private void jButton19ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton19ActionPerformed // Selected default synth channel 6 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+5, 19, 0, dSaveTo); }//GEN-LAST:event_jButton19ActionPerformed private void jButton20ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton20ActionPerformed // Selected default synth channel 7 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+6, 20, 0, dSaveTo); }//GEN-LAST:event_jButton20ActionPerformed private void jButton21ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton21ActionPerformed // Selected default synth channel 8 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+7, 21, 0, dSaveTo); }//GEN-LAST:event_jButton21ActionPerformed private void jButton22ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton22ActionPerformed // Selected default synth channel 9 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+8, 22, 0, dSaveTo); }//GEN-LAST:event_jButton22ActionPerformed private void jButton23ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton23ActionPerformed // Selected default synth channel 10 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+9, 23, 0, dSaveTo); }//GEN-LAST:event_jButton23ActionPerformed private void jButton24ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton24ActionPerformed // Selected default synth channel 11 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+10, 24, 0, dSaveTo); }//GEN-LAST:event_jButton24ActionPerformed private void jButton25ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton25ActionPerformed // Selected default synth channel 12 // (int voiceNum, String voiceName, ch, buttonId, int kProId, boolean voiceSave) dSaveTo = setVoice(jComboBox3.getSelectedIndex(), (String) jComboBox3.getSelectedItem(), midiPorts.defaultChannelNo+11, 25, 0, dSaveTo); }//GEN-LAST:event_jButton25ActionPerformed // User entered a number for the bottom note of the keyboard. Later, I'll replace this function with a MIDI read from an actual // keyboard. For right now,it lets me play some rudimentary tunes with the gate arp turned on. When either jTextField3 (base note) // or jTextField5 change, update the contents of jTextField2, the gate arp base note field (which is display-only right now. private void jTextField3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField3ActionPerformed if(isInt(jTextField3.getText())) { keyboardBottomNote = Integer.parseInt(jTextField3.getText()); jTextField2.setText(Integer.toString(keyboardBottomNote + keyboardKey * keyboardSpacing)); // bottomNote = Integer.parseInt(jTextField3.getText()); // Keyboard bottom note // Right now, arpBottom note is being used to set the start point of the arpeggiator pattern. // However, when a keyboard is added eventually, jTextField3 will be used to offset the base note of the keyboard // and jTextField4 will be used to set the spacing between keys. This will produced a "current note being pressed" // which will then replace the arpeggiator bottom note text field. } else { jTextArea1.append(jTextField3.getText() + " is not a number.\n"); } }//GEN-LAST:event_jTextField3ActionPerformed // There are two buttons that supplement the gate arp rate slider, for single incrementing or decrementing the slider. private void jButton29ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton29ActionPerformed int x = jSlider2.getValue(); // Arp Rate U button if(x > 0) { x--; jSlider2.setValue(x); } }//GEN-LAST:event_jButton29ActionPerformed private void jButton30ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton30ActionPerformed int x = jSlider2.getValue(); // Arp Rate D button if(x < jSlider2.getMaximum()) { x++; jSlider2.setValue(x); } }//GEN-LAST:event_jButton30ActionPerformed // There are also two buttons that supplement the gate arp ratio slider, for single incrementing or decrementing the slider. private void jButton31ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton31ActionPerformed int x = jSlider3.getValue(); // Arp Ratio U button if(x > 0) { x--; jSlider3.setValue(x); } }//GEN-LAST:event_jButton31ActionPerformed private void jButton32ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton32ActionPerformed int x = jSlider3.getValue(); // Arp Ratio D button if(x < jSlider3.getMaximum()) { x++; jSlider3.setValue(x); } }//GEN-LAST:event_jButton32ActionPerformed // Gate arp bottom note. Display only (calculated from keyboard bottom note and keyboard spacing. private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField2ActionPerformed // keyboardBottomNote = Integer.parseInt(jTextField2.getText()); // Arp bottom note }//GEN-LAST:event_jTextField2ActionPerformed // User selected a gate arpeggiator pattern from the combo box. If the gate arp is on, play the pattern. Either way // put the pattern into a text box to let the user edit it. private void jComboBox2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox2ActionPerformed arp.currentPat = jComboBox2.getSelectedIndex(); // Selecting arp pattern arp.patLength = arpPatternsList.get(arp.currentPat).size(); String s = (String) jComboBox2.getSelectedItem(); s = s.substring(s.indexOf(")") + 1); // Strip out pattern number at beginning jTextField6.setText(s.trim()); }//GEN-LAST:event_jComboBox2ActionPerformed // User changed the gate arp pattern step size in the text box. private void jTextField5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField5ActionPerformed if(isInt(jTextField5.getText())) { arp.stepSize = Integer.parseInt(jTextField5.getText()); // Changing Arp Step Spacing } else { jTextArea1.append(jTextField5.getText() + " is not a number.\n"); } }//GEN-LAST:event_jTextField5ActionPerformed // User changed the keyboard note spacing. Update the gate arp base note display. private void jTextField4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField4ActionPerformed if(isInt(jTextField4.getText())) { keyboardSpacing = Integer.parseInt(jTextField4.getText()); // Changing keyboard note spacing jTextField2.setText(Integer.toString(keyboardBottomNote + keyboardKey * keyboardSpacing)); } else { jTextArea1.append(jTextField4.getText() + " is not a number.\n"); } }//GEN-LAST:event_jTextField4ActionPerformed // Save the gate arpeggiator patterns to a file. private void jMenuItem9ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem9ActionPerformed String s = ""; boolean done = false; JFileChooser fileSaveChoice = new JFileChooser(); // Save arp file FileFilter ft = new FileNameExtensionFilter("Arp Patterns", "arp"); fileSaveChoice.setFileFilter(ft); int userChoice = JFileChooser.CANCEL_OPTION; while (! done) { userChoice = fileSaveChoice.showSaveDialog(this); if(fileSaveChoice.getSelectedFile().exists()) { userChoice = JOptionPane.showConfirmDialog(this, "File already exists.\nOverwrite it?", "Patch File Save", JOptionPane.YES_NO_OPTION); if(userChoice == JFileChooser.APPROVE_OPTION) { done = true; } } else { done = true; } } if(userChoice == JFileChooser.APPROVE_OPTION) { try { BufferedWriter writer = new BufferedWriter(new FileWriter(fileSaveChoice.getSelectedFile())); for(ArrayList a : arpPatternsList) { s = ""; for(int i=0; i < a.size(); i++) { s += " " + a.get(i); } writer.write(s.trim() + "\n"); } writer.flush(); writer.close(); JOptionPane.showMessageDialog(this, "File Saved."); selectedArpFile = fileSaveChoice.getSelectedFile().getPath(); } catch(IOException ex) { System.err.println("Couldn't save file"); JOptionPane.showMessageDialog(this, "Couldn't Save File.\n" + ex); } } }//GEN-LAST:event_jMenuItem9ActionPerformed // Read the gate arpeggiator patterns from a file. This can either be manually called by the user from the File Menu, or // automatically called when the user loads the patches from a patch file. private void jMenuItem8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem8ActionPerformed JFileChooser fileRead = new JFileChooser(); // File Menu Item ->Read Arp Patterns File FileFilter ft = new FileNameExtensionFilter("Arp Patterns", "arp"); fileRead.setFileFilter(ft); int userChoice = fileRead.showOpenDialog(this); if(userChoice == JFileChooser.APPROVE_OPTION) { readArpPatFile(fileRead.getSelectedFile()); } }//GEN-LAST:event_jMenuItem8ActionPerformed // User is attempting to add a gate arp pattern to the combo box. Fail if the pattern contains something other than integers // (space delimited), or if the identical pattern already exists. private void jButton33ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton33ActionPerformed String s = jTextField6.getText(); // Add new pattern to Arp list String [] str = s.split(" "); ArrayList a = new ArrayList(); boolean goodSoFar = true; for(int i = 0; i < str.length; i++) { if(isInt(str[i])) { a.add(Integer.parseInt(str[i])); // Build up new pattern as Integer ArayList } else { goodSoFar = false; } } if(goodSoFar) { for(int i=0; i < jComboBox2.getItemCount(); i++) { if(jComboBox2.getItemAt(i).equals(s)) { goodSoFar = false; } } if(goodSoFar) { arpPatternsList.add(a); // Add to the main patterns list jComboBox2.addItem(s); // Add to combobox jComboBox2.setSelectedIndex(jComboBox2.getItemCount() - 1); } else { jTextArea1.append("Pattern already exists. Not added to list.\n"); } } else { jTextArea1.append("Bad string. Contains Not a Number.\n"); } }//GEN-LAST:event_jButton33ActionPerformed // User wants to delete the currently-selected gate arp pattern. Fail if there's only one pattern. Trying to delete the only // pattern in the combo box will throw an exception. private void jButton34ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton34ActionPerformed int curPatNo = jComboBox2.getSelectedIndex(); // Delete arp pattern int curSize = -1; String s = ""; if(arpPatternsList.size() > 1) { arpPatternsList.remove(curPatNo); jComboBox2.removeItemAt(curPatNo); curSize = arpPatternsList.size(); if(curPatNo <= 0) { // If deleted first in list, select current first pattern jComboBox2.setSelectedIndex(0); } else if(curPatNo >= jComboBox2.getItemCount() - 1) { // If deleted last in list, select current last pattern jComboBox2.setSelectedIndex(jComboBox2.getItemCount() - 1); } else { // Select previous pattern instead jComboBox2.setSelectedIndex(curPatNo - 1); } } else { jTextArea1.append("Can't delete remaining patterns without getting a system error.\nPlease add a new pattern before deleting this one.\n"); } }//GEN-LAST:event_jButton34ActionPerformed // User is attempting to change the MIDI channel number for the K-Pro. Open a dialog box to get the new channel number. // If the channel is changed, check for errors (allowed values: 0-3 and 13-15). private void jMenuItem6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem6ActionPerformed String s = (String)JOptionPane.showInputDialog(this, "K-Pro MIDI Channel:", "Channel", JOptionPane.PLAIN_MESSAGE, null, null, midiPorts.kProChannelNo); midiPorts.setKProChannel(Integer.parseInt(s)); }//GEN-LAST:event_jMenuItem6ActionPerformed // User is attempting to change the MIDI channel number for the keyboard (if any). Open a dialog box to get the new channel number. // If the channel is changed, check for errors (allowed values: 0-3 and 13-15). private void jMenuItem10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem10ActionPerformed String s = (String)JOptionPane.showInputDialog(this, "Keyboard MIDI Channel:", "Channel", JOptionPane.PLAIN_MESSAGE, null, null, midiPorts.keyboardChannelNo); midiPorts.setKeyboardChannel(Integer.parseInt(s)); }//GEN-LAST:event_jMenuItem10ActionPerformed // User is attempting to change the starting MIDI channel number for the default synth. Open a dialog box to get the new channel number. // If the channel is changed, check for errors (allowed values: 0-3). Default synth uses 12 sequential channels. private void jMenuItem11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem11ActionPerformed String s = (String)JOptionPane.showInputDialog(this, "Default Synth Starting MIDI Channel:", "Channel", JOptionPane.PLAIN_MESSAGE, null, null, midiPorts.defaultChannelNo); midiPorts.setDefaultSynthChannel(Integer.parseInt(s)); }//GEN-LAST:event_jMenuItem11ActionPerformed // Display the About box. private void jMenuItem7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem7ActionPerformed JOptionPane.showMessageDialog(this, "Kaossilator MIDI Driver and Arpeggiator\nCopyright Curtis H. Hoffmann\n(c)2012", "About K-Gator", JOptionPane.PLAIN_MESSAGE); }//GEN-LAST:event_jMenuItem7ActionPerformed // User is attempting to add a new patch (all of the screen settings in one patch object) to the combo box. Fail if a patch // with the same name already exists. private void jButton35ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton35ActionPerformed patch newPatch = new patch(); // Clicked Add Patch boolean isInList = false; if(jTextField7.getText().isEmpty()) { jTextArea1.append("Please give a name for the patch.\n"); } else { for(patch p : patchList) { if(p.name.equals(jTextField7.getText())) { isInList = true; } } if(isInList) { jTextArea1.append("Patch name already assigned. Please pick a new name.\n"); } else { newPatch.gatherPatch(); jComboBox4.addItem(newPatch.name); patchList.add(newPatch); suppressUpdate = true; jComboBox4.setSelectedIndex(jComboBox4.getItemCount() - 1); } } }//GEN-LAST:event_jButton35ActionPerformed // User is attempting to delete the selected patch from the combo box. Fail if there's only one patch left. private void jButton36ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton36ActionPerformed int sel = jComboBox4.getSelectedIndex(); // Clicked Delete Patch if(sel == -1) { jTextArea1.append("Please select a patch to delete.\n"); } else { if(patchList.size() > 1) { patchList.remove(sel); suppressUpdate = false; jComboBox4.removeItemAt(sel); } else { jTextArea1.append("Deleting all patches will cause a system error. Please append at least one new patch first."); } } }//GEN-LAST:event_jButton36ActionPerformed // User entered the patch name in the jTextField7 component. Treat it as if they clicked the Add Patch button. private void jTextField7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField7ActionPerformed jButton35.doClick(); // Pressing Enter in Patch Name field is same as Add Patch }//GEN-LAST:event_jTextField7ActionPerformed // User selected a patch from the combo box. Load it and update all the buttons. private void jComboBox4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox4ActionPerformed int sel = jComboBox4.getSelectedIndex(); // Select a patch to load if(suppressUpdate) { // Because Add and Delete Patch select a new patch in the suppressUpdate = false; // Combo Box, the Combo Box will try loading the } else { // Patch as Select Patch. Suppress this loading. patchList.get(sel).loadPatch(); jTextArea1.append("Patch " + patchList.get(sel).name + " loaded.\n"); jTextField7.setText(patchList.get(sel).name); } }//GEN-LAST:event_jComboBox4ActionPerformed // My original plan was to allow the user to turn on the K-Pro after starting the app, and then using the Find K-Pro option // from the menu to see if the K-Pro driver was running yet. However, the System object doesn't seem to be refreshing // properly. According to the Java forums, refresh defaults to every 60 seconds, although it's possible to set it shorter. // But,after 5 minutes, System still hadn't refreshed and the K-Pro driver wasn't in the MIDI information list. So I deactivated // this option. private void jMenuItem12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem12ActionPerformed boolean quit = false; // Menu -> Edit -> Retry K-Pro Read int cntr = 1; jTextArea1.append("-------------------\n"); while(! quit) { initMidiDevices(); jTextArea1.append("------------------- Attempt No.: " + cntr + "\n"); cntr++; if(kProDevice != null) { quit = true; } else { int n = JOptionPane.showConfirmDialog(this, "K-Pro still not found.\nTry again?", "Find K-Pro", JOptionPane.YES_NO_OPTION); if(n == JFileChooser.CANCEL_OPTION) { quit = true; } } } }//GEN-LAST:event_jMenuItem12ActionPerformed // User selected to save the patch objects to a file. private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed savePatchFile(lastSavedPatchFile); // Menu -> File -> Save Patch File }//GEN-LAST:event_jMenuItem3ActionPerformed // User wants to read the patch objects from a file. Simultaneously, load the associated gate arpeggiator patterns // file associated with the first patch in the list. This is buggy, I know. There's a good chance that the user may // save the patterns to another file, adding or deleting them, and the patches won't have the correct pattern file loaded. // I have to figure out how to address this some day. private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed patch p; // Read Patch file JFileChooser fileRead = new JFileChooser(); FileFilter ft = new FileNameExtensionFilter("Patch Patterns", "ptc"); fileRead.setFileFilter(ft); int userChoice = fileRead.showOpenDialog(this); if(userChoice == JFileChooser.APPROVE_OPTION) { try { BufferedReader reader = new BufferedReader(new FileReader(fileRead.getSelectedFile())); String line = ""; while((line = reader.readLine()) != null) { if(! line.isEmpty()) { p = new patch(); p.parseFromFile(line); patchList.add(p); } lastSavedPatchFile = fileRead.getSelectedFile().getPath(); } } catch (Exception ex) { jTextArea1.append("\nCouldn't open |" + fileRead.getSelectedFile() + "|.\n"); jTextArea1.append(ex.toString()); } File f = new File(patchList.get(0).arpPatternFile); // Read the arp patterns and pre-load the combo box. readArpPatFile(f); String s = ""; // Add patches to combo box for(patch patch1 : patchList) { s = patch1.name; jComboBox4.addItem(s); } jComboBox4.setSelectedIndex(0); // Pre-select patch 0 just to be on the safe side. } }//GEN-LAST:event_jMenuItem2ActionPerformed // User selected SaveAs Patch file from the menu bar. private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem4ActionPerformed savePatchFile(""); // File -> Menu -> SaveAs Patch File }//GEN-LAST:event_jMenuItem4ActionPerformed // -<><><><><><>- End of my code. Everything else is Netbeans-generated. -<><><><><><>- /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ // /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(kproUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(kproUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(kproUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(kproUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new kproUI().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jButton1; private javax.swing.JButton jButton10; private javax.swing.JButton jButton11; private javax.swing.JButton jButton12; private javax.swing.JButton jButton13; private javax.swing.JButton jButton14; private javax.swing.JButton jButton15; private javax.swing.JButton jButton16; private javax.swing.JButton jButton17; private javax.swing.JButton jButton18; private javax.swing.JButton jButton19; private javax.swing.JButton jButton2; private javax.swing.JButton jButton20; private javax.swing.JButton jButton21; private javax.swing.JButton jButton22; private javax.swing.JButton jButton23; private javax.swing.JButton jButton24; private javax.swing.JButton jButton25; private javax.swing.JButton jButton26; private javax.swing.JButton jButton27; private javax.swing.JButton jButton28; private javax.swing.JButton jButton29; private javax.swing.JButton jButton3; private javax.swing.JButton jButton30; private javax.swing.JButton jButton31; private javax.swing.JButton jButton32; private javax.swing.JButton jButton33; private javax.swing.JButton jButton34; private javax.swing.JButton jButton35; private javax.swing.JButton jButton36; private javax.swing.JButton jButton4; private javax.swing.JButton jButton5; private javax.swing.JButton jButton6; private javax.swing.JButton jButton7; private javax.swing.JButton jButton8; private javax.swing.JButton jButton9; private javax.swing.JComboBox jComboBox1; private javax.swing.JComboBox jComboBox2; private javax.swing.JComboBox jComboBox3; private javax.swing.JComboBox jComboBox4; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JLabel jLabel7; private javax.swing.JLabel jLabel8; private javax.swing.JLabel jLabel9; private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu2; private javax.swing.JMenu jMenu3; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JMenuItem jMenuItem1; private javax.swing.JMenuItem jMenuItem10; private javax.swing.JMenuItem jMenuItem11; private javax.swing.JMenuItem jMenuItem12; private javax.swing.JMenuItem jMenuItem2; private javax.swing.JMenuItem jMenuItem3; private javax.swing.JMenuItem jMenuItem4; private javax.swing.JMenuItem jMenuItem5; private javax.swing.JMenuItem jMenuItem6; private javax.swing.JMenuItem jMenuItem7; private javax.swing.JMenuItem jMenuItem8; private javax.swing.JMenuItem jMenuItem9; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel5; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSlider jSlider1; private javax.swing.JSlider jSlider2; private javax.swing.JSlider jSlider3; private javax.swing.JTextArea jTextArea1; private javax.swing.JTextField jTextField1; private javax.swing.JTextField jTextField2; private javax.swing.JTextField jTextField3; private javax.swing.JTextField jTextField4; private javax.swing.JTextField jTextField5; private javax.swing.JTextField jTextField6; private javax.swing.JTextField jTextField7; // End of variables declaration//GEN-END:variables }