2013-04-24 51 views
1

我没有编写很长的代码,但这是迄今为止我看到的最奇怪的错误。现在我知道它说空指针异常错误,这是,但它是一个特定的一个,我已经无法在网上找到一个多星期,现在两个。我遇到了一个非常独特的问题,我迫切需要帮助。 (我想出了一个解决方法,所以我会按时完成我的项目,但是这个错误仍然困扰着我)。 (代码将在问题的最底部)。针对空指针异常的任何解决方案由Java paintComponent()引用单独的类导致的错误?

项目: 要创建交通灯模拟题:

  • 启动时处于“关”,必须与 键盘上的“O”键打开。它也必须能够关闭。
  • 当按下“f”键时,它会导致黄灯闪烁。
  • 必须有

该问题的实际交通灯进展(绿色>黄色>红>绿色>等): 当在我的面板的方法的paintComponent(图形笔)时,由产生的多个错误它。 (屏幕截图在这里:Errors

我已经推断它在面板内创建对象后有一段时间(当你阅读代码时更有意义)。这是非常奇特的,因为解决方法只是将类方法复制并粘贴到原始面板中。

即,如果我的代码是用pen.drawOval绘制椭圆(插入参数),它将在面板类中持有paintComponent(Graphics pen)方法。但是,如果它属于Circle类,那么它就行不通。

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

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

我希望我能尽我所能解释它。

现在生成该区域的代码。

我有一种令人难过的感觉,那就是它那么简单,我忽略了它。这实际上是我最后的手段,因为我还没有发现为什么这会产生错误。

(?JComponent中可能会损坏难道仅仅是用户特定的?)

验证码:

考虑灯为一组类保持它内部的多个对象的私有类。 (这可能是问题,私人课程?)

  /****************** 
       * 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); 
        } 
       } 

       } 
      } 

现在为框架类。 代码:

交通。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 

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

+0

哪条线是造成NPE,LightBoxPanel.java线211?哦,下一次,请将您的例外信息作为文本发布在您的问题中,而不是图片。 – 2013-04-24 03:32:06

+2

另外,不要在'paintComponent(...)'中创建对象,**不要在'paintComponent(...)'内调用'repaint()'。 – 2013-04-24 03:34:04

回答

2

当你得到一个NullPointerException异常时,这意味着你试图使用一个未被初始化的变量,一个没有被引用到具体对象的变量。

解决方法是在投射NPE的线上看,NPE错误文本会告诉你它是哪一行(这里是LightBoxPanel的第211行 - 一个不存在的类??),然后看看为什么你试图在该行上使用的变量之一为null。您可能没有通过调用Foobar myVariable = new Foobar();来为该变量分配一个对象。

此外,

  • 不要建立在paintComponent(...)对象作为这个方法应该是绘画和绘画只。
  • 不要在paintComponent(...)内拨打repaint()

编辑:你的问题是你的阴影变量。你在类构造函数中重新声明它们,这意味着你在构造函数中初始化的变量不是你认为它们是的类字段,而是构造函数的局部变量,只存在于构造函数中。所以,当你初始化这些局部变量时,你将类字段保留为空。解决方案:不要在构造函数中重新声明变量。

例如,改变该:

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 
+0

非常感谢!它像一个魅力。关于粘贴错误。我目前正在**博士工作。 Java IDE **,它不允许复制控制台错误。目前,对于未来的项目,我正在将我的工作空间转移到Netbeans IDE,因为我目前正在处理其他语言。在解决'paintComponent(...)'的其他空指针异常错误中,并未暗示此解决方案。其他人指出文件本身的问题,而不是其他类的引用,这些引用将我的想法缩小为“那么我的错误必须是JComponent”。 谢谢,抱歉错误混乱。 – 2013-04-24 21:33:23

+0

@IanAlexanderEffendi:很高兴你有东西可以运作,欢迎您的光临! – 2013-04-24 22:09:14