2014-09-12 92 views
1

我正在处理下面的示例。 而我有困难。 必须让球脱离鼠标指针。 找到指针时改变方向。Java BounceBall鼠标事件

我想作为参数传递给鼠标位置传递给函数“移动”,但得到的错误:“在线程异常”线程2“显示java.lang.NullPointerException”

谁能给我一个提示如何做到这一点? 我迷路了。

代码:

public class SimpleBalls { 

    private Point mousePoint; 

    public static void main(String[] args) { 
     new SimpleBalls(); 
    } 

    public SimpleBalls() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager 
          .getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Spot"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       Balls balls = new Balls(); 
       frame.add(balls); 
       frame.setSize(400, 400); 
       frame.setVisible(true); 

       new Thread(new BounceEngine(balls)).start(); 

      } 
     }); 
    } 

    public static int random(int maxRange) { 
     return (int) Math.round((Math.random() * maxRange)); 
    } 

    public class Balls extends JPanel { 

     private List<Ball> ballsUp; 

     public Balls() { 
      ballsUp = new ArrayList<Ball>(25); 

      MouseAdapter handler = new MouseAdapter() { 

       @Override 
       public void mouseMoved(MouseEvent e) { 
        mousePoint = e.getPoint(); 
        // System.out.println(mousePoint); 
       } 

       @Override 
       public void mouseExited(MouseEvent e) { 
        mousePoint = e.getPoint(); 
       } 

      }; 

      addMouseListener(handler); 
      addMouseMotionListener(handler); 

      for (int index = 0; index < 10 + random(10); index++) { 
       ballsUp.add(new Ball(new Color(random(255), random(255), 
         random(255)))); 
      } 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      for (Ball ball : ballsUp) { 
       ball.paint(g2d); 
      } 
      g2d.dispose(); 
     } 

     public List<Ball> getBalls() { 
      return ballsUp; 
     } 
    } 

    public class BounceEngine implements Runnable { 

     private Balls parent; 

     public BounceEngine(Balls parent) { 
      this.parent = parent; 
     } 

     @Override 
     public void run() { 

      int width = getParent().getWidth(); 
      int height = getParent().getHeight(); 

      for (Ball ball : getParent().getBalls()) { 
       int x = random(width); 
       int y = random(height); 

       Dimension size = ball.getSize(); 

       if (x + size.width > width) { 
        x = width - size.width; 
       } 
       if (y + size.height > height) { 
        y = height - size.height; 
       } 

       ball.setLocation(new Point(x, y)); 

      } 

      while (getParent().isVisible()) { 

       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         getParent().repaint(); 
        } 
       }); 

       for (Ball ball : getParent().getBalls()) { 
        move(ball, mousePoint); 
       } 

       try { 
        Thread.sleep(100); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 

      } 

     } 

     public Balls getParent() { 
      return parent; 
     } 

     public void move(Ball ball, Point mouse) { 

      try { 
       Point p = ball.getLocation(); 
       Point speed = ball.getSpeed(); 
       Dimension size = ball.getSize(); 

       System.out.println(mouse.x); 

       int vx = speed.x; 
       int vy = speed.y; 

       int x = p.x; 
       int y = p.y; 

       if (x + vx < 0 || x + size.width + vx > getParent().getWidth()) { 
        vx *= -1; 
       } 
       if (y + vy < 0 || y + size.height + vy > getParent().getHeight()) { 
        vy *= -1; 
       } 
       x += vx; 
       y += vy; 

       ball.setSpeed(new Point(vx, vy)); 
       ball.setLocation(new Point(x, y)); 

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

     } 

    } 

    public class Ball { 

     private Color color; 
     private Point location; 
     private Dimension size; 
     private Point speed; 
     private int dimeter; 

     public Ball(Color color) { 
      Random rnd = new Random(); 
      dimeter = 10 + rnd.nextInt(35); 

      setColor(color); 

      speed = new Point(10 - random(20), 10 - random(20)); 
      size = new Dimension(dimeter, dimeter); 

     } 

     public Dimension getSize() { 
      return size; 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

     public void setLocation(Point location) { 
      this.location = location; 
     } 

     public Color getColor() { 
      return color; 
     } 

     public Point getLocation() { 
      return location; 
     } 

     public Point getSpeed() { 
      return speed; 
     } 

     public void setSpeed(Point speed) { 
      this.speed = speed; 
     } 

     protected void paint(Graphics2D g2d) { 

      Point p = getLocation(); 
      if (p != null) { 
       g2d.setColor(getColor()); 
       Dimension size = getSize(); 
       g2d.fillOval(p.x, p.y, size.width, size.height); 
      } 

     } 
    } 
} 

感谢。

编辑: 错误..

java.lang.NullPointerException 
    at balls.SimpleBalls$BounceEngine.move(SimpleBalls.java:170) 
    at balls.SimpleBalls$BounceEngine.run(SimpleBalls.java:146) 
    at java.lang.Thread.run(Unknown Source) 
+1

我们可以,如果你提供的堆栈跟踪... – StackFlowed 2014-09-12 20:21:43

+0

@Aeshang我把方法“移动”一个尝试捕捉,并当鼠标离开屏幕,是印刷错误,当你进入第一时间,并打印该位置。 但是在找到指针时不知道如何改变方向。 – 2014-09-12 20:31:40

+0

请注意,即使未初始化mousePoint,您仍可在'move()'中使用'mousePoint.x'。因此,直到您首次将它设置为响应鼠标事件时,该点才为空。所以一个NPE。 – kiheru 2014-09-12 20:32:11

回答

5

问题是mousepoint可能不是由时间move()被称为设置。请检查您的move()方法中是否有null。它看起来并不像你已经开始添加代码来“逃离鼠标指针” - 我猜你可以自己处理这个部分。

public void move(Ball ball, Point mouse) { 
    Point p = ball.getLocation(); 
    Point speed = ball.getSpeed(); 
    Dimension size = ball.getSize(); 

    if (mouse != null) { 
     System.out.println(mouse.x); // here 
    } 

    int vx = speed.x; 
    int vy = speed.y; 
    // ... 
+0

错误不再存在。现在改变方向。 – 2014-09-12 20:37:40

+0

@ FernandoA.W .:威士忌回答了你的问题,现在你正在改变这个问题。也许你应该接受这个答案,并且要么提出一个新问题,要么首先尝试自己解决方向问题的改变(这是我的投票),并且只有在它不起作用时才会带着一个新的问题回来新的代码尝试。 1+来回答。 – 2014-09-12 20:44:07

+0

@HovercraftFullOfEels它是有道理的。我试图解决aki,但又遇到了另一个问题。当鼠标在屏幕内时,所有球都会跑到屏幕的角落。 再次游览?或编辑帖子? – 2014-09-12 20:57:50