1

我编码的时间不长,但这是迄今为止我见过的最奇特的错误。现在我知道它说 Null Pointer Exception 错误,这是,但它是一个特定的错误,我已经一个多星期没在网上找到了,持续两个。我遇到了一个非常独特的问题,我急需帮助。(我想出了一个解决方法,所以我会按时完成我的项目,但这个错误仍然困扰着我)。(代码将在问题的最底部)。

项目:创建一个交通灯模拟:

  • 启动时处于“关闭”状态,必须使用键盘上的“o”键打开。它也必须能够关闭。
  • 当按下“f”键时,会导致黄灯闪烁。
  • 必须有一个真正的红绿灯进程(绿>黄>红>绿>等)

问题:当我的面板方法中的paintComponent(Graphics pen)发生时,会产生多个错误。(此处的屏幕截图:错误

我推断它发生在面板内创建对象之后的某个时间(当您阅读代码时更有意义)。这很奇怪,因为解决方法只是从类方法中复制并粘贴到原始面板中。

即,如果我的代码是用 pen.drawOval(insert parameters) 绘制一个椭圆,它将在其中包含paintComponent(Graphics pen) 方法的面板类中工作。但是,如果它在一个 Circle 类中,它就行不通了。

仅当paintComponent 访问另一个类的对象、另一个类的变量或另一个类的方法时,才会生成此错误。

如果使用 Circle 对象,则 object.drawOval(parameters) 将不起作用,但如果面板中使用了另一个公共 void 方法,称为 objectDraw(Graphics pen) 并从 paintComponent 作为 objectDraw(pen) 运行,它将起作用.

我希望我能尽力解释它。

现在是生成区域的代码。

我有一种令人作呕的感觉,它是如此简单以至于我忽略了。这真的是我最后的手段,因为我无法发现为什么会产生错误。

(JComponent 会损坏吗?它可能只是用户特定的吗?)

编码:

将 Lights 视为一个组类,其中包含多个对象作为私有类。(这可能是问题吗,私人课程?)

            /******************
              * Lights.java
              * 
              * Creates graphic objects.
              * 
              ******************/
            import java.awt.*; //Import the awt package.

            public class Lights{ //Driver class header.

              private final int RED = 1; //Creates switch constant.
              private final int YELLOW = 2; //Creates switch constant.
              private final int GREEN = 3; //Creates switch constant.
              private final int ALL_ON = 5; //Creates switch constant.
              private final int ALL_OFF = 6; //Creates switch constant.
              private final int BACKGROUND = 0; //Background switch constant.
              private final int FOREGROUND = 8; //Foreground switch constant.
              private final int FLASHING_YELLOW = 4; //Creates Flashing Yellow
              private final int DARK_YELLOW = 9; //Case in case.
              private int flashingColor = YELLOW; //Case in case.
              private boolean flashingYellow = false; //Creates false by default flashingYellow boolean.
              private Color lightColor; //Color variable lightcolor.
              private int colorSwitch; //Switch integer using constants and lightcolor.
              private int typeSwitch; //Also similar to above.
              private int x, y, lightswitch; //Other integers.
              private Rectangle grayBG, blackBG;
              private Circle red, green, yellow, redFore, greenFore, yellowFore;


              public Lights(){
                Rectangle grayBG = new Rectangle(35, 35, 280, 830, true);
                Rectangle blackBG = new Rectangle(50, 50, 250, 800, true);
                Circle red = new Circle(80, 75, 200, 200, true);
                Circle green = new Circle(80, 575, 200, 200, true);
                Circle yellow = new Circle(80, 325, 200, 200, true);
                Circle redFore = new Circle(80, 75, 200, 200, false);
                Circle greenFore = new Circle(80, 575, 200, 200, false);
                Circle yellowFore = new Circle(80, 325, 200, 200, false);
              }

              //Drawn when flash is on.
              public void flashOn(Graphics g){
                drawYellowLight(g, true);        
                drawGreenLight(g, false);
                drawRedLight(g, false);
                drawFore(g);
              }

              //Drawn when light is off.
              public void flashOff(Graphics g){
                drawYellowLight(g, false); 
                drawGreenLight(g, false);
                drawRedLight(g, false);
                drawFore(g);  
              }


              //Draws the foreground.
              public void drawFore(Graphics pen){
                drawRed(pen);
                drawYellow(pen);
                drawGreen(pen);
              }

              //Draws the foreground's red, yellow, and green.
              public void drawRed(Graphics pen){    
                pen.setColor(Color.RED);
                redFore.draw(pen);    
              }  
              public void drawYellow(Graphics pen){    
                pen.setColor(Color.YELLOW);
                yellowFore.draw(pen);    
              }  
              public void drawGreen(Graphics pen){    
                pen.setColor(Color.GREEN);
                greenFore.draw(pen);    
              }


              //Draws the background.
              public void drawBox(Graphics pen){
                //HTML Color Code for 'LightYellow4' (looks gray though); Color GRAY = new Color(139, 139, 122);
                pen.setColor(new Color(139, 139, 122));
                grayBG.draw(pen);
                pen.setColor(Color.BLACK);
                blackBG.draw(pen);
              }



              //Draws the green light whether on or off.
              public void drawGreenLight(Graphics pen, boolean isOn){
                //Color darkGreen = new Color(105, 139, 105);
                //Color lightGreen = new Color(0, 238, 0);
                if(!isOn){
                  pen.setColor(new Color(105, 139, 105));
                  green.draw(pen);        
                } else {
                  pen.setColor(new Color(0, 238, 0));
                  green.draw(pen);
                }
              }







              //Draws the yellow light whether on or off.
              public void drawYellowLight(Graphics pen, boolean isOn){     
                //Color darkYellow = new Color(139, 69, 0);
                //Color lightYellow = new Color(255, 215, 0);
                if(!isOn){
                  pen.setColor(new Color(139, 69, 0));
                  yellow.draw(pen);      
                } else {
                  pen.setColor(new Color(255, 215, 0));
                  yellow.draw(pen); 
                } 
              }







              //Draws the red light whether on or off.  
              public void drawRedLight(Graphics pen, boolean isOn){     
                //Color darkRed = new Color(139, 26, 26);
                //Color lightRed = new Color(255, 48, 48);
                if(!isOn){
                  pen.setColor(new Color(139, 26, 26));
                  red.draw(pen);      
                } else {
                  pen.setColor(new Color(255, 48, 48));
                  red.draw(pen); 
                } 
              }



              /******************
                * Lights$Rectangle.java
                * 
                * Creates a graphic object named Rectangle.
                * 
                ******************/
              private class Rectangle{ //Driver class header.

                //Define global private integers.
                private int x, y, h, w;
                private boolean fill;

                //Methods

                //Object constructor, Definition.
                //Defines the info for a rectangle.
                public Rectangle(int a, int b, int height, int width, boolean isFilled){
                  x = a;
                  y = b;
                  h = height;
                  w = width;
                  fill = isFilled;
                }

                public void draw(Graphics pen){
                  if(fill == true){
                    int xPosition = x - w;
                    int yPosition = y - h;
                    pen.fillRect(xPosition, yPosition, w, h);
                  } else {      
                    int xPosition = x - w;
                    int yPosition = y - h;
                    pen.drawRect(xPosition, yPosition, w, h);  
                  }
                }

              }





              /******************
                * Lights$Circle.java
                * 
                * Creates a graphic object named Rectangle.
                * 
                ******************/
              private class Circle{
                //Define global private integers.
                private int x, y, radius;
                private boolean fill;


                //Object constructor, Definition.
                //Defines the info for a circle.
                public Circle(int a, int b, int size, int size_alt, boolean isFilled){
                  x = a;
                  y = b;
                  radius = ((int)size/2);
                  fill = isFilled;

                }

                public void draw(Graphics pen){
                  if(fill == true){
                    int diameter = (radius*2);
                    int xPosition = x - radius;
                    int yPosition = y - radius;
                    pen.fillOval(xPosition, yPosition, diameter, diameter);
                  } else {      
                    int diameter = (radius*2);
                    int xPosition = x - radius;
                    int yPosition = y - radius;
                    pen.drawOval(xPosition, yPosition, diameter, diameter);  
                  }
                }

              }
            }

现在为框架类。编码:

Traffic.java 是这个项目的文字 JFrame 部分:

            /****************************
              * Traffic.java
              * 
              * 
              ******************************/
            import javax.swing.*; //Import swing package.
            import java.awt.*; //Import awt package.
            import java.awt.event.*; //Import events package.



            public class Traffic extends JFrame{

              public static void main(String[] args){

                //Create new JFrame.
                JFrame lightbox = new JFrame("Light Box");


                //Create new LightboxPanel.
                TrafficPanel traffic = new TrafficPanel();    


                //Set focus to the LightboxPanel in order to allow key inputs.
                traffic.setFocusable(true);   


                //Set the Default Close Operation to exit when the "x" button is selected.
                lightbox.setDefaultCloseOperation(EXIT_ON_CLOSE);


                //Add the LightboxPanel to the Lightbox JFrame.
                lightbox.add(traffic);


                //Pack the frame to the warranted preferred size of the LightboxPanel.
                lightbox.pack();


                //Set the frame's visibility to true.
                lightbox.setVisible(true);
              }
            }

最后是面板类本身,TrafficPanel.java 更多的是调用方法从灯光绘制图形的面板。

编码:

            //*****************************************************************************
            //  TrafficPanel.java   
            //
            //  Panel that holds graphics for the traffic light simulation.
            //*****************************************************************************

            import java.util.Scanner;  // import Scanner class from util package
            import javax.swing.JPanel;  // import JPanel class from swing package 
            import javax.swing.JButton;
            import java.awt.*;         // import awt package 
            import java.awt.event.*;  // import event package from awt package
            import java.util.Random; // import Random class from the util package

            public class TrafficPanel extends JPanel
            {  
              private Lights shapes;  
              private final int RED = 1; //Creates switch constant.
              private final int YELLOW = 2; //Creates switch constant.
              private final int GREEN = 3; //Creates switch constant.
              private final int ALL_ON = 5; //Creates switch constant.
              private final int ALL_OFF = 6; //Creates switch constant.
              private final int FLASHING_YELLOW = 4; //Creates Flashing Yellow
              private final int DARK_YELLOW = 9; //Case in case.
              private int flashingColor = YELLOW; //Case in case.
              private boolean flashingYellow = false; //Creates false by default flashingYellow boolean.
              private Color lightColor; //Color variable lightcolor.
              private int colorSwitch; //Switch integer using constants and lightcolor.
              private int typeSwitch; //Also similar to above.
              private int x, y, lightswitch; //Other integers.


              public TrafficPanel()
              {    
                Lights shapes = new Lights();
                //KeyListener trafficListener = new KeyListener();
                addKeyListener(new KeyListener());    
                //Set the size.
                //Dimension preferred = new Dimension(800, 920);
                setPreferredSize(new Dimension(800, 920));    
                //Set the background.
                //Color bisque = new Color(255, 228, 196);
                setBackground(new Color(255, 228, 196));
              }

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

                //Normal state of panel. Initially offline.
                Lights shapes = new Lights();
                shapes.drawBox(g);    
                shapes.drawRedLight(g, false);
                shapes.drawYellowLight(g, false);
                shapes.drawGreenLight(g, false);
                shapes.drawFore(g);

                //Check state of light.
                switch(lightswitch){

                  case ALL_OFF:
                shapes.drawBox(g);    
                shapes.drawRedLight(g, false);
                shapes.drawYellowLight(g, false);
                shapes.drawGreenLight(g, false);
                shapes.drawFore(g);
                    break;



                  case ALL_ON:
                shapes.drawBox(g);    
                shapes.drawRedLight(g, true);
                shapes.drawYellowLight(g, true);
                shapes.drawGreenLight(g, true);
                shapes.drawFore(g);
                    break;

                  case RED:
                shapes.drawBox(g);    
                shapes.drawRedLight(g, true);
                shapes.drawYellowLight(g, false);
                shapes.drawGreenLight(g, false);
                shapes.drawFore(g);
                    break;


                  case GREEN:
                shapes.drawBox(g);    
                shapes.drawRedLight(g, false);
                shapes.drawYellowLight(g, false);
                shapes.drawGreenLight(g, true);
                shapes.drawFore(g);
                    break;


                  case YELLOW:
                shapes.drawBox(g);    
                shapes.drawRedLight(g, false);
                shapes.drawYellowLight(g, true);
                shapes.drawGreenLight(g, false);
                shapes.drawFore(g);
                    break;


                  case FLASHING_YELLOW: //If Flashing yellow.
                    switch(flashingColor){
                    case DARK_YELLOW:
                      flashingColor = YELLOW;
                      break;
                    case YELLOW:
                      flashingColor = DARK_YELLOW;
                      break;
                  }

                    try{
                      if(flashingColor == YELLOW){
                        shapes.flashOn(g);
                      }
                      Thread.sleep(250);
                      if(flashingColor == DARK_YELLOW){
                        shapes.flashOff(g); 
                      }
                    } catch(Exception e){}
                    break;    
                }



                repaint ();
              }

              /*********************
                * TrafficPanel$KeyListener.java
                * Author: Ian Effendi
                * 
                * Extension of KeyAdapter.
                * Inputs of 'o', 'f', and the spacebar all return actions.
                **********************/
              private class KeyListener extends KeyAdapter{


                //Occurs when a key is pressed.
                public void keyPressed(KeyEvent event){

                }

                //Occurs, only, when a key is released.
                public void keyReleased(KeyEvent event){

                  //If the key input is 'o'.
                  if(event.getKeyCode() == KeyEvent.VK_O){

                    flashingYellow = false;        

                    //Switch on what lightswitch is equal to.
                    switch(lightswitch){
                      case ALL_ON:
                        lightswitch = ALL_OFF;
                        break;
                      case ALL_OFF: 
                        lightswitch = ALL_ON;
                        break;
                      case RED: 
                        lightswitch = ALL_OFF;
                        break;
                      case YELLOW:
                        lightswitch = ALL_OFF;
                        break;
                      case GREEN:
                        lightswitch = ALL_OFF;
                        break;
                      case FLASHING_YELLOW:
                        lightswitch = ALL_OFF;
                        break;
                    }



                    //If the key input is the spacebar.
                  } else if(event.getKeyCode() == KeyEvent.VK_SPACE){

                    flashingYellow = false;

                    //Switch on what lightswitch is equal to.
                    switch(lightswitch){
                      case ALL_ON:
                        lightswitch = RED;
                        break;
                      case ALL_OFF:
                        lightswitch = ALL_OFF;
                        break;
                      case RED:
                        lightswitch = GREEN;
                        break;
                      case YELLOW:
                        lightswitch = RED;
                        break;
                      case GREEN:
                        lightswitch = YELLOW;
                        break;
                      case FLASHING_YELLOW:
                        lightswitch = YELLOW;
                        break;
                    }



                    //If the key input is 'f'.
                  } else if(event.getKeyCode() == KeyEvent.VK_F){

                    flashingYellow = true;

                    //Switch on what lightswitch is equal to.
                    switch(lightswitch){
                      case ALL_ON:
                        lightswitch = FLASHING_YELLOW;
                        break;
                      case ALL_OFF:
                        lightswitch = ALL_OFF;
                        break;
                      case RED:
                        lightswitch = FLASHING_YELLOW;
                        break;
                      case YELLOW:
                        lightswitch = FLASHING_YELLOW;
                        break;
                      case GREEN:
                        lightswitch = FLASHING_YELLOW;
                        break;
                      case FLASHING_YELLOW:
                        lightswitch = YELLOW;
                        break;
                    }


                    //If nothing is input, lightswitch returns itself.
                  } else {
                    int x = lightswitch;
                    lightswitch = x;
                  }      
                }


                //Occurs when an input is typed(not held).
                public void keyTyped(KeyEvent event){


                }
              }


            }//end of class

