【问题标题】:Drawing polygons interactively in Java在 Java 中交互式绘制多边形
【发布时间】:2014-09-17 18:41:01
【问题描述】:

我正在编写一个程序,其中用户左键单击至少 3 个位置,当用户右键单击时,将绘制一个多边形,这些位置作为顶点。框架已创建,但程序不工作。它说 线程“AWT-EventQueue-0”java.lang.NullPointerException 中的异常。我不明白为什么。

我是 Java 图形新手,这是我第一次使用 MouseListener。

主类:

import javax.swing.JFrame;

public class Main 
{
    public static void main(String[] args) 
    {
        DrawPolygon dp = new DrawPolygon();
        JFrame f = new JFrame("Draw Polygon");
        f.getContentPane().add(dp);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setSize(700,700);
        f.setVisible(true); 
    }
}

DrawPolygon 类:

import java.awt.Polygon;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

public class DrawPolygon extends JPanel implements MouseListener 
{
    int Vertices = 0; //to store number of vertices

    //use vector instead of array because dynamic structure is required as there can be any number of vertices >= 3
    Vector<Integer> PolyX = new Vector<Integer>(3,1); //to store x coordinates
    Vector<Integer> PolyY = new Vector<Integer> (3,1); //to store y coordinates

    Polygon poly; //polygon to draw

    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) //left button is clicked - creating new vertex for polygon
        {
            Vertices++; //new polygon vertex is created
            PolyX.addElement(e.getX()); //store x coordinates in vector
            PolyY.addElement(e.getY()); //store y coordinates in vector
        }
        else if (e.getButton() == MouseEvent.BUTTON2) //right button is clicked - instruction to draw polygon
        {
            if (Vertices < 3) //a polygon has at least 3 vertices
            {
                JOptionPane.showMessageDialog(null, "There must be at least 3 clicks.");
            }
            else //draw polygon
            {
                //create array to pass coordinates to Polygon which accepts only int[] as coordinates
                int[] xPoints = new int[PolyX.size() - 1];
                int[] yPoints = new int[PolyY.size() - 1];
                //copy coordinates from vector to array
                for (int i = 0; i < Vertices; i++)
                {
                    xPoints[i] = PolyX.elementAt(i + 1);
                }
                for (int i = 0; i < Vertices; i++)
                {
                    yPoints[i] = PolyY.elementAt(i + 1);
                }
                //draw polygon
                poly = new Polygon(xPoints, yPoints, Vertices);
            }
        }
    }

    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}

    public void paintComponent(Graphics g)
    {
        Graphics2D graphx = (Graphics2D) g;
        graphx.draw(poly);
    }
}

完整的错误信息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at java.awt.geom.Path2D$Float.<init>(Path2D.java:232)
    at java.awt.geom.Path2D$Float.<init>(Path2D.java:207)
    at sun.java2d.pipe.BufferedRenderPipe.draw(BufferedRenderPipe.java:525)
    at sun.java2d.pipe.PixelToParallelogramConverter.draw(PixelToParallelogramConverter.java:148)
    at sun.java2d.pipe.ValidatePipe.draw(ValidatePipe.java:154)
    at sun.java2d.SunGraphics2D.draw(SunGraphics2D.java:2461)
    at assignment1.DrawPolygon.paintComponent(DrawPolygon.java:61)
    at javax.swing.JComponent.paint(JComponent.java:1053)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paint(JComponent.java:1062)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paint(JComponent.java:1062)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5224)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1532)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1455)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1252)
    at javax.swing.JComponent.paint(JComponent.java:1039)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
    at java.awt.Container.paint(Container.java:1973)
    at java.awt.Window.paint(Window.java:3901)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
    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:1680)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at java.awt.geom.Path2D$Float.<init>(Path2D.java:232)
    at java.awt.geom.Path2D$Float.<init>(Path2D.java:207)
    at sun.java2d.pipe.BufferedRenderPipe.draw(BufferedRenderPipe.java:525)
    at sun.java2d.pipe.PixelToParallelogramConverter.draw(PixelToParallelogramConverter.java:148)
    at sun.java2d.pipe.ValidatePipe.draw(ValidatePipe.java:154)
    at sun.java2d.SunGraphics2D.draw(SunGraphics2D.java:2461)
    at assignment1.DrawPolygon.paintComponent(DrawPolygon.java:61)
    at javax.swing.JComponent.paint(JComponent.java:1053)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paint(JComponent.java:1062)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paint(JComponent.java:1062)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:886)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5224)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1532)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1455)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1252)
    at javax.swing.JComponent.paint(JComponent.java:1039)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
    at java.awt.Container.paint(Container.java:1973)
    at java.awt.Window.paint(Window.java:3901)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
    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:1680)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

【问题讨论】:

  • 包括错误堆栈跟踪。
  • 您应该在您发布的代码中指出发生此错误的行
  • 我在帖子中添加了完整的错误消息。
  • 您的 paintComponent 方法可能在您初始化 poly 之前被调用。
  • paintComponent 方法应该放在哪里?

标签: java swing graphics paintcomponent mouselistener


【解决方案1】:

您的代码在多个方面存在缺陷:

1.只实现MouseListener是不够的,还得注册:

public DrawPolygon() {
    addMouseListener(this);
}

2.根据 Vertices-Vector 长度的错误假设: 为什么PolyX.elementAt(i + 1)??

3.当多边形发生变化时,JPanel 必须重新绘制。在 mouseClicked 结束时调用 repaint();

4.如果已经像这样初始化,只绘制多边形:

public void paintComponent(Graphics g)
{
    if (poly != null) {
        Graphics2D graphx = (Graphics2D) g;
        graphx.draw(poly);
    }
}

【讨论】:

    【解决方案2】:

    如果您使用的是 OpenGL,想想多边形是什么,它是由许多三角形组成的形状,例如,如果形状是立方体,则需要 12 个由浮点数组成的三角形:

    Float[] polygon = {1.0f , 0.0f};
    

    无论如何你都知道它是如何工作的,并且还要观察多边形的数量,三角形越多,渲染所需的时间就越长。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-30
      相关资源
      最近更新 更多