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

Java简易绘图工具改进需求:实现笔画点连线绘制文字

Java简易绘图程序:实现字母笔画的直线连接方案

我想要修改自己的Java简易绘图程序,将构成单个字母笔画的一系列点用直线连接,以实现文字绘制功能,但目前没有明确的实现思路,希望获取相关参考方案。我尝试使用drawLine方法实现,但未达到预期效果。

我当前的代码

初始版本(绘制点)

package tool;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

}

public class MyPaintApp extends JFrame {
    int x, y;
    Vector<Point> list = new Vector<>();

    class MyPanel extends JPanel {
        public MyPanel() {
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent event) {
                    x = event.getX();
                    y = event.getY();
                    list.add(new Point(x, y));
                    repaint();
                }
            });
        }

        public void paintComponent(Graphics g) {

            super.paintComponent(g);
            for (Point p : list)
                g.fillOval(p.x, p.y, 4, 4);
        }
    }

    public MyPaintApp() {
        setSize(600, 450);
        setLocation(400, 0);
        setTitle("My Paint");
        add(new MyPanel());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

尝试drawLine的版本

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

}

public class MyPaintApp extends JFrame {
    int x, y;
    Vector<Point> list = new Vector<>();
    Vector<Vector<Point>> list1 = new Vector<>();

    class MyPanel extends JPanel {
        public MyPanel() {
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent event) {
                    x = event.getX();
                    y = event.getY();
                    list.add(new Point(x, y));
                    repaint();
                }
            });
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (int i = 0; i < list.size() - 1; i++) {
                Point p1 = list.get(i);
                Point p2 = list.get(i + 1);
                g.drawLine(p1.x, p1.y, p2.x, p2.y);  
            }
        }
    }

    public MyPaintApp() {
        setSize(600, 450);
        setLocation(400, 0);
        setTitle("My Paint");
        add(new MyPanel());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

问题分析与解决方案

核心问题

当前代码存在两个关键问题:

  • 未区分独立笔画:所有拖拽产生的点都存在同一个列表中,绘制多笔画字母(比如A、B)时,不同笔画的端点会被错误连接。
  • 缺少笔画生命周期管理:没有触发笔画开始/结束的逻辑,无法区分不同的笔画段。

实现步骤

  1. 数据结构优化:用Vector<Vector<Point>>存储所有笔画,每个子Vector<Point>对应一个独立笔画(比如一笔完成的线条)。
  2. 完善鼠标事件:
    • mousePressed:按下鼠标时,初始化当前笔画的点列表,准备记录新笔画。
    • mouseDragged:拖拽时,将当前点加入当前笔画的列表,触发重绘。
    • mouseReleased:松开鼠标时,将当前笔画存入总列表,结束当前笔画的记录。
  3. 重绘逻辑调整:遍历总笔画列表,对每个笔画内的连续点依次调用drawLine连接。

修正后的完整代码

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class MyPaintApp extends JFrame {
    // 存储所有笔画,每个子Vector对应一个独立笔画
    Vector<Vector<Point>> allStrokes = new Vector<>();
    // 当前正在绘制的笔画
    Vector<Point> currentStroke;

    class MyPanel extends JPanel {
        public MyPanel() {
            addMouseListener(new MouseAdapter() {
                // 按下鼠标,开始新笔画
                public void mousePressed(MouseEvent e) {
                    currentStroke = new Vector<>();
                    currentStroke.add(new Point(e.getX(), e.getY()));
                    repaint();
                }

                // 松开鼠标,结束当前笔画并加入总列表
                public void mouseReleased(MouseEvent e) {
                    if (currentStroke != null && !currentStroke.isEmpty()) {
                        allStrokes.add(currentStroke);
                        currentStroke = null;
                        repaint();
                    }
                }
            });

            addMouseMotionListener(new MouseAdapter() {
                // 拖拽鼠标,记录当前点
                public void mouseDragged(MouseEvent e) {
                    if (currentStroke != null) {
                        currentStroke.add(new Point(e.getX(), e.getY()));
                        repaint();
                    }
                }
            });
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            // 绘制所有已完成的笔画
            for (Vector<Point> stroke : allStrokes) {
                drawStroke(g, stroke);
            }
            
            // 绘制当前正在进行的笔画
            if (currentStroke != null && currentStroke.size() > 1) {
                drawStroke(g, currentStroke);
            }
        }

        // 辅助方法:绘制单个笔画的连续点
        private void drawStroke(Graphics g, Vector<Point> stroke) {
            for (int i = 0; i < stroke.size() - 1; i++) {
                Point p1 = stroke.get(i);
                Point p2 = stroke.get(i + 1);
                g.drawLine(p1.x, p1.y, p2.x, p2.y);
            }
        }
    }

    public MyPaintApp() {
        setSize(600, 450);
        setLocation(400, 0);
        setTitle("My Paint");
        add(new MyPanel());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new MyPaintApp();
    }
}

效果说明

修正后的程序可以:

  • 每按下鼠标并拖拽绘制一段独立笔画,松开鼠标结束该笔画
  • 不同笔画之间不会自动连接,完美支持多笔画字母的绘制
  • 实时显示当前正在绘制的笔画和已完成的所有笔画

内容的提问来源于stack exchange,提问作者Hưng Nguyễn Thành

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:27:05