带有Canvas类的Java GUI NullPointerException

带有Canvas类的Java GUI NullPointerException,java,swing,nullpointerexception,awt,mixing,Java,Swing,Nullpointerexception,Awt,Mixing,所以我正在为我的班级做一个GUI项目,我有点被卡住了。我的问题与GUI方面有关,因此我想您可以忽略与排序有关的其他方法。到目前为止,我主要关心的是如何让GUI正常工作。但是,我一直遇到一个错误,确切地说是空指针异常: Java.lang.NullPointerException at SortDriver$SortCanvas.paint(SortDriver.java:253) at SortDriver.init(SortDriver.java:197) at sun

所以我正在为我的班级做一个GUI项目,我有点被卡住了。我的问题与GUI方面有关,因此我想您可以忽略与排序有关的其他方法。到目前为止,我主要关心的是如何让GUI正常工作。但是,我一直遇到一个错误,确切地说是空指针异常:

Java.lang.NullPointerException
    at SortDriver$SortCanvas.paint(SortDriver.java:253)
    at SortDriver.init(SortDriver.java:197)
    at sun.applet.AppletPanel.run(AppletPanel.java:436)
    at java.lang.Thread.run(Thread.java:679)
在阅读了我的代码之后,我想我把它缩小到了我的SortCanvas类。我以前从未用过它,但它是我教授给我们的存根的一部分。也就是说,它工作正常,图像显示正确,但我的实现似乎不正确。有人能帮我弄清楚如何正确实现我的SortCanvas“图片”吗?我仔细阅读了画布上的Java文档,但仍然不明白我做错了什么。这是我的密码:

import java.awt.*;
import java.applet.Applet;
import javax.swing.*;
import java.awt.event.*;

