3

这两天我一直在寻找这个问题的答案,但这似乎并没有解决太多。主要是因为我一开始并不真正了解导致我的错误的原因,也不知道如何解决问题。

我一直在尝试制作某种“动画”,其中一个图层在屏幕右侧生成圆圈并随着时间的推移将它们发送到左侧。问题是每次它打算产生一个圆圈时,它都没有出现,我得到一个错误。

Exception in thread "Thread-4" java.lang.NullPointerException
at Ball.draw(Ball.java:39)
at Ball.run(Ball.java:23)

这是导致错误的类:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;


public class Ball extends Thread{
    JPanel drawingPanel;
    private int x=400,y=200;
    private int dx=-2,dy=0;
    private static final int XSIZE=10,YSIZE=10;
    Random rdm = new Random();
    int y_rdm = rdm.nextInt(440)+30;

    public Ball(JPanel jp){
        drawingPanel=jp;
        dx-=1;

    }
    public void run(){
        draw();
        for (int i=0;i<1000;i++){
            try{
                Thread.sleep(10);
            }
            catch(InterruptedException e){} 
            move();
        }
    }
    private void move(){
        erase();
        changePos();
        draw();
    }
    private void draw(){
        Graphics g = drawingPanel.getGraphics();
        g.setColor(Color.WHITE);
        g.fillOval(x,y_rdm,XSIZE,YSIZE);
        g.dispose();
    }
    private void erase(){
        Graphics g=drawingPanel.getGraphics();
        g.setColor(drawingPanel.getBackground());
        g.fillOval(x,y_rdm,XSIZE,YSIZE);
        g.dispose();
    }

    private void changePos(){
        x+=dx;y_rdm+=dy;
    }



}

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.Timer;


public class BallPanel extends JPanel implements ActionListener{

    JPanel drawingPanel = new JPanel();
    public BallPanel(){

      int delay = 300;
      ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              Ball b= new Ball(drawingPanel);
                b.start();
          }
      };

      new Timer(delay, taskPerformer).start();

    }
    @Override
    public void actionPerformed(ActionEvent e) {

    }

}

import java.awt.BorderLayout;
import java.awt.Color;
import java.io.InputStream;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javazoom.jl.player.Player;


public class Window extends JFrame{

      private JLayeredPane layerpane;
      private JPanel up, down;

    public Window(){
          layerpane = new JLayeredPane();

          down = new JPanel();
          down.setBounds(0, 0, 450, 450);
          down.setBackground(new Color(0, 51, 102));
          layerpane.add(down, new Integer(1));

          BallPanel bp = new BallPanel();
          layerpane.add(bp, new Integer(2));
          bp.setBounds(0, 0, 450, 450);
          bp.setOpaque(!bp.isOpaque());

          Animation2 ani2 = new Ani2();
          ani2.setBounds(0, 0, 400, 450);
          layerpane.add(ani2, new Integer(3));

          ani2.setOpaque(!ani2.isOpaque());

         getContentPane().add(layerpane, BorderLayout.CENTER);

    }

        public static void main(String args[]){

        JFrame f = new Window();

        f.setVisible(true);
        f.setSize(450,450);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        try{
            URL url = new URL("file:///C://song.mp3");
            InputStream in = url.openStream();
            Player pl = new Player(in);
            pl.play();
            }        

            catch(Exception e){
                e.printStackTrace();
            } 


        }

    }

请告诉我是否需要包括我的其他课程,它们似乎有点无关紧要。

4

1 回答 1

5

getGraphics方法JComponent返回与Graphics关联的对象Component。但是,如果没有Graphics关联的对象,它将返回 null,这就是您的代码中的情况。

仅当A被添加到Component与某个Graphics对象关联的容器中,或者它是顶级容器(JFrameJDialogJApplet)时,它才与对象关联。

您的问题是您JPanel的不包含在任何顶级容器中,因此其关联Graphics对象为空。

要解决此问题,请确保在调用JPanel顶级容器之前getGraphics()已将需要重新绘制(例如,如果它被调整大小,或者被其他窗口阻止和解除阻止,...))。JPanelpaintComponent(Graphics g)paintComponent

(By the way, in your BallPanel class which extends JPanel, you define a new JPanel and pass it to Ball's constructor. You should be passing this to the the constructor, since the drawingPanel is never added to any container, but the BallPanel instance itself is. It really doesn't make sense to define a JPanel field inside a class which is itself a JPanel and have the field do the job that the class itself is supposed to do.)

于 2012-06-06T03:48:17.593 回答