1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
| // 绘图形状接口
interface Shape extends Cloneable {
void draw();
Shape clone();
String getInfo();
}
// 圆形
class Circle implements Shape {
private int x, y, radius;
private String color;
public Circle(int x, int y, int radius, String color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
@Override
public void draw() {
System.out.println("绘制圆形:位置(" + x + "," + y + ") 半径=" + radius + " 颜色=" + color);
}
@Override
public Circle clone() {
return new Circle(x, y, radius, color);
}
@Override
public String getInfo() {
return "圆形(" + x + "," + y + "," + radius + "," + color + ")";
}
// Getters and Setters
public void setPosition(int x, int y) { this.x = x; this.y = y; }
public void setRadius(int radius) { this.radius = radius; }
public void setColor(String color) { this.color = color; }
}
// 矩形
class Rectangle implements Shape {
private int x, y, width, height;
private String color;
public Rectangle(int x, int y, int width, int height, String color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
@Override
public void draw() {
System.out.println("绘制矩形:位置(" + x + "," + y + ") 尺寸=" + width + "x" + height + " 颜色=" + color);
}
@Override
public Rectangle clone() {
return new Rectangle(x, y, width, height, color);
}
@Override
public String getInfo() {
return "矩形(" + x + "," + y + "," + width + "x" + height + "," + color + ")";
}
public void setPosition(int x, int y) { this.x = x; this.y = y; }
public void setSize(int width, int height) { this.width = width; this.height = height; }
public void setColor(String color) { this.color = color; }
}
// 绘图画布
class DrawingCanvas {
private List<Shape> shapes;
private String canvasName;
private String backgroundColor;
public DrawingCanvas() {
this.shapes = new ArrayList<>();
this.canvasName = "未命名画布";
this.backgroundColor = "白色";
}
// 添加形状
public void addShape(Shape shape) {
shapes.add(shape);
System.out.println("添加形状:" + shape.getInfo());
}
// 删除形状
public void removeShape(int index) {
if (index >= 0 && index < shapes.size()) {
Shape removed = shapes.remove(index);
System.out.println("删除形状:" + removed.getInfo());
}
}
// 移动形状
public void moveShape(int index, int deltaX, int deltaY) {
if (index >= 0 && index < shapes.size()) {
Shape shape = shapes.get(index);
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
// 这里简化处理,实际应该有更好的方法
System.out.println("移动圆形:" + shape.getInfo());
} else if (shape instanceof Rectangle) {
Rectangle rect = (Rectangle) shape;
System.out.println("移动矩形:" + shape.getInfo());
}
}
}
// 设置画布属性
public void setCanvasName(String name) {
this.canvasName = name;
System.out.println("画布名称设置为:" + name);
}
public void setBackgroundColor(String color) {
this.backgroundColor = color;
System.out.println("背景色设置为:" + color);
}
// 绘制所有形状
public void drawAll() {
System.out.println("=== 绘制画布:" + canvasName + " ===");
System.out.println("背景色:" + backgroundColor);
if (shapes.isEmpty()) {
System.out.println("画布为空");
} else {
for (int i = 0; i < shapes.size(); i++) {
System.out.print((i + 1) + ". ");
shapes.get(i).draw();
}
}
System.out.println("========================");
}
// 创建快照
public CanvasSnapshot createSnapshot(String description) {
// 深拷贝所有形状
List<Shape> shapesCopy = new ArrayList<>();
for (Shape shape : shapes) {
shapesCopy.add(shape.clone());
}
return new CanvasSnapshot(shapesCopy, canvasName, backgroundColor, description);
}
// 从快照恢复
public void restoreFromSnapshot(CanvasSnapshot snapshot) {
this.shapes = new ArrayList<>();
for (Shape shape : snapshot.getShapes()) {
this.shapes.add(shape.clone());
}
this.canvasName = snapshot.getCanvasName();
this.backgroundColor = snapshot.getBackgroundColor();
System.out.println("已恢复快照:" + snapshot.getDescription());
}
public List<Shape> getShapes() { return shapes; }
public String getCanvasName() { return canvasName; }
public String getBackgroundColor() { return backgroundColor; }
}
// 画布快照
class CanvasSnapshot {
private final List<Shape> shapes;
private final String canvasName;
private final String backgroundColor;
private final String description;
private final long timestamp;
public CanvasSnapshot(List<Shape> shapes, String canvasName, String backgroundColor, String description) {
this.shapes = new ArrayList<>(shapes);
this.canvasName = canvasName;
this.backgroundColor = backgroundColor;
this.description = description;
this.timestamp = System.currentTimeMillis();
}
public List<Shape> getShapes() { return shapes; }
public String getCanvasName() { return canvasName; }
public String getBackgroundColor() { return backgroundColor; }
public String getDescription() { return description; }
public long getTimestamp() { return timestamp; }
@Override
public String toString() {
return "快照[" + description + " - " + shapes.size() + "个形状 - " +
new SimpleDateFormat("HH:mm:ss").format(new Date(timestamp)) + "]";
}
}
// 绘图应用的撤销重做管理器
class DrawingUndoRedoManager {
private List<CanvasSnapshot> history;
private int currentIndex;
private final int maxHistory;
public DrawingUndoRedoManager(int maxHistory) {
this.history = new ArrayList<>();
this.currentIndex = -1;
this.maxHistory = maxHistory;
}
public void saveSnapshot(CanvasSnapshot snapshot) {
// 清除当前位置之后的历史
if (currentIndex < history.size() - 1) {
history.subList(currentIndex + 1, history.size()).clear();
}
history.add(snapshot);
currentIndex++;
// 限制历史大小
if (history.size() > maxHistory) {
history.remove(0);
currentIndex--;
}
System.out.println("保存快照:" + snapshot);
}
public CanvasSnapshot undo() {
if (canUndo()) {
currentIndex--;
CanvasSnapshot snapshot = history.get(currentIndex);
System.out.println("撤销到:" + snapshot);
return snapshot;
}
System.out.println("无法撤销");
return null;
}
public CanvasSnapshot redo() {
if (canRedo()) {
currentIndex++;
CanvasSnapshot snapshot = history.get(currentIndex);
System.out.println("重做到:" + snapshot);
return snapshot;
}
System.out.println("无法重做");
return null;
}
public boolean canUndo() {
return currentIndex > 0;
}
public boolean canRedo() {
return currentIndex < history.size() - 1;
}
public void showHistory() {
System.out.println("=== 操作历史 ===");
for (int i = 0; i < history.size(); i++) {
String marker = (i == currentIndex) ? "→ " : " ";
System.out.println(marker + i + ": " + history.get(i));
}
System.out.println("===============");
}
}
// 绘图应用使用示例
public class DrawingAppExample {
public static void main(String[] args) throws InterruptedException {
DrawingCanvas canvas = new DrawingCanvas();
DrawingUndoRedoManager undoRedoManager = new DrawingUndoRedoManager(10);
// 初始状态
canvas.setCanvasName("我的画作");
undoRedoManager.saveSnapshot(canvas.createSnapshot("初始空画布"));
// 添加一些形状
System.out.println("\n=== 开始绘图 ===");
canvas.addShape(new Circle(100, 100, 50, "红色"));
undoRedoManager.saveSnapshot(canvas.createSnapshot("添加红色圆形"));
Thread.sleep(500);
canvas.addShape(new Rectangle(200, 150, 80, 60, "蓝色"));
undoRedoManager.saveSnapshot(canvas.createSnapshot("添加蓝色矩形"));
Thread.sleep(500);
canvas.addShape(new Circle(300, 200, 30, "绿色"));
undoRedoManager.saveSnapshot(canvas.createSnapshot("添加绿色圆形"));
// 显示当前画布
canvas.drawAll();
// 设置背景色
System.out.println("\n=== 修改背景 ===");
canvas.setBackgroundColor("浅灰色");
undoRedoManager.saveSnapshot(canvas.createSnapshot("修改背景色"));
canvas.drawAll();
// 显示历史
undoRedoManager.showHistory();
// 撤销操作
System.out.println("\n=== 撤销操作 ===");
CanvasSnapshot snapshot = undoRedoManager.undo();
if (snapshot != null) {
canvas.restoreFromSnapshot(snapshot);
canvas.drawAll();
}
snapshot = undoRedoManager.undo();
if (snapshot != null) {
canvas.restoreFromSnapshot(snapshot);
canvas.drawAll();
}
// 重做操作
System.out.println("\n=== 重做操作 ===");
snapshot = undoRedoManager.redo();
if (snapshot != null) {
canvas.restoreFromSnapshot(snapshot);
canvas.drawAll();
}
// 在中间状态进行新操作
System.out.println("\n=== 分支操作 ===");
canvas.addShape(new Rectangle(50, 50, 40, 40, "黄色"));
undoRedoManager.saveSnapshot(canvas.createSnapshot("添加黄色小矩形"));
canvas.drawAll();
undoRedoManager.showHistory();
}
}
|