You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中连接顶点绘制凸多边形?

实现凸多边形绘制功能

我正在开发一款创建凸多边形的应用,设计逻辑是先设置多边形顶点,再生成完整图形。目前已实现顶点添加功能,现在需要完成点击“Draw Polygon”按钮后,将所有顶点连接成闭合多边形的功能。

当前效果:点击画布添加顶点时,会直接连接相邻顶点(未形成闭合图形)
目标效果:点击“Draw Polygon”按钮后,按顶点添加顺序连接所有点,并闭合最后一个顶点与第一个顶点的连线

原可运行代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;

public class MyPaint{
    
    public static void main(String[] args){    
        
        final PadDraw drawPad = new PadDraw();     

        JFrame frame = new JFrame("Draw Polygon");  
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 450, 300);

        Container contentPane = frame.getContentPane();
        ((JComponent) contentPane).setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        frame.setContentPane(contentPane);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        
        JButton buttonDrawPolygon = new JButton("Draw Polygon");
        buttonPanel.add(buttonDrawPolygon);
        
        JButton buttonReset = new JButton("Reset");
        buttonPanel.add(buttonReset);
        
        contentPane.add(drawPad, BorderLayout.CENTER);
    
    }
}


class PadDraw extends JComponent{

    private Image image;    
    private Graphics2D graphics2D;  
    private int currentX , currentY , oldX , oldY ;
    
    public PadDraw(){
    addMouseListener(new MouseAdapter(){
        public void mousePressed(MouseEvent e){
            oldX = e.getX();
            oldY = e.getY();
        }
    });
    
    addMouseListener(new MouseAdapter(){
        public void mousePressed(MouseEvent e){
            currentX = e.getX();
            currentY = e.getY();
            if(graphics2D != null) {
                graphics2D.drawLine(oldX, oldY, currentX, currentY);
                repaint();
                oldX = currentX;
                oldY = currentY;
            }
            System.out.println(oldX + " " + oldY);
        }
    });
    
}   
    
    public void paintComponent(Graphics g){
    if(image == null){
        image = createImage(getSize().width, getSize().height);
        graphics2D = (Graphics2D)image.getGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2D.setStroke(new BasicStroke(5));
    }
    g.drawImage(image, 0, 0, null);
    }

}

修改后的完整代码(实现目标功能)

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;

public class MyPaint {

    public static void main(String[] args) {
        final PadDraw drawPad = new PadDraw();

        JFrame frame = new JFrame("Draw Polygon");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 450, 300);

        Container contentPane = frame.getContentPane();
        ((JComponent) contentPane).setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));

        JPanel buttonPanel = new JPanel();
        buttonPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        contentPane.add(buttonPanel, BorderLayout.SOUTH);

        JButton buttonDrawPolygon = new JButton("Draw Polygon");
        buttonPanel.add(buttonDrawPolygon);
        // 绑定绘制按钮事件
        buttonDrawPolygon.addActionListener(e -> drawPad.drawPolygon());

        JButton buttonReset = new JButton("Reset");
        buttonPanel.add(buttonReset);
        // 绑定重置按钮事件
        buttonReset.addActionListener(e -> drawPad.resetCanvas());

        contentPane.add(drawPad, BorderLayout.CENTER);
        frame.setVisible(true);
    }
}

class PadDraw extends JComponent {

    private Image image;
    private Graphics2D graphics2D;
    // 用集合存储所有顶点坐标
    private ArrayList<Point> vertices = new ArrayList<>();

    public PadDraw() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 点击画布时记录顶点,不直接连线
                Point point = new Point(e.getX(), e.getY());
                vertices.add(point);
                // 绘制顶点标记,方便查看
                if (graphics2D != null) {
                    graphics2D.fillOval(point.x - 3, point.y - 3, 6, 6);
                    repaint();
                }
            }
        });
    }

    // 绘制闭合多边形
    public void drawPolygon() {
        if (vertices.size() < 3) {
            JOptionPane.showMessageDialog(this, "至少需要3个顶点才能绘制多边形!");
            return;
        }
        // 清空画布,重新绘制顶点和多边形
        resetCanvas(false);
        // 重新绘制顶点标记
        for (Point p : vertices) {
            graphics2D.fillOval(p.x - 3, p.y - 3, 6, 6);
        }
        // 转换顶点集合为数组,用于drawPolygon方法
        int[] xPoints = new int[vertices.size()];
        int[] yPoints = new int[vertices.size()];
        for (int i = 0; i < vertices.size(); i++) {
            xPoints[i] = vertices.get(i).x;
            yPoints[i] = vertices.get(i).y;
        }
        // 绘制闭合多边形
        graphics2D.drawPolygon(xPoints, yPoints, vertices.size());
        repaint();
    }

    // 重置画布,可选是否清空顶点集合
    public void resetCanvas() {
        resetCanvas(true);
    }

    private void resetCanvas(boolean clearVertices) {
        if (clearVertices) {
            vertices.clear();
        }
        // 清空画布
        graphics2D.setColor(getBackground());
        graphics2D.fillRect(0, 0, getWidth(), getHeight());
        graphics2D.setColor(Color.BLACK);
        repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        if (image == null) {
            image = createImage(getSize().width, getSize().height);
            graphics2D = (Graphics2D) image.getGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics2D.setStroke(new BasicStroke(2));
            graphics2D.setColor(Color.BLACK);
        }
        g.drawImage(image, 0, 0, null);
    }
}

关键改动说明

  • 新增ArrayList<Point>存储所有顶点坐标,替代原有的仅记录前后点的变量,方便后续统一处理
  • 调整鼠标点击事件:仅记录顶点并绘制顶点标记,不再直接连线
  • 给“Draw Polygon”按钮添加点击事件,触发多边形绘制逻辑:检查顶点数量(至少3个),将顶点转换为数组后用drawPolygon方法绘制闭合图形
  • 实现Reset按钮功能:清空画布和顶点集合,恢复初始状态
  • 优化画布重置逻辑,支持保留顶点的清空操作,方便绘制时重新渲染
  • 调整画笔样式,让顶点标记和多边形线条区分更明显

内容的提问来源于stack exchange,提问作者Panter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:05:55