本来再看《Head First 设计模式》的,但是看到里面提到《Head First Java》就先把这本书看完了,里面有一个电子音效的小例子,就照着做了一下。
主要功能:
1,一共有16个拍子,16种音高,可以循环播放这16个拍子。
2,可以保存/打开编好的节奏
完整代码:
package com.ztc.view;
import javax.sound.midi.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ztc on 15-11-24.
*/
public class display extends JFrame {
JPanel center,move;
Box buttonBox,nameBox;
JButton start,stop,up,down,save,open,clear;
JFileChooser jfc;
List<JCheckBox> checkBox;
Sequencer sequencer;
Sequence sequence;
Track track;
String[] typeName={"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[] type={35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
public static void main(String[] args){
new display();
}
public display(){
jfc=new JFileChooser("./");
//左部
nameBox=new Box(BoxLayout.Y_AXIS);
for(int i=0;i<16;i++){
nameBox.add(new JLabel(typeName[i]));
}
this.add(nameBox,"West");
//右部
buttonBox=new Box(BoxLayout.Y_AXIS);
start=new JButton("Start");
start.addActionListener(new MyStartListener());
stop=new JButton("Stop");
stop.addActionListener(new MyStopListener());
up=new JButton("Up");
up.addActionListener(new MyUpListener());
down=new JButton("Down");
down.addActionListener(new MyDownListener());
save=new JButton("Save");
save.addActionListener(new MySaveListener(this));
open=new JButton("Open");
open.addActionListener(new MyOpenListener(this));
clear=new JButton("Clear");
clear.addActionListener(new MyClearListener());
buttonBox.add(start);
buttonBox.add(stop);
buttonBox.add(up);
buttonBox.add(down);
buttonBox.add(save);
buttonBox.add(open);
buttonBox.add(clear);
this.add(buttonBox, "East");
//中部
checkBox=new ArrayList<JCheckBox>();
center=new JPanel();
center.setLayout(new GridLayout(16,16,2,2));
for(int i=0;i<256;i++){
JCheckBox c=new JCheckBox();
c.setSelected(false);
checkBox.add(c);
center.add(c);
}
this.add(center,"Center");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500,280);
this.setLocation(500,300);
this.setVisible(true);
this.setTitle("BeatBox");
try {
sequencer= MidiSystem.getSequencer();
sequencer.open();
sequence=new Sequence(Sequence.PPQ,4);
track=sequence.createTrack();
sequencer.setTempoInBPM(120);
} catch (MidiUnavailableException e) {
e.printStackTrace();
} catch (InvalidMidiDataException e) {
e.printStackTrace();
}
}
public void makeTracks(int[] list){
for(int i=0;i<16;i++){
if(list[i]!=0){
track.add(makeEvent(144,9,list[i],100,i));
track.add(makeEvent(128,9,list[i],100,i+1));
}
}
}
public MidiEvent makeEvent(int comd,int chan,int one,int two,int tick){
MidiEvent event=null;
try {
ShortMessage b=new ShortMessage();
b.setMessage(comd, chan, one, two);
event=new MidiEvent(b,tick);
} catch (InvalidMidiDataException e) {
e.printStackTrace();
}
return event;
}
public void buildTrackAndStart(){
int[] trackList=null;
sequence.deleteTrack(track);
track=sequence.createTrack();
for(int i=0;i<16;i++){
trackList=new int[16];
for(int j=0;j<16;j++){
JCheckBox jc=(JCheckBox)checkBox.get(j+(16*i));
if(jc.isSelected()){
trackList[j]=type[i];
}else{
trackList[j]=0;
}
}
makeTracks(trackList);
track.add(makeEvent(176,1,126,0,16));
}
try {
track.add(makeEvent(192,9,1,0,15));
sequencer.setSequence(sequence);
sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempoInBPM(120);
} catch (InvalidMidiDataException e) {
e.printStackTrace();
}
}
private class MyStartListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
buildTrackAndStart();
}
}
private class MyStopListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
sequencer.stop();
}
}
private class MyDownListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*0.97));
}
}
private class MyUpListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*1.03));
}
}
private class MySaveListener implements ActionListener {
JFrame jf;
public MySaveListener(JFrame jf){
this.jf=jf;
}
@Override
public void actionPerformed(ActionEvent e) {
jfc.setCurrentDirectory(jfc.getCurrentDirectory());
int result=jfc.showSaveDialog(jf);
File f=jfc.getSelectedFile();
boolean[] o=new boolean[256];
for(int i=0;i<256;i++){
if(((JCheckBox)checkBox.get(i)).isSelected()){
o[i]=true;
}
}
if(result==0&&f!=null) {
try {
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(o);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
private class MyOpenListener implements ActionListener {
JFrame jf;
public MyOpenListener(JFrame jf) {
this.jf=jf;
}
@Override
public void actionPerformed(ActionEvent e) {
jfc.setCurrentDirectory(jfc.getCurrentDirectory());
int result=jfc.showOpenDialog(jf);
File f=jfc.getSelectedFile();
if(result==0&&f!=null) {
try {
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
boolean[] o = (boolean[]) ois.readObject();
for (int i = 0; i < 256; i++) {
if (o[i]) {
checkBox.get(i).setSelected(true);
} else {
checkBox.get(i).setSelected(false);
}
}
sequencer.stop();
//buildTrackAndStart();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
}
private class MyClearListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
for(int i=0;i<256;i++){
checkBox.get(i).setSelected(false);
}
sequencer.stop();
}
}
}