Swing运用:音乐播放器

16×16的乐器组合,可勾选不同组合播放乐音。
勾选后按下start键即可循环播放,按下stop键即可停止;

package a新音乐播放器;

import javax.sound.midi.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

public class BeatBox {
     
    JPanel mainPanel;
    //把checkbox存储在ArrayList中
    ArrayList<JCheckBox> checkboxList;

    Sequencer sequencer;
    Sequence sequence;
    Track track;
    JFrame theFrame;
    //设置乐器名称
    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"};
    //乐器在Java中对应的关键字
    int[] instruments = {
     35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
    //main()函数
    public static void main(String[] args) {
     
        new BeatBox().buildGUI();
    }
    //创建GUI
    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);//用BoxLayout进行布局

        //start按钮,开始循环播放
        JButton start = new JButton("Start");
        start.addActionListener(new MyStartListener());
        buttonBox.add(start);

        //stop按钮,停止播放
        JButton stop = new JButton("Stop");
        stop.addActionListener(new MyStopListener());
        buttonBox.add(stop);

        //调高节奏
        JButton upTempo = new JButton("Tempo Up");
        stop.addActionListener(new MyUpTempoListener());
        buttonBox.add(upTempo);

        //调低节奏
        JButton downTempo = new JButton("Tempo Down");
        downTempo.addActionListener(new MyDownTempoListener());
        buttonBox.add(downTempo);

        //将乐器名字按照BoxLayout进行排列
        Box nameBox = new Box(BoxLayout.Y_AXIS);
        for(int i=0;i<16;i++)
        {
     
            nameBox.add(new Label(instrumentNames[i]));
        }

        //将4个按钮设置在背景的右边,将乐器名字设置在左边
        background.add(BorderLayout.EAST,buttonBox);
        background.add(BorderLayout.WEST,nameBox);

        //把设置好的背景添加到JFrame对象中
        theFrame.getContentPane().add(background);

        //按GridLayout的排列方式设置16*16的格子
        GridLayout grid = new GridLayout(16,16);
        grid.setVgap(1);//设置垂直间距
        grid.setHgap(2);//设置水平间距
        //将16*16的勾选格加到背景中
        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();

        //基操
        theFrame.setBounds(50,50,300,300);
        theFrame.pack();
        theFrame.setVisible(true);
    }

    //setUPMidi()方法是一般的Midi设置程序代码
    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(){
     
        int[] trackList =null;//储存乐器值

        //消掉旧的track并创建一个新的
        sequence.deleteTrack(track);
        track = sequence.createTrack();

        //对16个乐器都执行一遍
        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));
                //如果勾选了,就加到数组中,否则补0
                if(jc.isSelected()){
     
                    trackList[j] = key;
                }else{
     
                    trackList[j] = 0;
                }

            }
            //创建乐器事件并加到track中
            makeTracks(trackList);
            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();
        }
    }
    
    //四个内部类,分别实现4个按钮的接听
    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* 1.03));
        }
    }
    public class MyDownTempoListener implements ActionListener{
     
        public void actionPerformed(ActionEvent a){
     
            float tempoFactor = sequencer.getTempoFactor();
            sequencer.setTempoFactor((float)(tempoFactor* .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+1));
            }
        }
    }
    //1-4个参数是给信息用的,tick是何时播放信息
    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;
    }
    public class MyReadInListener implements ActionListener{
     
        public void actionPerformed(ActionEvent a){
     
            boolean[] checkboxState = null;
            try{
     
                FileInputStream fileIn = new FileInputStream(new File("Checkbox.ser"));
                ObjectInputStream is =new ObjectInputStream(fileIn);
                checkboxState = (boolean[])is.readObject();
            }catch (Exception e){
     
                e.printStackTrace();
            }
            for(int i=0;i<256;i++)
            {
     
                JCheckBox check = (JCheckBox) checkboxList.get(i);
                if(checkboxState[i]){
     
                    check.setSelected(true);
                }else{
     
                    check.setSelected(false);
                }
            }
            sequencer.stop();
            buildTrackAndStart();
        }
    }


}

Swing运用:音乐播放器_第1张图片

你可能感兴趣的:(Java学习笔记,java,swing)