public class SortDriver extends Applet {

private int array[];  // array to be sorted
private int limit = 1000;  // size of array to be sorted - you may have to make
// this bigger for faster sorts
private int largestNum; // need to know for color scaling purposes in paint()

// flag to tell paint() whether to paint a single location or the whole array
private enum PaintType {ALL, SINGLE};
private PaintType doPaint = PaintType.ALL;

private int index = -1;  // index of single array location to be painted

//this listener object responds to button events
private ButtonActionListener buttonListener;

//button to start the sort
private JButton sortButton;

//basic window frame
private JFrame mainFrame;

//layouts
private BorderLayout initialLayout;
private FlowLayout northLayout;
private BorderLayout centerLayout;
private BorderLayout southLayout;

//basic panel for window frame
private JPanel initialPanel;
//panels for window layout
private JPanel northPanel;
private JPanel centerPanel;
private JPanel southPanel;
//panels for radio buttons
private JPanel radioOrderPanel;
private JPanel radioSortPanel;
private JPanel radioColorPanel;

//north panel header labels
private JLabel topTitleLabel;
private JLabel bottomTitleLabel;
private JLabel arraySizeLabel;

//radio buttons for list order (radioOrderButton)
//random set, ordered set, reverse set
private JRadioButton rOB1, rOB2, rOB3;
//radio buttons for sort type (radioSortButton)
//bubblesort, insertionsort, mergesort, quicksort
private JRadioButton rSB1, rSB2, rSB3, rSB4;
//radio buttons for color choice (radioColorButton)
//green, red, white, blue
private JRadioButton rCB1, rCB2, rCB3, rCB4;

//radio button groups for each radio panel
private ButtonGroup orderGroup, sortGroup, colorGroup;

//text field for size of the array
private JTextField arraySizeTextField;

// the picture of the sort will appear on this canvas
private SortCanvas picture;
private final int pictureWidth = 500;  // size of the sort bar 1001
private final int pictureHeight = 50;

public void init() {

    buttonListener = new ButtonActionListener();

    array = new int[limit];
    // load the array
    largestNum = array[0] = (int) (Math.random()*1000000.0);
    for (int i=1; i<limit; i++) {
        array[i] = (int) (Math.random()*1000000.0);
        // also keep track of the largest so that we can scale by it in paint()
        if (array[i] > largestNum) largestNum = array[i]; 
    }

    //set up the main frame
    mainFrame = new JFrame();
    initialPanel = (JPanel) mainFrame.getContentPane();
    initialLayout = new BorderLayout();
    mainFrame.setResizable(false);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.setSize(650, 750);
    initialPanel.setLayout(initialLayout);

    //set up north panel
    northPanel = new JPanel();
    northLayout = new FlowLayout();
    topTitleLabel = new JLabel("SortIt!");
    bottomTitleLabel = new JLabel("A program by Mike Sevilla");
    northPanel.setLayout(northLayout);
    northPanel.add(topTitleLabel, BorderLayout.NORTH);
    northPanel.add(bottomTitleLabel, BorderLayout.NORTH);
    initialPanel.add(northPanel, BorderLayout.NORTH);

    //set up center panel
    centerPanel = new JPanel();
    centerLayout = new BorderLayout();
    centerPanel.setLayout(centerLayout);
    //place array size label
    arraySizeLabel = new JLabel("Size:");
    //place array size text field w/ space for 5 chars
    arraySizeTextField = new JTextField("", 5);
    //place sort button
    sortButton = new JButton("Sort it!");
    // the listener is triggered when the button is clicked
    sortButton.addActionListener(buttonListener);
    centerPanel.setLayout(centerLayout);
    //place sort bar on top of center layout
    picture = new SortCanvas();
    centerPanel.add(picture, BorderLayout.CENTER);
    centerPanel.add(arraySizeLabel, BorderLayout.CENTER);
    centerPanel.add(arraySizeTextField, BorderLayout.CENTER);
    centerPanel.add(sortButton, BorderLayout.CENTER);
    initialPanel.add(centerPanel, BorderLayout.CENTER);

    //set up south panel
    southPanel = new JPanel();
    southLayout = new BorderLayout();
    southPanel.setLayout(southLayout);
    //set radio buttons and format layouts
    radioOrderPanel = new JPanel();
    radioOrderPanel.setLayout(new BoxLayout(radioOrderPanel, BoxLayout.Y_AXIS));
    radioSortPanel = new JPanel();
    radioSortPanel.setLayout(new BoxLayout(radioSortPanel, BoxLayout.Y_AXIS));
    radioColorPanel = new JPanel();
    radioColorPanel.setLayout(new BoxLayout(radioColorPanel, BoxLayout.Y_AXIS));
    //define radio buttons
    rOB1 = new JRadioButton("Random Order", true);
    rOB1.addActionListener(buttonListener);
    radioOrderPanel.add(rOB1);

    rOB2 = new JRadioButton("In Order", false);
    rOB2.addActionListener(buttonListener);
    radioOrderPanel.add(rOB2);

    rOB3 = new JRadioButton("In Reverse", false);
    rOB3.addActionListener(buttonListener);
    radioOrderPanel.add(rOB3);

    rSB1 = new JRadioButton("Bubble Sort", true);
    rSB1.addActionListener(buttonListener);
    radioSortPanel.add(rSB1);

    rSB2 = new JRadioButton("Insertion Sort", false);
    rSB2.addActionListener(buttonListener);
    radioSortPanel.add(rSB2);

    rSB3 = new JRadioButton("Merge Sort", false);
    rSB3.addActionListener(buttonListener);
    radioSortPanel.add(rSB3);

    rSB4 = new JRadioButton("Quick Sort", false);
    rSB4.addActionListener(buttonListener);
    radioSortPanel.add(rSB4);

    rCB1 = new JRadioButton("Green", true);
    rCB1.addActionListener(buttonListener);
    radioColorPanel.add(rCB1);

    rCB2 = new JRadioButton("Red", false);
    rCB2.addActionListener(buttonListener);
    radioColorPanel.add(rCB2);

    rCB3 = new JRadioButton("White", false);
    rCB3.addActionListener(buttonListener);
    radioColorPanel.add(rCB3);

    rCB4 = new JRadioButton("Blue", false);
    rCB4.addActionListener(buttonListener);
    radioColorPanel.add(rCB4);

    //add radio buttons to a button group
    orderGroup = new ButtonGroup();
    orderGroup.add(rOB1);
    orderGroup.add(rOB2);
    orderGroup.add(rOB3);       
    sortGroup = new ButtonGroup();
    sortGroup.add(rSB1);
    sortGroup.add(rSB2);
    sortGroup.add(rSB3);
    sortGroup.add(rSB4);
    colorGroup = new ButtonGroup();
    colorGroup.add(rCB1);
    colorGroup.add(rCB2);
    colorGroup.add(rCB3);
    colorGroup.add(rCB4);
    initialPanel.add(southPanel, BorderLayout.NORTH);

    picture.paint(picture.getGraphics());
    mainFrame.setVisible(true);
}

// this object is triggered whenever a button is clicked
private class ButtonActionListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {

