Java: BeatBox 网络版

这是一个基于HeadFirstJava中的BeatBox改进版程序,通过调用midi发出声音,并具备网络功能,允许不同客户端共享创作。用户可以创建、保存及加载自己的音乐作品。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

气死我了, 在此之前写了两个多小时的Ruby学习记录居然,没有提交上,丢了!

修改了一个BeatBox的网络版本, 觉得有点儿意思
可以保存并载入自己普的曲目
这个程序是通过调用midi发出声音的
而且做了网络功能来使得不同的客户端共享自己的创作.
Enjoy!

是HeadFirst Java中的BeatBox 的改进版

package practice;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class BeatBox {
    
private JPanel mainPanel;
    
private ArrayList<JCheckBox> checkBoxList;
    
private JFrame frame;
    
private File file;
    
    
private MidiPlayer midiPlayer;
    
    
private JButton sendButton;
    
private JButton start;
    
private JButton stop;
    
private JButton tempoUp;
    
private JButton tempoDown;
    
private JButton randomButton;
    
private JList incomingList;
    
private JTextField userMessage;
    
    
private Socket socket;
    
    
private ObjectOutputStream writer;
    
private ObjectInputStream reader;
    
    
private Vector<String> receivedKeyList = new Vector<String>();
    
private HashMap<String, boolean[]> receivedPlayList = new HashMap<String, boolean[]>();
    
    
private String[] instrumentNames = {"Bass Drum""Closed Hi-Hat"
            
"Open Hi-Hat""Acousetic Snare""Crash Symble""Hand Clap"
            
"High Tom""Hi Bongo""Maracas""Whistle""Low conga"
            
"Cow Bell""Vibraslap""Low-mid Tom""High Agogo",
            
"Open Hi-Congo"}
;
    
    
private final int PORT=5000;
    
private String serverIp = "127.0.0.1";
    
    
public String getServerIp() {
        
return serverIp;
    }


    
public void setServerIp(String serverIp) {
        
this.serverIp = serverIp;
    }


    
public static void main(String[] args){
        BeatBox beatBox 
= new BeatBox();
        
        beatBox.buildGUI();
        
        beatBox.initMidiSystem();    
        
        
if(beatBox.setupSocketAndStream()){
            beatBox.createLisnenerThread();
            beatBox.enableSend();
        }

    }

    
    
private void initMidiSystem(){
        
// setup midi
        midiPlayer = new MidiPlayer();
        midiPlayer.setUpMidi();
    }

    
    
private boolean setupSocketAndStream(){
        
try{
            socket 
= new Socket(serverIp,PORT);
            reader 
= new ObjectInputStream(socket.getInputStream());
            writer 
= new ObjectOutputStream(socket.getOutputStream());
            
return true;
        }
catch(Exception e){
            e.printStackTrace();
            System.out.println(
"couldn't connect to server,you have to play alone.");
            
return false;
        }

    }

    
    
private void createLisnenerThread(){
        Thread remote 
= new Thread(new RemoteReader());
        remote.setName(
"reader");
        remote.start();
    }

    
    
class RemoteReader implements Runnable{
        
public void run(){
            BeatBoxSendingData data 
= null;
            
try{
                
while((data = (BeatBoxSendingData)reader.readObject())!=null){
                    
                    receivedPlayList.put(data.getName(), data.getBeatList());
                    receivedKeyList.add(data.getName());
                    incomingList.setListData(receivedKeyList);
                }

            }
catch(Exception e){
                e.printStackTrace();
                System.out.print(
"Maybe Server is closeed.");
            }

        }

    }

    
    
private void enableSend(){
        sendButton.setEnabled(
true);
    }

    
    
private void buildGUI(){
        frame 
= new JFrame("Cyber BeatBox");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        BorderLayout layout 
= new BorderLayout();
        JPanel background 
= new JPanel(layout);
        background.setBorder(BorderFactory.createEmptyBorder(
10101010));
        
        
// create button
        Box buttonBox = new Box(BoxLayout.Y_AXIS);
        
        start 
= new JButton("Start");
        start.addActionListener(
new MyStartActionListener());
        buttonBox.add(start);
        
        stop 
= new JButton("Stop");
        stop.addActionListener(
new MyStopActionListener());
        buttonBox.add(stop);
        
        tempoUp 
= new JButton("Tempo Up");
        tempoUp.addActionListener(
new MyTempoUpActionListener());
        buttonBox.add(tempoUp);
        
        tempoDown 
= new JButton("Tempo Down");
        tempoDown.addActionListener(
new MyTempoDownActionListener());
        buttonBox.add(tempoDown);
        
        randomButton 
= new JButton("Random Create Music");
        randomButton.addActionListener(
new MyRandomActionListener());
        buttonBox.add(randomButton);
        
        JButton saveButton 
= new JButton("Save");
        saveButton.addActionListener(
new MySaveActionListener());
        buttonBox.add(saveButton);
        
        JButton loadButton 
= new JButton("Load");
        loadButton.addActionListener(
new MyLoadActionListener());
        buttonBox.add(loadButton);
        
        sendButton 
= new JButton("Send");
        sendButton.addActionListener(
new MySendActionListener());
        sendButton.setEnabled(
false);
        buttonBox.add(sendButton);
        
        userMessage 
= new JTextField();
        buttonBox.add(userMessage);
        
        incomingList 
= new JList();
        incomingList.addListSelectionListener(
new MyListSelectionListener());
        incomingList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane scroller 
= new JScrollPane(incomingList);
        buttonBox.add(scroller);
        incomingList.setListData(receivedKeyList);
        
        
// create instruction
        Box nameBox = new Box(BoxLayout.Y_AXIS);
        Font font 
= new Font("Arial", Font.PLAIN, 18);
        JLabel label 
= null;
        
for(int i=0; i<16; i++){
            label 
= new JLabel(instrumentNames[i]);
            label.setFont(font);
            nameBox.add(label);
        }

        
        
// create checkbox
        checkBoxList = new ArrayList<JCheckBox>();
        GridLayout grid 
= new GridLayout(1616);
        grid.setHgap(
2);
        grid.setVgap(
1);
        mainPanel 
= new JPanel(grid);
        
for(int i=0;i<256;i++){
            JCheckBox c 
= new JCheckBox();
            c.setSelected(
false);
            mainPanel.add(c);
            checkBoxList.add(c);
        }
// close loop
        
        
// add three parts
        background.add(BorderLayout.EAST, buttonBox);
        background.add(BorderLayout.WEST, nameBox);
        background.add(BorderLayout.CENTER, mainPanel);
        
        frame.getContentPane().add(background);
        frame.setBounds(
50,50,300,300);
        frame.pack();
        frame.setVisible(
true);
        
        makeStopingGUI();
    }
// close method
    
    
private void makeStopingGUI(){
        start.setEnabled(
true);
        stop.setEnabled(
false);
        tempoUp.setEnabled(
false);
        tempoDown.setEnabled(
false);
    }

    
    
private void makeRunningGUI(){
        start.setEnabled(
false);
        stop.setEnabled(
true);
        tempoUp.setEnabled(
true);
        tempoDown.setEnabled(
true);
    }

    
    
class MyStartActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            midiPlayer.buildTrackAndStart(checkBoxList);
            makeRunningGUI();
        }

    }

    
    
class MyStopActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            midiPlayer.stop();
            makeStopingGUI();
        }

    }

    
    
class MyTempoUpActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            midiPlayer.setTempoFactor((
float)(midiPlayer.getTempoFactor()*1.03));
        }

    }

    
class MyTempoDownActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            midiPlayer.setTempoFactor((
float)(midiPlayer.getTempoFactor()*0.97));
        }

    }

    
class MyRandomActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            updateGUI(getRandomMusicList());
        }

    }

    
    
private boolean[] getRandomMusicList(){
        
boolean[] list = new boolean[256];
        
int count = (int)(Math.random()*96);
        
for(int i=0; i< count; i++){
            list[(
int)(Math.random()*256)] = true;
        }

        
return list; 
    }

    
    
class MySaveActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            
boolean[] checkBoxState = getStateList();
            file 
= getFile2Save();
            
if(file == null){
                
return;
            }

            serializeState(checkBoxState);
        }

    }

    
    
private boolean[] getStateList(){
        
boolean[] checkBoxState = new boolean[256];
        
for(int i=0; i<256; i++){
            
if(checkBoxList.get(i).isSelected()){
                checkBoxState[i] 
= true;
            }

        }

        
return checkBoxState;
    }

    
    
private File getFile2Save(){
        JFileChooser chooser 
= new JFileChooser(file);
        chooser.showSaveDialog(frame);
        
return chooser.getSelectedFile();
    }

    
    
