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

使用StdDraw在Java中实现简易版MS Paint的技术问询

实现简易版MS Paint(基于Java StdDraw)

Alright, let's build this simple MS Paint-style program using Java's StdDraw library. We'll break down each required component step by step, using the provided Point2D class and adding our custom Drawing class plus a main interaction handler.

1. 核心容器类:Drawing(实现Serializable)

This class will store all the points that make up our drawing, and handle the serialization/deserialization needed for save/load functionality.

import java.io.Serializable;
import java.util.ArrayList;

public class Drawing implements Serializable {
    // 存储所有绘图点的集合
    private ArrayList<Point2D> points;

    // 构造方法:初始化空绘图集合
    public Drawing() {
        points = new ArrayList<>();
    }

    // 添加单个点到绘图中
    public void addPoint(Point2D point) {
        points.add(point);
    }

    // 获取所有绘图点(用于渲染)
    public ArrayList<Point2D> getPoints() {
        return points;
    }

    // 清空当前绘图
    public void clear() {
        points.clear();
    }
}

关键细节:

  • Implementing Serializable is non-negotiable here—it lets us write the entire Drawing object directly to a file (and read it back) without manually handling each point's data.
  • Make sure your existing Point2D class also implements Serializable (if it doesn't, just add implements Serializable to its class definition—no extra methods are required for basic serialization).

2. 主交互程序:SimplePaint

This class handles user input (mouse drags for drawing, keyboard shortcuts for save/load/clear), renders the drawing via StdDraw, and manages the save/load logic.

import java.io.*;
import java.awt.Color;

public class SimplePaint {
    private static Drawing currentDrawing = new Drawing();
    private static boolean isDrawing = false;

    public static void main(String[] args) {
        // 初始化StdDraw画布
        StdDraw.setCanvasSize(800, 600);
        StdDraw.setXscale(0, 800);
        StdDraw.setYscale(0, 600);
        StdDraw.setPenColor(Color.BLACK);
        StdDraw.setPenRadius(0.005);
        StdDraw.clear(Color.WHITE);

        // 主循环:处理交互与渲染
        while (true) {
            // 处理鼠标拖动绘图
            if (StdDraw.isMousePressed()) {
                if (!isDrawing) isDrawing = true;
                double x = StdDraw.mouseX();
                double y = StdDraw.mouseY();
                Point2D newPoint = new Point2D(x, y); // 假设Point2D有x/y构造方法
                currentDrawing.addPoint(newPoint);
                StdDraw.point(x, y); // 实时绘制当前点
            } else {
                isDrawing = false;
            }

            // 处理键盘快捷键
            handleKeyboardInputs();

            StdDraw.show(20); // 控制渲染帧率
        }
    }

    private static void handleKeyboardInputs() {
        // 按's'保存绘图到文件
        if (StdDraw.isKeyPressed('s')) {
            saveDrawing("drawing.ser");
            System.out.println("Drawing saved to drawing.ser!");
            // 防止重复触发,等待按键释放
            while (StdDraw.isKeyPressed('s')) StdDraw.show(20);
        }

        // 按'l'加载已保存的绘图
        if (StdDraw.isKeyPressed('l')) {
            loadDrawing("drawing.ser");
            redrawDrawing();
            System.out.println("Drawing loaded from drawing.ser!");
            while (StdDraw.isKeyPressed('l')) StdDraw.show(20);
        }

        // 按'c'清空画布
        if (StdDraw.isKeyPressed('c')) {
            currentDrawing.clear();
            StdDraw.clear(Color.WHITE);
            System.out.println("Drawing cleared!");
            while (StdDraw.isKeyPressed('c')) StdDraw.show(20);
        }
    }

    // 序列化保存绘图
    private static void saveDrawing(String filename) {
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename))) {
            out.writeObject(currentDrawing);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 反序列化加载绘图
    private static void loadDrawing(String filename) {
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename))) {
            currentDrawing = (Drawing) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 重新绘制整个加载的绘图
    private static void redrawDrawing() {
        StdDraw.clear(Color.WHITE);
        for (Point2D point : currentDrawing.getPoints()) {
            StdDraw.point(point.getX(), point.getY()); // 假设Point2D有getX()/getY()方法
        }
    }
}

3. 补充:完善Point2D类(如果需要)

If your provided Point2D class doesn't implement Serializable yet, update it like this:

import java.io.Serializable;

public class Point2D implements Serializable {
    private double x;
    private double y;

    public Point2D(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() { return x; }
    public double getY() { return y; }
}

功能使用说明

  • 绘图:按住鼠标左键拖动即可绘制连续的黑色点(模拟画笔)
  • 保存:按下 s 键,绘图会保存到项目根目录的 drawing.ser 文件中
  • 加载:按下 l 键,会从 drawing.ser 加载之前保存的绘图并渲染到画布
  • 清空:按下 c 键,一键清空当前画布

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:53:06