读书笔记——《Head First Java》MIDI音乐播放器实例

来源:互联网 发布:seo外链资源 编辑:程序博客网 时间:2024/06/03 17:41

书的第十一章到十四章

以一个MIDI音乐播放器的例子

穿插了异常处理,图形用户接口,和文件输入输出流的知识


异常处理:

当你调用了有风险的方法时,需要用try/catch来处理

如果自己编写的程序中可能有风险,就要用throw来抛出异常,并且可以抛出多个

try中存放调用方法的语句,然后用catch块做异常处理/恢复程序

有多个catch时,要从继承最底层开始

final语句为无论如何都会执行的部分

一个异常处理代码块中,catch与try中间不能有程序

try一定要含有catch或者final,但只有final要继续抛出异常

如果不想处理异常,暴力的一直throw给java虚拟机,会通过编译,但会产生问题


JAVA的图形界面,awt,swing似乎用的并不多。毕竟是主要用于服务器端语言

大致了解了一些基本方法


还是直接开始实例吧,回顾代码,加上注释

这是运行后的大概样子


这个小程序还是很好玩的,可以自己创作乐器伴奏

下面是我自己敲的源码


public class BeatBox {JPanel mainPanel;ArrayList<JCheckBox> checkboxList;Sequencer sequencer;Sequence sequence;Track track;JFrame theFrame;//存放16种乐器的数组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"};//存放各乐器在MIDI中对应的序号int[] instruments = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};//主方法启动播放器public static void main(String[] args) {// TODO Auto-generated method stubBeatBox beatbox = new BeatBox();beatbox.buildGUI();}//建立用户界面public void buildGUI() {//主界面的几个模块和初始属性theFrame = new JFrame("BeatBox by Yshen");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);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 save = new JButton("Save");save.addActionListener(new MySendListener());buttonBox.add(save);JButton load = new JButton("Load");load.addActionListener(new MyReadInListener());buttonBox.add(load);//乐器列表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);grid.setVgap(1);grid.setHgap(2);mainPanel = new JPanel(grid);background.add(BorderLayout.CENTER, mainPanel);//256个checkbox生成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);}//建立MIDI播放器,记得trypublic 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();}}//track就像歌曲信息public void buildTrackAndStart () {int[] trackList = null;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++) {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));}//192为乐器频道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();}}//144和128频道分别表示开始和结束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));}}}//MIDIEvent就像乐谱,前四个参数是类型,频道,音符,音量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 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 * 0.97));}}//这里往下是存取的监听,将256个checkbox序列化存取public class MySendListener implements ActionListener {public void actionPerformed (ActionEvent a) {boolean[] checkboxState = new boolean[256];for (int i = 0; i < 256; i++) {JCheckBox check = (JCheckBox) checkboxList.get(i);if (check.isSelected()) {checkboxState[i] = true;}}try {FileOutputStream fileStream = new FileOutputStream(new File("Checkbox.ser"));ObjectOutputStream os = new ObjectOutputStream(fileStream);os.writeObject(checkboxState);os.close();} catch (Exception e) {e.printStackTrace();}}}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();is.close();} 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();}}}

可以用这个尝试发布成jar包后转为exe给朋友玩玩。