private void serializeState(boolean[] checkBoxState){
        
try{
            ObjectOutputStream objectOutputStream 
= new ObjectOutputStream(new FileOutputStream(file));
            objectOutputStream.writeObject(checkBoxState);
            objectOutputStream.close();
        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
    
class MyLoadActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            file 
= getSavedFile();
            
if(file == null){
                
return;
            }

            
boolean[] checkBoxState = loadFile2List();
            updateGUI(checkBoxState);
        }

    }

    
    
private File getSavedFile(){
        JFileChooser chooser 
= new JFileChooser(file);
        chooser.showOpenDialog(frame);
        
return chooser.getSelectedFile();
    }

    
    
private boolean[] loadFile2List(){
        
boolean[] state = new boolean[256];
        
try{
            ObjectInputStream objectInputStream 
= new ObjectInputStream(new FileInputStream(file));
            state 
= (boolean[])objectInputStream.readObject();
            objectInputStream.close();
        }
catch(Exception e){
            e.printStackTrace();
        }

        
return state; 
    }

    
    
private void updateGUI(boolean[] checkBoxState){
        
for(int i=0; i<256; i++){
            checkBoxList.get(i).setSelected(checkBoxState[i]);
        }

    }

    
    
class MySendActionListener implements ActionListener{
        
public void actionPerformed(ActionEvent event){
            
try{
                writer.writeObject(
new BeatBoxSendingData(userMessage.getText(), getStateList()));
                userMessage.setText(
"");
            }
catch(Exception e){
                e.printStackTrace();
                System.out.println(
"maybe connection crashed!");
            }

            
        }

    }

    
    
class MyListSelectionListener implements ListSelectionListener{
        
public void valueChanged(ListSelectionEvent event){
            
if(event.getValueIsAdjusting()){
                String selection 
= (String)incomingList.getSelectedValue();
                
if(selection != null){
                    updateGUI(receivedPlayList.get(selection));
                    midiPlayer.stop();
                    midiPlayer.buildTrackAndStart(checkBoxList);
                    makeRunningGUI();
                }

            }

        }

    }

}
package practice;

import java.util.ArrayList;

import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.swing.JCheckBox;

