2013-11-04 38 views
0

我正在學習Java幾周,並且遇到了「項目」問題。由鼠標單擊問題引起的圓圈

我想寫一個簡單的(顯然不適合我)程序,通過鼠標點擊畫布上的一個圓圈,在鼠標點擊的座標上!

這裏是我的代碼:

MyGame3.java 包mygame3;

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import javax.swing.JFrame; 

public class MyGame3 extends JFrame{ 
    int WIDTH, HEIGHT; 

    Image dbImage; 
    Graphics dbg; 

    static ArrayList<Circle> circles; 

    public MyGame3(){ 
     WIDTH = 600; 
     HEIGHT = 600; 

     setSize(WIDTH, HEIGHT); 
     setTitle("My Game 3"); 
     setBackground(Color.white); 
     setResizable(false); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     addMouseListener(new MouseAdapter() { 
      public void mousePressed(MouseEvent e){ 
       System.out.println(e.getX() + " " + e.getY()); 
       circles.add(new Circle(e.getX(), e.getY())); 
      } 
     }); 
    } 

    @Override 
    public void paint(Graphics g){ 
     dbImage = createImage(getWidth(), getHeight()); 
     dbg = dbImage.getGraphics(); 
     draw(dbg); 
     g.drawImage(dbImage, 0, 0, this); 
    } 

    public void draw(Graphics g){ 
     if (circles.size() > 0){ 
      for (Circle c: circles){ 
       c.draw(g); 
      } 
      repaint(); 
     } 

    } 

    public static void main (String[] args){ 
     MyGame3 main = new MyGame3(); 

     if (circles.size() > 0){ 
      for (Circle c: circles){ 
       Thread circle = new Thread(c); 
       circle.start(); 
      } 
     } 
    } 
} 

Circle.java:

package mygame3; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.geom.Ellipse2D; 

public class Circle implements Runnable{  

    Ellipse2D circle; 

    public Circle(int x, int y){ 

     circle = new Ellipse2D.Double(x, y, 30, 30); 
    } 

    public void draw (Graphics g){ 
     g.setColor(Color.blue); 
     g.drawOval((int)circle.getX(), 
        (int)circle.getY(), 
        (int)circle.getWidth(), 
        (int)circle.getHeight()); 
    } 

    @Override 
    public void run() { 
     try{ 
      while(true){ 
       Thread.sleep(2); 
      } 
     } 
     catch(Exception e){ 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

這裏是我2次點擊屏幕上得到的錯誤:

run: 
Exception in thread "main" java.lang.NullPointerException 
    at mygame3.MyGame3.main(MyGame3.java:59) 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
    at mygame3.MyGame3.draw(MyGame3.java:47) 
    at mygame3.MyGame3.paint(MyGame3.java:42) 
    at javax.swing.RepaintManager$3.run(RepaintManager.java:819) 
    at javax.swing.RepaintManager$3.run(RepaintManager.java:796) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796) 
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769) 
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718) 
    at javax.swing.RepaintManager.access$1100(RepaintManager.java:62) 
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677) 
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733) 
    at java.awt.EventQueue.access$200(EventQueue.java:103) 
    at java.awt.EventQueue$3.run(EventQueue.java:694) 
    at java.awt.EventQueue$3.run(EventQueue.java:692) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
    at mygame3.MyGame3.draw(MyGame3.java:47) 
    at mygame3.MyGame3.paint(MyGame3.java:42) 
    at javax.swing.RepaintManager$3.run(RepaintManager.java:819) 
    at javax.swing.RepaintManager$3.run(RepaintManager.java:796) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796) 
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769) 
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718) 
    at javax.swing.RepaintManager.access$1100(RepaintManager.java:62) 
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677) 
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733) 
    at java.awt.EventQueue.access$200(EventQueue.java:103) 
    at java.awt.EventQueue$3.run(EventQueue.java:694) 
    at java.awt.EventQueue$3.run(EventQueue.java:692) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
245 386 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
    at mygame3.MyGame3$1.mousePressed(MyGame3.java:33) 
    at java.awt.Component.processMouseEvent(Component.java:6502) 
    at java.awt.Component.processEvent(Component.java:6270) 
    at java.awt.Container.processEvent(Container.java:2229) 
    at java.awt.Window.processEvent(Window.java:2022) 
    at java.awt.Component.dispatchEventImpl(Component.java:4861) 
    at java.awt.Container.dispatchEventImpl(Container.java:2287) 
    at java.awt.Window.dispatchEventImpl(Window.java:2719) 
    at java.awt.Component.dispatchEvent(Component.java:4687) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735) 
    at java.awt.EventQueue.access$200(EventQueue.java:103) 
    at java.awt.EventQueue$3.run(EventQueue.java:694) 
    at java.awt.EventQueue$3.run(EventQueue.java:692) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
    at java.awt.EventQueue$4.run(EventQueue.java:708) 
    at java.awt.EventQueue$4.run(EventQueue.java:706) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
245 386 
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
    at mygame3.MyGame3$1.mousePressed(MyGame3.java:33) 
    at java.awt.Component.processMouseEvent(Component.java:6502) 
    at java.awt.Component.processEvent(Component.java:6270) 
    at java.awt.Container.processEvent(Container.java:2229) 
    at java.awt.Window.processEvent(Window.java:2022) 
    at java.awt.Component.dispatchEventImpl(Component.java:4861) 
    at java.awt.Container.dispatchEventImpl(Container.java:2287) 
    at java.awt.Window.dispatchEventImpl(Window.java:2719) 
    at java.awt.Component.dispatchEvent(Component.java:4687) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735) 
    at java.awt.EventQueue.access$200(EventQueue.java:103) 
    at java.awt.EventQueue$3.run(EventQueue.java:694) 
    at java.awt.EventQueue$3.run(EventQueue.java:692) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
    at java.awt.EventQueue$4.run(EventQueue.java:708) 
    at java.awt.EventQueue$4.run(EventQueue.java:706) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
BUILD SUCCESSFUL (total time: 3 seconds) 

感謝任何迴應!

回答

1

讓我們先從...

我沒有看到任何地方你初始化circlesArrayList ...

然後移動到...

你應該避免覆蓋頂部paint除了它們不是雙緩衝的事實之外,它們通常還包括構成頂層容器的一系列附加組件。

相反,您應該創建一個自定義組件,例如從JPanel延伸,並覆蓋它的方法paintComponent。 Swing組件是雙重緩衝的,所以你不需要做任何特別的事情。

我也不明白爲什麼Circle應該需要執行Runnable

如果您想要執行某種動畫,您應該使用單個線程來修改整個狀態,然後應該將其作爲單個步驟呈現。這可以讓你保持同步並防止你餓死系統。

您還應該避免在任何paintXxx方法中修改或更新UI的狀態。例如,不要致電repaint在您的油漆方法...

看看Performing Custom Painting瞭解更多詳情