服务端
import java.io.*;
import java.util.*;
import java.net.*;
public class MusicServer {
ArrayList<ObjectOutputStream> clientOutputStreams;
public static void main(String[] args) {
new MusicServer().go();
}
public class ClientHandler implements Runnable{
Socket clientSocket;
ObjectInputStream in;
public ClientHandler(Socket s){
try {
clientSocket = s;
in = new ObjectInputStream(clientSocket.getInputStream()); //getInputstream要抛出异常
}catch(Exception ex){
ex.printStackTrace();
}
}
public void run(){
Object o1 = null;
Object o2 = null;
try{
while((o1 = in.readObject()) != null){//readObject存在异常
o2 = in.readObject();
System.out.println("read two objects");
tellEveryone(o1,o2);
}
}catch(Exception ex){}
}
}//关闭内部类
public void go(){
clientOutputStreams = new ArrayList<ObjectOutputStream>(); //忘记new这个会导致抛出nullpoint异常
try{
ServerSocket serverSocket = new ServerSocket(5000); //监听4242端口(存在io异常)
while(true) {
Socket socket = serverSocket.accept(); //接受客户端的连接
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream()); //存在io异常
clientOutputStreams.add(os); //将客户端的输出流保存起来
Thread t = new Thread(new ClientHandler(socket));
t.start();
}
}catch(Exception ex){ex.printStackTrace();}
}
public void tellEveryone(Object o1,Object o2){
//利用迭代器和集合向所有客户端发送信息
Iterator it = clientOutputStreams.iterator();
while(it.hasNext()){
try{
ObjectOutputStream out = (ObjectOutputStream)it.next();
out.writeObject(o1); //io异常
out.writeObject(o2); //io异常
}catch(Exception ex){}
}
}
}
客户端
import java.awt.*;
import javax.swing.*;
import java.io.*;
import javax.sound.midi.*;
import java.util.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.event.*;
public class BeatBoxFinal {
JFrame theFrame;
JPanel mainPanel;
JList incomingList;
JTextField userMessage;
ArrayList<JCheckBox> checkBoxList; //存放256个勾选框
int nextNum;
Vector<String> listVector = new Vector<String>(); //动态数组存放读取到的音频的名字
String userName;
ObjectOutputStream out;
ObjectInputStream in;
HashMap<String, boolean[]> otherSeqsMap = new HashMap<String, boolean[]>(); //音频信息存储在map中根据key查询
Sequencer sequencer;
Sequence sequence;
Sequence mySequence = null;
Track track;
String[] instrumentNames = {"Bass Drum", "Closed Hi-Hat", "Open Hi-Hat", "Acoustic Share", "Crash Cymbal"
, "Hand Clap", "High Tom", "Hi Bongo", "Maracas", "Whistle", "Low Conga", "Cowbell", "Vibraslap", "Low-mid Tom",
"High Agogo", "Open Hi Conga"};
int[] instruments = {35, 42, 46, 38, 49, 39, 50, 60, 70, 72, 64, 56, 58, 47, 67, 63};
public static void main(String[] args) {
new BeatBoxFinal().startUp(args[0]);
}
public void startUp(String name) {
userName = name;
try {
Socket socket = new Socket("127.0.0.1", 5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.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");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout layout = new BorderLayout();
JPanel background = new JPanel(layout);
background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); //格组件的间距
checkBoxList = new ArrayList<JCheckBox>();
Box buttonBox = new Box(BoxLayout.Y_AXIS); //box布局的容器
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("sendIt");
sendIt.addActionListener(new MySendListener());
buttonBox.add(sendIt);
userMessage = new JTextField();
buttonBox.add(userMessage);
//收到信息后的List
incomingList = new JList();
incomingList.addListSelectionListener(new MyListSelectionListener());
incomingList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //限制用户只能选择一个
JScrollPane theList = new JScrollPane(incomingList); //滚轮中有一个list
buttonBox.add(theList);
incomingList.setListData(listVector); //从动态数组里获得信息
Box nameBox = new Box(BoxLayout.Y_AXIS);
for (int i = 0; i < 16; i++)
nameBox.add(new Label(instrumentNames[i]));
background.add(BorderLayout.EAST, buttonBox);
background.add(BorderLayout.WEST, nameBox);
theFrame.getContentPane().add(background);
GridLayout grid = new GridLayout(16, 16); //16x16组件格局
grid.setVgap(1); //组件竖直距离1
grid.setHgap(2); //横距为2
mainPanel = new JPanel(grid);
background.add(BorderLayout.CENTER, mainPanel);
for (int i = 0; i < 256; i++) {
JCheckBox c = new JCheckBox();
c.setSelected(false); //默认关闭
checkBoxList.add(c);
mainPanel.add(c);
}
theFrame.setBounds(50, 50, 300, 300);
theFrame.pack();
theFrame.setVisible(true);
}
public void setUpMidi() {
try {
sequencer = MidiSystem.getSequencer();
sequencer.open();
sequence = new Sequence(Sequence.PPQ, 4);
track = sequence.createTrack();
sequencer.setTempoInBPM(120);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void buildTrackAndStart() {
ArrayList<Integer> trackList = null;
sequence.deleteTrack(track);
track = sequence.createTrack(); //创造新的track
for (int i = 0; i < 16; i++) {
trackList = new ArrayList<Integer>();
for (int j = 0; j < 16; j++) {
JCheckBox jc = (JCheckBox) checkBoxList.get(i + j * 16);
if (jc.isSelected()) {
int key = instruments[i];
trackList.add(key);
} else {
trackList.add(null);
}
}
makeTracks(trackList);
}
track.add(makeEvent(192, 9, 1, 0, 15));
try {
sequencer.setSequence(sequence);
sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempoInBPM(120);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void makeTracks(ArrayList list){
Iterator it = list.iterator();
for(int i=0;i<16;i++){
Integer num = (Integer)it.next();
if(num != null){
int numKey = num.intValue();
track.add(makeEvent(144,9,numKey,100,i));
track.add(makeEvent(128,9,numKey,100,i+1));
}
}
}
public MidiEvent makeEvent(int comd,int chan,int one,int two,int tick){
MidiEvent event = null;
try{
ShortMessage a = new ShortMessage();
a.setMessage(comd,chan,one,two);
event = new MidiEvent(a,tick);
}catch(Exception ex){
ex.printStackTrace();
}
return event;
}
class MyStartListener implements ActionListener{
public void actionPerformed(ActionEvent a){
buildTrackAndStart();
}
}
class MyStopListener implements ActionListener{
public void actionPerformed(ActionEvent a){
sequencer.stop();
}
}
class MyUpTempoListener implements ActionListener{
public void actionPerformed(ActionEvent event){
float tempoFactor = sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*1.03));
}
}
class MyDownTempoListener implements ActionListener{
public void actionPerformed(ActionEvent event){
float tempoFactor = sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*0.97));
}
}
class MySendListener implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean[] checkboxState = new boolean[256];
for(int i=0;i<256;i++){
JCheckBox check = (JCheckBox)checkBoxList.get(i);
if(check.isSelected())
checkboxState[i] = true;
else
checkboxState[i] = false;
}
String messageToSend = null;
try{
out.writeObject(userName+nextNum+":"+userMessage.getText());
out.writeObject(checkboxState);
}catch(Exception ex){
System.out.println("Sorry dude.Could not send it to the server.");
}
userMessage.setText("");
}
}
class MyListSelectionListener implements ListSelectionListener{
public void valueChanged(ListSelectionEvent le){
if(!le.getValueIsAdjusting()){//为了不得到两次事件
String selected = (String)incomingList.getSelectedValue();
if(selected != null){
boolean[] selectedState = (boolean[])otherSeqsMap.get(selected);//根据key在map中寻到信息
changeSequence(selectedState);
sequencer.stop();
buildTrackAndStart();
}
}
}
}
//多线程随时接受服务器发来的信息
class RemoteReader implements Runnable{
boolean[] checkBoxState = null;
String nameToShow = null;
Object obj = null;
public void run(){
try {
while ((obj = in.readObject()) != null) {
System.out.println("got an object from server");
System.out.println(obj.getClass());
nameToShow = (String) obj;
checkBoxState = (boolean[]) in.readObject();
otherSeqsMap.put(nameToShow, checkBoxState); //放入map存储
listVector.add(nameToShow); //把key加入动态数组
incomingList.setListData(listVector); //重新设置list
}
}catch(Exception ex){}
}
}
class MyPlayMineListener implements ActionListener{
public void actionPerformed(ActionEvent event){
if(mySequence != null)
sequence = mySequence;
}
}
public void changeSequence(boolean[] checkboxState){
for(int i=0;i<256;i++){
JCheckBox checkBox = (JCheckBox)checkBoxList.get(i);
if(checkboxState[i])
checkBox.setSelected(true);
else
checkBox.setSelected(false);
}
}
}