如何在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
相关产品推荐
相关产品推荐

