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();
            }
        }
    }
}

圈子.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)

感谢您的任何回复!

4

1 回答 1

1

让我们从...

我没有看到你在哪里初始化circles ArrayList...

然后继续...

您应该避免覆盖paint顶级容器,除了它们不是双缓冲的事实之外,它们通常还涉及构成顶级容器的一系列附加组件。

相反,您应该创建一个自定义组件,从JPanel例如扩展,并覆盖它的paintComponent方法。Swing 组件是双缓冲的,所以你不需要对此做任何特别的事情。

我也不明白为什么Circle需要实施Runnable.

如果要执行某种动画,则应使用用于修改整个状态的单个线程,然后应将其渲染为单个步骤。这使您可以保持同步并防止系统挨饿。

您还应该避免在任何paintXxx方法中修改或更新 UI 的状态。例如,不要调用repaint你的绘画方法......

看看Performing Custom Painting了解更多细节

于 2013-11-04T22:10:35.553 回答