Java I';我试图制作一个笑脸GUI,但在我的JButtons上总是给我一个空指针异常(NPE)
我需要建立一个标准的笑脸图形用户界面,在那里你可以眨眼,眨眼,微笑,皱眉头。我需要使用三个独立的类来完成这项工作:一个绘制笑脸的类,一个包含所有按钮和控制笑脸的ActionListener的类,以及一个包含小程序的类 在button类中,我的按钮上不断出现NPE。我不明白为什么。请对我放轻松点,我是Java新手 这是我的控件类:Java I';我试图制作一个笑脸GUI,但在我的JButtons上总是给我一个空指针异常(NPE),java,class,jpanel,jbutton,paintcomponent,Java,Class,Jpanel,Jbutton,Paintcomponent,我需要建立一个标准的笑脸图形用户界面,在那里你可以眨眼,眨眼,微笑,皱眉头。我需要使用三个独立的类来完成这项工作:一个绘制笑脸的类,一个包含所有按钮和控制笑脸的ActionListener的类,以及一个包含小程序的类 在button类中,我的按钮上不断出现NPE。我不明白为什么。请对我放轻松点,我是Java新手 这是我的控件类: public class SmileyControls extends JPanel implements ActionListener { Smiley s
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);
}
}
首先调用
setUpControl()
,在那里创建SmileyControls
并将smiley1
传递给它(当时为null
)。
然后调用setUpSmiley()
,创建Smiley
的实例
因此,在调用
setUpControl()
之前,您可能只需调用setUpSmiley()
,您的问题就应该得到解决。尝试更改这些行的顺序,因为您在smiley1
变量获得其值之前使用它:
setUpControl(); // This uses smiley1
setUpSmiley(); // This instantiates smiley1
编辑
应将图形移动到paint*()
方法,或直接从这些方法调用的方法
也就是说,您的
seteyecodition()
方法应该在smiley上设置一个属性,并且图形应该进入您的setEyes()
方法。在控件类的actionPerformed方法中抛出的异常
具体在哪里。您必须向下滚动,行被注释。不要维护对您未创建的图形上下文的引用,而是将提供给您的引用传递给需要使用它的方法,这些方法摆脱了NPE,谢谢!!但现在我的纽扣无法重新粉刷眼睛。我在想,这是因为我在用一种非绘画成分的方法绘画?那就摆脱了NPE,谢谢!!但现在我的纽扣无法重新粉刷眼睛。我在想,这是因为我在用一种不是paintComponent的方法作画?