第13章-Swing(2)--BeatBox-总结与实例

来源:互联网 发布:大数据平滑处理 编辑:程序博客网 时间:2024/06/11 18:28

2015/6/22

源码:

package BeatBox;import java.awt.*;import javax.swing.*;import java.util.*;import java.awt.event.*;import javax.sound.midi.*;public class BeatBox {JPanel mainPanel;//把checkbox储存咋ArrayList中ArrayList<JCheckBox> checkboxList;Sequencer sequencer;Sequence sequence;Track track;JFrame frame;//乐器的名称String[] instrumentNames={"Bass Drum","Closed Hi-Hat","Open Hi-Hat","Acoustic Snare","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 BeatBox().buildGUI();}public void buildGUI(){frame=new JFrame("Cyber BeatBox");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//将background的布局改为BorderLayoutBorderLayout layout=new BorderLayout();JPanel background=new JPanel(layout);//设定面板上摆设组件式的空白边缘background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));checkboxList=new ArrayList<JCheckBox>();//Box类,是一种不可见组件,Box 用来提供使用 BoxLayout的容器//BoxLayout.Y_AXIS表示垂直排列//用来储存按钮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);frame.getContentPane().add(background);//GridLayout是表格布局,设定行数和列数,按顺序将组件添加到每个格子中GridLayout grid=new GridLayout(16,16);//表格布局中的水平间隙和垂直间隙grid.setVgap(1);grid.setHgap(2);//将mainPanel设定为表格布局mainPanel=new JPanel(grid);background.add(BorderLayout.CENTER,mainPanel);//创建CheckBox,设定为false并加到ArrayList和面板上for(int i=0;i<256;i++){JCheckBox c=new JCheckBox();c.setSelected(false);checkboxList.add(c);mainPanel.add(c);}setUpMidi();frame.setBounds(50,50,300,300);/**Pack()方法的作用:调整此窗口的大小,以适合其子组件的首选大小和布局。如果该窗口和/或其所有者还不可显示,则在计算首选大小之前都将变得可显示。在计算首选大小之后,将会验证该窗口。 */frame.pack();frame.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 e){e.printStackTrace();}}//核心代码,创建出16个元素的数组来储存一项乐器的值,如果该乐器应该要演奏,其值会是关键字值,否则值为零。public void buildTrackAndStart(){int[] trackList=null;//清除之前的track,之后建一个新的sequence.deleteTrack(track);track=sequence.createTrack();//对每个乐器都执行一次for(int i=0;i<16;i++){trackList=new int[16];//设定代表乐器的关键字int key=instruments[i];for(int j=0;j<16;j++){//每个拍子运行一次//取得每一个CheckBoxJCheckBox jc=(JCheckBox)checkboxList.get(j+(16*i));if(jc.isSelected()){trackList[j]=key;}else{trackList[j]=0;}}//创建此乐器的事件,并且加到track上makeTracks(trackList);/*插入编号为176的类型,它不会做任何事情,只是用来判别音符是 否被播放, * 它与144(开始发声)类型是同时进行的*/ track.add(makeEvent(176,1,127,0,16));}//确保第16拍有事件,否则不会重复播放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 class MyStartListener implements ActionListener{public void actionPerformed(ActionEvent e) {buildTrackAndStart();}}public class MyStopListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {// TODO 自动生成的方法存根sequencer.stop();}}public class MyUpTempoListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {// TODO 自动生成的方法存根float tempoFactor=sequencer.getTempoFactor();sequencer.setTempoFactor((float)(tempoFactor*1.03));}}public class MydownTempoListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {// TODO 自动生成的方法存根float tempoFactor=sequencer.getTempoFactor();sequencer.setTempoFactor((float)(tempoFactor*0.97));}}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++));}}}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 e){e.printStackTrace();}return event;}}


0 0