BeatBox终极版——Head first java 650

服务端

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);
        }
    }

}

你可能感兴趣的:(BeatBox终极版——Head first java 650)