/* A HashMap is like an ArrayList except you get to store a key/velue pair. This is used to store the incoming messages from the server. The key is the String message from the server. The value is the pattern associated with that message. */
new BeatBoxFinal().startUp((args.length == 0)? "standard" : args[0]); }
public void startUp(String name) { userName = name; // Open connection to the server try { /* Make a Socket connection to the server. 4242 is the port number. 127.0.0.1 is the IP address for "localhost". This can be changed in order to run the programs from different machines. */
Socket sock = new Socket("127.0.0.1", 4242); out = new ObjectOutputStream(sock.getOutputStream()); in = new ObjectInputStream(sock.getInputStream());
Thread remote = new Thread(new RemoteReader()); remote.start(); }
catch(Exception ex) { System.out.println("Couldn't connect - you'll have to play alone"); }
setUpMidi(); buildGUI(); }
public void buildGUI() { theFrame = new JFrame("Cyber BeatBox"); BorderLayout layout = new BorderLayout(); JPanel background = new JPanel(layout); background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
checkboxList = new ArrayList();
Box buttonBox = new Box(BoxLayout.Y_AXIS);
submitMessage = new JButton("Submit message"); submitMessage.addActionListener(new MySubmitMessageListener()); buttonBox.add(submitMessage);
// message = new JTextField(); // buttonBox.add(message);
chatArea = new JTextArea(); buttonBox.add(chatArea);
/* Create buttons and checkboxes. Add the buttons to the GUI and add ActionListeners to them. Instead of passing (this) to the buttons ActionListener registration method, pass a new instance of the appropiate listener class.
The BoxLayout constructor needs to know the component its laying out and the axis - the buttonBox and y axis. */
JButton start = new JButton("Start"); start.addActionListener(new MyStartListener()); buttonBox.add(start);
JButton stop = new JButton("Stop"); stop.addActionListener(new MyStopListener()); buttonBox.add(stop);
JButton upTempo = new JButton("Tempo up"); upTempo.addActionListener(new MyUpTempoListener()); buttonBox.add(upTempo);
JButton downTempo = new JButton("Tempo down"); downTempo.addActionListener(new MyDownTempoListener()); buttonBox.add(downTempo);
JButton sendIt = new JButton("Send it"); sendIt.addActionListener(new MySendListener()); buttonBox.add(sendIt);
userMessage = new JTextField(); buttonBox.add(userMessage);
incomingList = new JList(); incomingList.addListSelectionListener(new MyListSelectionListener()); incomingList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane theList = new JScrollPane(incomingList); buttonBox.add(theList); incomingList.setListData(listVector);
Box nameBox = new Box(BoxLayout.Y_AXIS);
for(int i = 0; i < 5; i++) { nameBox.add(new Label(instrumentNames)); }
public void setUpMidi() { try { // Get the sequencer, make a sequence and make a track
/* The sequencer object is the main part of the MIDI device/instrument being used. It's the thing that "sequences" all the MIDI information into a song. */
public void buildTrackAndStart() { /* Build a track by walking through the checkboxes to get their state, and mapping that to an instrument (and making the MidiEvent for it). */
/* Implement the ActionListener interfaces ActionPerformed() method. This is the event-handling method. */
public class MyStartListener implements ActionListener { public void actionPerformed(ActionEvent a) { buildTrackAndStart(); } }
public class MyStopListener implements ActionListener { public void actionPerformed(ActionEvent a) { sequencer.stop(); } }
public class MyUpTempoListener implements ActionListener { public void actionPerformed(ActionEvent a) { bpm += 3; } }
public class MyDownTempoListener implements ActionListener { public void actionPerformed(ActionEvent a) { bpm -= 3; } }
public class MySubmitMessageListener implements ActionListener { public void actionPerformed(ActionEvent a) { if(a.getSource() == submitMessage) { System.out.println("Message submitted"); chatArea.setText(userMessage.getText()); } } }
public class MySendListener implements ActionListener { public void actionPerformed(ActionEvent a) { // Make an arrayList of just the STATE of the checkboxes boolean[] checkboxState = new boolean[50]; for(int i = 0; i < 50; i++) { JCheckBox check = (JCheckBox) checkboxList.get(i); if(check.isSelected()) { checkboxState = true; } }
/* Serialize two objects (the String message and the beat pattern) and write those two objects to the socket output stream to the server */
String messageToSend = null;
try { out.writeObject(userName + nextNum++ + ": " + userMessage.getText()); out.writeObject(checkboxState); } catch(Exception ex) { System.out.println("Sorry! Could not sent it to the server!"); }
userMessage.setText(""); } }
/* ListSelectionListener tells is when the user made a selection on the list of messages. When the user selects a message, we immediately load the associated beat pattern and start playing it. */
/* This is the thread work - reading in data from the server. The data in this program will always be the two serialized objects: the String message and the beat pattern - an ArrayList of cjeckbox state values.
When a message comes in, we read or deserialize the two objects (the message and the ArrayList of Boolean checkbox state values) and add it to the JList component.
Adding to a JList is two-step process: you keep a Vector of the lists data and then tell the JList to use that Vector as it's source for what to display in the list. */
/* This method is called when the user selects something from the list. The pattern is immediately changed to the one the user selected. */
public void changeSequence(boolean[] checkboxState) { for(int i = 0; i < 50; i++) { JCheckBox check = (JCheckBox) checkboxList.get(i); check.setSelected(checkboxState); } }
public void makeTracks(ArrayList list) { Iterator it = list.iterator(); // Detect which key was pressed for(int i = 0; i < 5; i++) { Integer num = (Integer) it.next(); if(num != null) { int numKey = num.intValue(); // This is where the beat is picked up from. track.add(makeEvent(144, 9, numKey, 100, i)); track.add(makeEvent(128, 9, numKey, 100, i + 1)); } } }
// Add the four arguments for the message
public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) { MidiEvent event = null; try { // Make the message and the event, using the parameters // Make a message instance ShortMessage a = new ShortMessage(); // Call setMessage() with the instructions a.setMessage(comd, chan, one, two); // Make a MidiEvent instance for the message event = new MidiEvent(a, tick); } catch(Exception e) { }