Head_First_Java之BeatBox.java

import javax.swing.*;
import java.awt.*;
import javax.sound.midi.*;
import java.util.*;//ArrayList
import java.awt.event.*;

public class BeatBox {
	JPanel mainPanel;
	ArrayList
   
   
    
     checkboxList;//把checkbox存储在ArrayList中
	Sequencer sequencer;
	Sequence sequence;
	Track track;
	JFrame theFrame;
	
	String[] instrumentNames={"Bass Drum","Close Hi-Hat","Open Hi-Hat","Acounstic snare","Crash Cymbal","Hand Clap",
			"High Tom","Hi Bongo","Maracas","Whistle","Low conga","Cowbell","Vibraslap","Low-mid Tom","High Agogo","Open Hi Conga"};
	//乐器的名称,以String的array维护
	int[] instruments={35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
	//实际的乐器关键字,例如说35就代表Bass Drum
	
	public static void main(String[] args){
		BeatBox beatBox=new BeatBox();
		beatBox.buildGUI();
	}
	
	public void buildGUI(){
		theFrame=new JFrame("Cyber BeatBox");
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel background=new JPanel(new BorderLayout());//JPanel面板需要添加BorderLayout布局管理器
		background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));//设置面板上摆设组件时的空白边缘
		
		
		checkboxList=new ArrayList
    
    
     
     ();
		Box buttonBox=new Box(BoxLayout.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);
		
		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);
		
		
		
		GridLayout grid=new GridLayout(16,16);//布局管理器之网格布局GridLayout (16*16的网格分布)
		grid.setVgap(1);//设置垂直间距
		grid.setHgap(5);//设置水平间距
		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);          //从左至右,从上至下
		}
		setUpMidi();
		
		theFrame.getContentPane().add(background);
		//theFrame.setBounds(50,50,100,100);
		theFrame.pack();//若是已定义的setBound()范围太小,窗口自动调整
		theFrame.setVisible(true);
	}
		
		public void setUpMidi(){  //midi音频
			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(){
			int[] trackList=null;
			
		sequence.deleteTrack(track);
		track=sequence.createTrack();//清除旧的track,重建一个新的
		
		for(int i=0;i<16;i++){
			trackList=new int[16];
			
			int key=instruments[i];  //设定代表乐器的关键字
			
			for(int j=0;j<16;j++){
				
				JCheckBox jc=(JCheckBox) checkboxList.get(j+(16*i));
				if(jc.isSelected()){   //判断选取的状态
					trackList[j]=key;
				}else{
					trackList[j]=0;
				}
			}
			
			makeTracks(trackList);					
			//track.add(makeEvent(176,1,127,0,16));//不会做任何事情,只是让我们知道有音符在播放
		}
		
		track.add(makeEvent(192,9,1,0,15));//确拍保第16拍有事件,否则BeatBox不会重复播放
		try{
			sequencer.setSequence(sequence);
			sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);//指定无穷的重复次数
			sequencer.start();
			sequencer.setTempoInBPM(120);
		}catch(Exception e){e.printStackTrace();}
	}
	
	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){
			float tempoFactor=sequencer.getTempoFactor();
			sequencer.setTempoFactor((float)(tempoFactor*2));//节奏速度
		}
	}
	public class MyDownTempoListener implements ActionListener{
		public void actionPerformed(ActionEvent a){
			float tempoFactor=sequencer.getTempoFactor();
			sequencer.setTempoFactor((float)(tempoFactor*0.5));
		}
	}
	
	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 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);//tick表示拍
		}catch(Exception e){e.printStackTrace();}
		return event;
	  }

}


    
    
   
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值