用Java交互式绘制多边形

时间:2014-09-17 18:41:02

标签: java swing graphics paintcomponent mouselistener

我正在编写一个程序,用户在其中左键单击至少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)

2 个答案:

答案 0 :(得分:0)

您的准则在多个方面存在缺陷:

1.仅仅实现MouseListener还不够,你必须注册它:

public DrawPolygon() {
    addMouseListener(this);
}

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

3.当Polygon更改时,必须重新绘制.JPanel。在 mouseClicked 结尾处调用 repaint();

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

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

答案 1 :(得分:0)

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

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

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