Java 为音乐合成器创建GUI时出现NullException

Java 为音乐合成器创建GUI时出现NullException,java,Java,我试图从HeadFirstJava中复制代码,他们在那里为BeatBox创建了一个API。我一直得到一个空异常,但我不知道为什么。有人有主意吗?(空异常来自buildTrackAndStart()中的sequencer import java.awt.*; 导入javax.swing.*; 导入javax.sound.midi.*; 导入java.util.*; 导入java.awt.event.*; 公共类BeatBox{ JPanel主面板; ArrayList复选框列表; 测序器; 序列;

我试图从HeadFirstJava中复制代码,他们在那里为BeatBox创建了一个API。我一直得到一个空异常,但我不知道为什么。有人有主意吗?(空异常来自
buildTrackAndStart()
中的sequencer

import java.awt.*;
导入javax.swing.*;
导入javax.sound.midi.*;
导入java.util.*;
导入java.awt.event.*;
公共类BeatBox{
JPanel主面板;
ArrayList复选框列表;
测序器;
序列;
轨道;
JFrame框架;
String[]instrumentNames={“Bass Drum”,“Closed Hi Hat”,
“开放式打击帽”、“原声陷阱”、“撞击钹”、“手拍”,
“High Tom”、“High Bongo”、“Maracas”、“Whistle”、“Low Conga”,
“考贝尔”、“Vibraslap”、“中低档汤姆”、“High Agogo”,
“开嗨康加”};
国际[]文书={35、42、46、38、49、39、50、60、70、72、64、56、58、47、67、63};
公共静态void main(字符串[]args){
新建BeatBox().buildGui();
}
public void buildGui(){
theFrame=新的JFrame(“赛博拍盒”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout=新的BorderLayout();
JPanel背景=新JPanel(布局);
background.setboorder(BorderFactory.createEmptyBorder(10,10,10,10));
checkboxList=newarraylist();
框按钮框=新框(框布局Y_轴);
JButton start=新JButton(“start”);
start.addActionListener(新的MyStartListener());
按钮盒。添加(开始);
JButton stop=新JButton(“stop”);
addActionListener(新的MyStopListener());
按钮盒。添加(停止);
JButton upTempo=新JButton(“节拍上升”);
addActionListener(新的myuptempolListener());
按钮盒。添加(upTempo);
JButton downTempo=新JButton(“Tempo down”);
addActionListener(新的MyDownTempoListener());
按钮盒。添加(下拍子);
盒子名称盒子=新盒子(盒子布局Y_轴);
对于(int i=0;i<16;i++){
添加(新标签(仪器名称[i]);
}
添加(BorderLayout.EAST,buttonBox);
添加(BorderLayout.WEST,nameBox);
theFrame.getContentPane().add(后台);
GridLayout grid=新的GridLayout(16,16);
网格设置间隙(1);
网格。setHgap(1);
主面板=新的JPanel(网格);
添加(BorderLayout.CENTER,主面板);
对于(int i=0;i<256;i++){
JCheckBox c=新的JCheckBox();
c、 已选择(假);
复选框列表。添加(c);
主面板。添加(c);
}//结束循环
setUpMidi();
机架立根(50,50,300,300);
frame.pack();
frame.setVisible(true);
}//关闭方法
公共无效设置MIDI(){
试一试{
Sequencer Sequencer=MidiSystem.getSequencer();
System.out.println(“设置中的sequencer==null”+(sequencer==null));
sequencer.open();
序列=新序列(sequence.PPQ,4);
track=sequence.createTrack();
sequencer.setTempoInBPM(120);
}捕获(例外e){
e、 printStackTrace();
}
}//关闭方法
public void buildTrackAndStart(){
int[]trackList=null;
顺序。删除跟踪(跟踪);
track=sequence.createTrack();
对于(int i=0;i<16;i++){
trackList=newint[16];
int键=仪器[i];
对于(int j=0;j<16;j++){
JCheckBox jc=(JCheckBox)checkboxList.get(j+(16*i));
if(jc.isSelected()){
trackList[j]=键;
}
否则{
轨迹列表[j]=0;
}
}//闭合内环
makeTracks(trackList);
添加(makeEvent(176,1127,0,16));
}//闭合外环
添加(makeEvent(192,9,1,0,15));
试一试{
System.out.println(“sequencer==null”+(sequencer==null));
序列器。设置序列(序列);
sequencer.setLoopCount(sequencer.LOOP_连续);
sequencer.start();
sequencer.setTempoInBPM(120);
}捕获(例外e){
e、 printStackTrace();
}
}//关闭buildTrackAndStart方法
公共类MyStartListener实现ActionListener{
已执行的公共无效操作(操作事件a){
buildTrackAndStart();
}
}//关闭内部类
公共类MyStopListener实现ActionListener{
已执行的公共无效操作(操作事件a){
sequencer.stop();
}
}//关闭内部类
公共类MyUpTempoListener实现ActionListener{
已执行的公共无效操作(操作事件a){
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((浮点)(tempoFactor*1.03));
}
}//关闭内部类
公共类MyDownTempoListener实现ActionListener{
已执行的公共无效操作(操作事件a){
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((浮点)(tempoFactor*.97));
}
}//关闭内部类
公共void生成跟踪(int[]列表){
对于(int i=0;i<16;i++){
int key=list[i];
如果(键!=0){
添加(makeEvent(144,9,key,100,i));
添加(makeEvent(128,9,key,100,i+1));
}
}    
}//关闭makeTracks方法
公共MidiEvent生成事件(int comd、int chan、int one、int two、int tick){
MidiEvent=null;
试一试{
短消息a=新短消息();
a、 设置消息(comd、chan、一、二);
事件=新事件(a,勾号);
}捕获(例外e){
e、 printStackTrace();
}
返回事件;
}
}

setUpMidi
中,您声明了一个局部变量
sequencer
,并对其进行了初始化。但这并不影响您隐藏的变量,实例变量
sequencer
声明在类的顶部,因此它保持为
null
。更改

Sequencer sequencer = MidiSystem.getSequencer();


因此,它没有声明另一个变量,因此它引用的是实例变量。

异常发生在哪一行?您是否使用调试器逐行检查代码以准确查看发生了什么?请包括
Sequencer sequencer = MidiSystem.getSequencer();
sequencer = MidiSystem.getSequencer();