【问题标题】:I'm trying to make a smiley face GUI keeps giving me a Null Pointer Exception (NPE) on my JButtons [duplicate]我正在尝试制作笑脸 GUI 在我的 JButtons 上不断给我一个空指针异常 (NPE) [重复]
【发布时间】:2017-06-30 07:42:14
【问题描述】:

我需要设置一个标准的笑脸 GUI,您可以在其中使用 JButton 眨眼、眨眼、微笑和皱眉。我需要使用三个单独的类来完成此操作:绘制笑脸的类、包含所有按钮和控制笑脸的 actionListener 的类,以及带有小程序的类。

我在按钮类中的按钮上不断出现 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);
    }

}

【问题讨论】:

  • Exception 到底是在哪里抛出的?
  • 在控件类的actionPerformed方法中。您必须向下滚动,这些行已被注释
  • 不要维护对您未创建的 Graphics 上下文的引用,而是将您获得的引用传递给需要使用它的方法

标签: java class jpanel jbutton paintcomponent


【解决方案1】:

首先你调用setUpControl(),在那里你创建你的SmileyControls并将smiley1传递给它(当时是null)。 之后你调用setUpSmiley() 创建Smiley 的实例。

所以您可能只需要在拨打setUpControl() 之前拨打setUpSmiley() 即可解决您的问题。

【讨论】:

  • 那摆脱了NPE,谢谢!!但现在我的按钮不会重新绘制眼睛。我在想是因为我在用一种不是 paintComponent 的方法绘画?
【解决方案2】:

尝试更改这些行的顺序,因为在您使用 smiley1 变量之前,它会得到它的值:

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

编辑

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

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

【讨论】:

  • 那摆脱了NPE,谢谢!!但现在我的按钮不会重新绘制眼睛。我在想是因为我在用一种不是 paintComponent 的方法绘画?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
相关资源
最近更新 更多