使用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
Serializableis non-negotiable here—it lets us write the entireDrawingobject directly to a file (and read it back) without manually handling each point's data. - Make sure your existing
Point2Dclass also implementsSerializable(if it doesn't, just addimplements Serializableto 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
相关产品推荐
相关产品推荐

