我正试图做一个笑脸GUI继续在我的JButtons上给我一个空指针异常(NPE)

时间:2017-06-30 07:42:15

标签: java class jpanel jbutton paintcomponent

我需要设置一个标准的笑脸GUI,你可以用JButton眨眼,眨眼,微笑和皱眉。我需要用三个单独的类来做这个:一个绘制笑脸的类,一个包含所有按钮的类和控制笑脸的actionListeners,以及一个包含applet的类。

我一直在按钮类的按钮上获取NPE。我无法弄清楚为什么。请放轻松我,我是Java的新手。

这是我的控件类:

public class SmileyControls extends JPanel implements ActionListener {

    Smiley smiley;

    JPanel controlPanel, eyePanel;
    JButton open, wink, shut; // make these an animation???? see loop chapter in text

    public SmileyControls(Smiley smileControl) {

        smiley = smileControl;
        controlLayout();
    }

    public void controlLayout() {

        eyePanel = new JPanel(new FlowLayout());
        open = new JButton("Open");
        wink = new JButton("Wink");
        shut = new JButton("Shut");

        open.addActionListener(this);
        wink.addActionListener(this);
        shut.addActionListener(this);

        eyePanel.add(open);
        eyePanel.add(wink);
        eyePanel.add(shut);
        add(eyePanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if(e.getSource()==open){
            smiley.setEyeCondition(0);  // this calls the method setEyeCondition() from the smiley class that I created. I'm getting my NPE's here
        }
        if(e.getSource()==wink){
            smiley.setEyeCondition(1);  // and here
        }
        if(e.getSource()==shut){
            smiley.setEyeCondition(2);  // and here
        }
    }
}

这是我的笑脸课程:

public class Smiley extends JPanel {

    int locX, locY, height, width;
    Color moleColor;
    int eyeCondition;
    Graphics2D g2d;

    public Smiley(int x, int y, int w, int h) {

        locX = x;
        locY = y + 100; // needed to add 100 pixels to make room for hair
        height = h;
        width = w;

        moleColor = new Color(84,60,37);
        eyeCondition = 0;
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);

        g2d= (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        setHair();
        setFace();
        setEyes();  // these methods paint the face
        setMole();
        setMouth();
    }

    // CONTROL METHODS

    public void setEyeCondition(int eye) {

        // the int values here are taken from the smileyControls class
        // I think they'd repaint my applet if it weren't for the NPE's

        if(eye == 0) {
            // draw eyes open
            g2d.fillOval(locX+width/5, locY+height/5,width/5, height/5); // left eye
            g2d.fillOval(locX+3*width/5, locY+height/5, width/5, height/5); // right eye
            repaint();
        } else if(eye == 1) {
            // draw wink
            g2d.fillRect(locX+width/5, locY+height/5,width/2, height/20); // left eye winking
            g2d.fillOval(locX+3*width/5, locY+height/5, width/5, height/5); // right eye open
            repaint();
        } else if(eye == 2) {
            // draw blink
            g2d.fillRect(locX+width/5, locY+height/5,width/2, height/20); // left eye blinking
            g2d.fillRect(locX+3*width/5, locY+height/5,width/2, height/20); // right eye blinking
            repaint();
        }
    }

    public void setEyes() { // this method paints the original eyes

        g2d.setColor(Color.black);
        g2d.fillOval(locX+width/5, locY+height/5,width/5, height/5); // left eye
        g2d.fillOval(locX+3*width/5, locY+height/5, width/5, height/5); // right eye
    }

}

这是我的小程序:

public class SmileyApplet extends JApplet {

    Smiley smiley1;
    SmileyControls control1;

    JPanel container, smileyAndControls1, smileyAndControls2, smileyAndControls3;

    BorderLayout border;

    public void init() {

        border = new BorderLayout();
        setLayout(border);

        setUpContainer();

    }

    public void setUpContainer() {

        container = new JPanel(new FlowLayout());
        smileyAndControls1 = new JPanel(new FlowLayout());

        setUpControl();
        setUpSmiley();

        smiley1.setPreferredSize(new Dimension(450, 600));

        smileyAndControls1.add(control1);
        smileyAndControls1.add(smiley1);

        container.add(smileyAndControls1);  // add more controls to master container here

        add(container, BorderLayout.CENTER);
    }

    public void setUpSmiley() {

        smiley1 = new Smiley(0, 0, 400, 400);
        add(smiley1);
    }

    public void setUpControl() {

        control1 = new SmileyControls(smiley1);
    }

}

2 个答案:

答案 0 :(得分:0)

首先,您致电setUpControl(),在那里创建SmileyControls并将smiley1传递给它(当时为null)。 之后,您拨打setUpSmiley(),创建Smiley

的实例

因此,您可能只需在致电setUpSmiley()之前致电setUpControl(),问题应该得到解决。

答案 1 :(得分:0)

尝试更改这些行的顺序,因为在smiley1变量获取其值之前使用它:

    setUpControl(); // This uses smiley1
    setUpSmiley();  // This instantiates smiley1

修改

您应该将绘图移动到paint*()方法或直接从它们调用的方法。

也就是说,您的setEyeCondition()方法应该在笑脸上设置属性,并且绘图应该放在您的setEyes()方法中。