        // find out which button was clicked 
        Object source = event.getSource();

        // start sort button was clicked
        if (source == sortButton) {
            // call the sort
            doBubblesort();
        }
        // called when user hits return in text field
        if (source == arraySizeTextField) {
            int size = Integer.parseInt(arraySizeTextField.getText());
        }
    }    
}

private void doBubblesort() {
    int temp;

    // this is just bubblesort
    for (int i=0; i<limit-1; i++) {
        for (int j=0; j<limit-1-i; j++) {
            if (array[j]>array[j+1]) {
                temp = array[j]; array[j] = array[j+1]; array[j+1] = temp;

                // redraw only locations j and j+1
                doPaint = PaintType.SINGLE;  // try changing this to ALL and see what happens
                index = j; 
                picture.paint(picture.getGraphics());
                index = j+1; 
                picture.paint(picture.getGraphics());
            }
        }
    }
}      

class SortCanvas extends Canvas {
    // this class paints the sort bar 

    SortCanvas() {
        setSize(pictureWidth, pictureHeight);
        setBackground(Color.white);
    }

    public void paint(Graphics g) {

        if (doPaint == PaintType.ALL) {
            // paint whole array - this takes time so it shouldn't be done too frequently
            setBackground(Color.white);
            g.setColor(Color.white);
            g.fillRect(0, 0, pictureWidth, pictureHeight);

            for (int i=0; i<limit; i++) {
                // the larger the number, the brighter green it is
                // green is between 0.0 and 1.0
                // divide by the largest number to get a value between 0 and 1
                float green = (float)(array[i]/(float)largestNum);

                // clamp if necessary - it shouldn't be
                if (green<0f) green = 0f;
                if (green>1f) green = 1f;

                g.setColor(new Color(0.0f, green, 0.0f));
                // array location 0 is painted at left; 
                //   array location limit-1 is painted to right
                //this is a single vertical line in the bar
                g.drawLine((int)(i*pictureWidth/limit), 0, 
                        (int)(i*pictureWidth/limit), pictureHeight);
            }
        }
        else {
            // just paint one location on the bar
            float green = (float)(array[index]/(float)largestNum);
            if (green<0f) green = 0f;
            if (green>1f) green = 1f;
            g.setColor(new Color(0.0f, green, 0.0f));
            g.drawLine((int)(index*pictureWidth/limit), 0, 
                    (int)(index*pictureWidth/limit), pictureHeight);
        }   
    }
}
}
import java.awt.*;
导入java.applet.applet;
导入javax.swing.*;
导入java.awt.event.*;
公共类SortDriver扩展小程序{
私有int数组[];//要排序的数组
private int limit=1000;//要排序的数组大小-可能需要
//这个越大,排序越快
private int largestNum;//需要知道油漆()中的颜色缩放
//指示paint()是绘制单个位置还是整个阵列的标志
私有枚举类型{ALL,SINGLE};
私有PaintType doPaint=PaintType.ALL;
private int index=-1;//要绘制的单个数组位置的索引
//此侦听器对象响应按钮事件
私有按钮监听器按钮监听器;
//按钮开始排序
私有JButton-sortButton;
//基本窗框
专用JFrame主机;
//布局
私人边界布局;
私人物流布局;
私人边界布局中心布局;
私人边界布局;
//窗框基本板
私人JPanel小组;
//用于窗口布局的面板
私人JPanel northPanel;
私人JPanel中心面板;
私人JPanel southPanel;
//单选按钮面板
私人JPanel radioOrderPanel;
私人JPanel无线电传送面板;
私人JPanel无线电彩色面板;
//北面板标题标签
私人JLabel topttitlelabel;
私有JLabel-bottomTitleLabel;
私人JLabel arraySizeLabel;
//列表顺序单选按钮(radioOrderButton)
//随机集,有序集,逆向集
私人JRadioButton rOB1、rOB2、rOB3;
//排序类型的单选按钮(RadioPortButton)
//气泡排序、插入排序、合并排序、快速排序
专用JRadioButton rSB1、rSB2、rSB3、rSB4;
//颜色选择单选按钮(radioColorButton)
//绿色,红色,白色,蓝色
私人JRadioButton rCB1、rCB2、rCB3、rCB4;
//每个收音机面板的单选按钮组
私有按钮组orderGroup、sortGroup、colorGroup;
//数组大小的文本字段
私有JTextField arraySizeTextField;
//该类图片将显示在此画布上
私人SortCanvas图片;
private final int pictureWidth=500;//排序栏的大小1001
私人最终整数图片高度=50;
公共void init(){
buttonListener=新建ButtonActionListener();
数组=新整数[限制];
//加载数组
largestNum=array[0]=(int)(Math.random()*1000000.0);
对于(int i=1;i largestNum)largestNum=array[i];
}
//设置主框架
大型机=新的JFrame();
initialPanel=(JPanel)mainFrame.getContentPane();
initialLayout=新的BorderLayout();
mainFrame.setresizeable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
大型机。设置大小(650750);
initialPanel.setLayout(initialLayout);
//设置北面板
northPanel=新的JPanel();
northLayout=新的FlowLayout();
topTitleLabel=新的JLabel(“SortIt!”);
bottomTitleLabel=新的JLabel(“Mike Sevilla的程序”);
设置布局(northLayout);
添加(topTitleLabel,BorderLayout.NORTH);
添加(底部标题标签,BorderLayout.NORTH);
initialPanel.add(northPanel,BorderLayout.NORTH);
//设置中心面板
centerPanel=新的JPanel();
centerLayout=新的BorderLayout();
centerPanel.setLayout(中心布局);
//放置数组大小标签
arraySizeLabel=新的JLabel(“大小:”);
//放置数组大小的文本字段,带5个字符的空格
arraySizeTextField=新的JTextField(“,5”);
//放置排序按钮
sortButton=newjbutton(“排序!”);
//单击按钮时会触发侦听器
addActionListener(buttonListener);
centerPanel.setLayout(中心布局);
//将排序栏放置在中心布局的顶部
图片=新的SortCanvas();
中心面板。添加(图片、边框布局。中心);
添加(arraySizeLabel,BorderLayout.CENTER);
添加(arraySizeTextField,BorderLayout.CENTER);
添加(排序按钮,BorderLayout.CENTER);
initialPanel.add(中心面板,BorderLayout.CENTER);
//设置南面板
southPanel=newjpanel();
southLayout=新的BorderLayout();
设置布局(southLayout);
//设置单选按钮和格式布局
radioOrderPanel=new JPanel();
radioOrderPanel.setLayout(新的BoxLayout(radioOrderPanel,BoxLayout.Y_轴));
RadioPortPanel=新的JPanel();
RadioPortPanel.setLayout(新的BoxLayout(RadioPortPanel,BoxLayout.Y_轴));
radioColorPanel=新JPanel();
radioColorPanel.setLayout(新的BoxLayout(radioColorPanel,BoxLayout.Y_轴));
//定义单选按钮
rOB1=新的JRadioButton(“随机顺序”,真);
rOB1.addActionListener(按钮Listener);
radioOrderPanel.add(rOB1);
rOB2=新的JRadioButton(“按顺序”,错误);
rOB2.addActionListener(按钮Listener);
radioOrderPanel.add(rOB2);
rOB3=新的JRadioButton(“反向”,false);
rOB3.addActionListener(按钮Listener);
radioOrderPanel.add(rOB3);
rSB1=新的JRadioButton(“气泡排序”,true);
rSB1.addActionListener(按钮Listener);
无线电端口面板。添加(rSB1);
rSB2=新的JRadioButton(“插入排序”,false);
rSB2.addActionListener(按钮Listener);
picture.repaint();
picture.paint(picture.getGraphics());