3

私はこれに対する答えを2日間探していましたが、それはあまり解決しなかったようです。そもそも何が原因でエラーが発生しているのかよくわからず、問題の修正方法もわからないことが主な理由です。

私はある種の「アニメーション」を作成しようとしてきました。その中のレイヤーの1つが画面の右側に円を生成し、時間の経過とともにそれらを左側に送信します。問題は、サークルをスポーンすることを意図しているたびに、それが表示されず、エラーが発生することです。

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たオブジェクトを返します。ただし、オブジェクトが関連付けられていない場合は、null が返されます。これは、コードの場合です。GraphicsComponentGraphics

Componentは、オブジェクトに関連付けられているGraphicsコンテナに追加された場合、またはトップレベル コンテナ ( JFrameJDialog、およびJApplet) である場合にのみ、オブジェクトに関連付けられます。

ここでの問題は、JPanel最上位のコンテナ内に含まれていないため、関連付けられているGraphicsオブジェクトが null であることです。

JPanelこの問題を解決するには、呼び出す前に最上位のコンテナーに を追加したことを確認するかgetGraphics()、代わりにそのメソッドを拡張JPanelしてオーバーライドして描画を行います (親コンテナーが呼び出されるたびにメソッドが自動的に呼び出されるpaintComponent(Graphics g)ため、2 番目のオプションが推奨されます)。paintComponent再描画する必要があります(たとえば、サイズが変更された場合、または他のウィンドウによってブロックおよびブロック解除された場合...))。

(ちなみに、BallPanelを拡張するクラスではJPanel、 new を定義してJPanelのコンストラクターに渡します。はコンテナーに追加されることはないため、コンストラクターにBall渡す必要がありますが、インスタンス自体は追加されます。実際には追加されません。それ自体が であるクラス内にフィールドを定義し、そのフィールドにクラス自体が行うべき仕事をさせるのは意味がありません。)thisdrawingPanelBallPanelJPanelJPanel

于 2012-06-06T03:48:17.593 に答える