这就是所有的代码。请尽你所能提供帮助。任何提示也将不胜感激。

4

1 回答 1

2

当您收到 NullPointerException 时,这意味着您正在尝试使用一个尚未初始化的变量,一个尚未引用具体对象的变量。

解决方法是查看抛出 NPE 的行,NPE 错误文本会告诉你它是哪一行(这里是 ?LightBoxPanel 的第 211 行——一个不存在的类??),然后看看为什么其中之一您尝试在该行上使用的变量为空。您可能没有通过调用变量将对象分配给 Foobar myVariable = new Foobar();它。

还,

  • 不要在其中创建对象,paintComponent(...)因为此方法应仅用于绘画和绘画。
  • 不要打repaint()进来paintComponent(...)

编辑:你的问题是你隐藏了你的变量。您在类构造函数中重新声明它们,这意味着您在构造函数内部初始化的变量不是您认为它们是的类字段,而是构造函数的本地变量并且仅存在于构造函数中。因此,当您初始化这些局部变量时,您将类字段保留为空。解决方法:不要在构造函数中重新声明变量。

例如,改变这个:

class Lights {
   private final int RED = 1;
   private final int YELLOW = 2;

   // .... etc....

   private Rectangle grayBG, blackBG;
   private Circle red, green, yellow, redFore, greenFore, yellowFore;

   public Lights() {
      // the variables below are **local** to the constructor!
      Rectangle grayBG = new Rectangle(35, 35, 280, 830, true);
      Rectangle blackBG = new Rectangle(50, 50, 250, 800, true);

对此:

class Lights {
   private final int RED = 1;
   private final int YELLOW = 2;

   // .... etc....

   private Rectangle grayBG, blackBG;
   private Circle red, green, yellow, redFore, greenFore, yellowFore;

   public Lights() {
      grayBG = new Rectangle(35, 35, 280, 830, true); // *** note the difference
      blackBG = new Rectangle(50, 50, 250, 800, true); // *** note the difference
于 2013-04-24T03:47:09.377 回答