public class MidiPlayer {
    
private Sequencer sequencer;
    
private Sequence sequence;
    
private Track track;
    
private int[] instrument = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
    
    
public void setUpMidi(){
        
try{
            sequencer 
= MidiSystem.getSequencer();
            sequencer.open();
            sequence 
= new Sequence(Sequence.PPQ, 4);
            track 
= sequence.createTrack();
            sequencer.setTempoInBPM(
120);
            
        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
    
public void buildTrackAndStart(ArrayList<JCheckBox> checkBoxList){
        
int[] trackList = null;
        sequence.deleteTrack(track);
        track 
= sequence.createTrack();
        
        
for(int i=0; i<16; i++){
            trackList 
= new int[16];
            
int key = instrument[i];
            
for(int j=0;j<16;j++){
                JCheckBox jc 
= checkBoxList.get(i*16+j);
                
if(jc.isSelected()){
                    trackList[j] 
= key;
                }
else{
                    trackList[j] 
= 0;
                }

            }
// close inner loop
            
            makeTracks(trackList);
            track.add(makeEvent(
176,1,127,0,16));
        }
// close outer loop
        
        track.add(makeEvent(
192,9,1,0,15));
        
        
try{
            sequencer.setSequence(sequence);
            sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
            sequencer.start();
            sequencer.setTempoInBPM(
120);
        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
    
public void makeTracks(int[] list){
        
for(int i=0; i<16; i++){
            
int key = list[i];
            
if(key != 0){
                track.add(makeEvent(
144,9,key,100,i));
                track.add(makeEvent(
128,9,key,100,i+1));
            }

        }

    }

    
    
public MidiEvent makeEvent(int command, int chanel, int one, int two, int ticks){
        MidiEvent event 
= null;
        
try{
            ShortMessage a 
= new ShortMessage();
            a.setMessage(command, chanel, one, two);
            event 
= new MidiEvent(a, ticks);
        }
catch(Exception e){
            e.printStackTrace();
        }

        
return event;
    }

    
    
public void stop(){
        sequencer.stop();
    }

    
    
public double getTempoFactor(){
        
return sequencer.getTempoFactor();
    }

    
    
public void setTempoFactor(float factor){
        sequencer.setTempoFactor(factor);
    }

    
    
public void start(){
        sequencer.start();
    }

}

package practice;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class MusicServer {
    
private ArrayList<MusicClientInfo> musicClientList;
    
private final int PORT=5000;
    
public static void main(String[] args){
        (
new MusicServer()).go();
    }

    
private void go(){
        musicClientList 
= new ArrayList<MusicClientInfo>();
        
try{
            ServerSocket serverSocket 
= new ServerSocket(PORT);
            
while(true){
                Socket socket 
= serverSocket.accept();
                MusicClientInfo client 
= new MusicClientInfo(socket);
                musicClientList.add(client);

                Thread thread 
= new Thread(new Runner(client));
                thread.start();
                
                System.out.println(
"Got a new connection from: " + client.getClientInfo());
            }

        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
    
class Runner implements Runnable{
        MusicClientInfo client;
        
public Runner(MusicClientInfo client){
            
this.client = client;
            
try{
                
this.client = client;
            }
catch(Exception e){
                e.printStackTrace();
            }

        }

        
public void run(){
            BeatBoxSendingData data 
= null;
            
try{
                
while((data = (BeatBoxSendingData)client.getReader().readObject()) != null){
                    System.out.println(
"Get data: " + data.getName() +" from " + client.getClientInfo());
                    tellEveryOne(data);
                }

            }
catch(Exception e){
                
//e.printStackTrace();
                System.out.println("Maybe this client off: " + client.getClientInfo());
                client.closeSocket();
                musicClientList.remove(client);
            }

        }

        
        
public void tellEveryOne(BeatBoxSendingData data){
            
try{
                
for(MusicClientInfo client : musicClientList){
                    client.getWriter().writeObject(data);
                }

            }
catch(Exception e){
                e.printStackTrace();
            }

        }

    }

}

package practice;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class MusicClientInfo {
    
private Socket socket;
    
private ObjectOutputStream writer;
    
private ObjectInputStream reader;
    
private String clientIp;
    
private int clientPort;
    
    
public MusicClientInfo(Socket socket){
        
this.socket = socket;
        clientIp 
= socket.getInetAddress().getHostAddress();
        clientPort 
= socket.getPort();
        
try{
            
/*must be first writer then reader*/
            writer 
= new ObjectOutputStream(socket.getOutputStream());
            reader 
= new ObjectInputStream(socket.getInputStream());
        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
public String getClientIp() {
        
return clientIp;
    }

    
public void setClientIp(String clientIp) {
        
this.clientIp = clientIp;
    }

    
public int getClientPort() {
        
return clientPort;
    }

    
public void setClientPort(int clientPort) {
        
this.clientPort = clientPort;
    }

    
public Socket getSocket() {
        
return socket;
    }

    
public void setSocket(Socket socket) {
        
this.socket = socket;
    }

    
public ObjectInputStream getReader() {
        
return reader;
    }

    
public void setReader(ObjectInputStream reader) {
        
this.reader = reader;
    }

    
public ObjectOutputStream getWriter() {
        
return writer;
    }

    
public void setWriter(ObjectOutputStream writer) {
        
this.writer = writer;
    }

    
public void closeSocket(){
        
try{
            reader.close();
            writer.close();
            socket.close();
        }
catch(Exception e){
            e.printStackTrace();
        }

    }

    
    
public String getClientInfo(){
        
return getClientIp() + ":" + getClientPort();
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值