-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDrawPanel.java
More file actions
235 lines (195 loc) · 7.55 KB
/
Copy pathDrawPanel.java
File metadata and controls
235 lines (195 loc) · 7.55 KB
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
import dataStructure.DynamicStack;
import dataStructure.LinkedList;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import shape2D.Line;
import shape2D.Oval;
import shape2D.Rectangle;
import shape2D.Shape;
/*
* Author: Ri Xin Yang
* Date: July 9, 2019
* This class is a JPanel that handles the drawing and handles the events made by the mouse.
*/
public class DrawPanel extends JPanel {
// Initialize objects used in drawing.
private static final int LINE_MODE = 0;
private static final int RECT_MODE = 1;
private static final int OVAL_MODE = 2;
private boolean isFilled;
private boolean isGradient;
private boolean isDashed;
private Color shapeColor;
private Color gradientColor;
private int shapeMode;
private int lineWidth;
private int dashLength;
private Shape currentShape;
private JLabel statusBar;
private LinkedList<Shape> shapes;
private DynamicStack<Shape> redoStack;
// Constructor instantiates the main interactions within the panel.
public DrawPanel(JLabel statusLabel) {
// Initialize all the required objects for the panel.
statusBar = statusLabel;
isFilled = false;
isGradient = false;
shapeColor = Color.BLACK;
gradientColor = Color.BLACK;
shapeMode = LINE_MODE;
lineWidth = 1;
shapes = new LinkedList<>();
redoStack = new DynamicStack<>();
MouseEventListener drawPanelListener = new MouseEventListener();
// Mouse events.
addMouseListener(drawPanelListener);
addMouseMotionListener(drawPanelListener);
// Initiate color of background.
setBackground(Color.WHITE);
}
// Remove the latest action from drawn shapes, add it to the redo stack.
public void undo() {
Shape shape = shapes.removeLast();
if(shape != null) {
redoStack.push(shape);
}
// Repaint panel after any change.
repaint();
}
// Pop the redo stack, add it to the latest change of shapes if possible.
public void redo() {
Shape shape = redoStack.pop();
if (shape != null) {
shapes.addLast(shape);
}
// Repaint panel after any change.
repaint();
}
// Clear all shapes and redo stack as required.
public void clear() {
shapes.clear();
redoStack.clear();
// Repaint panel after any change.
repaint();
}
// A setter for isFilled.
public void setIsFilled(boolean isFilled) {
this.isFilled = isFilled;
}
// A setter for isGradient.
public void setIsGradient(boolean isGradient) {
this.isGradient = isGradient;
}
// A setter for shapeColor.
public void setShapeColor(Color shapeColor) {
this.shapeColor = shapeColor;
}
// A setter for shapeMode.
public void setShapeMode(int shapeMode) {
this.shapeMode = shapeMode;
}
// A setter for gradientColor.
public void setGradientColor(Color gradientColor) {
this.gradientColor = gradientColor;
}
// A setter for lineWidth.
public void setLineWidth(int lineWidth) {
this.lineWidth = lineWidth;
}
// A setter for isGradient.
public void setIsDashed(boolean isDashed) {
this.isDashed = isDashed;
}
// A setter for dashLength.
public void setDashLength(int dashLength) {
this.dashLength = dashLength;
}
class MouseEventListener extends MouseAdapter {
// Mouse press indicates a new shape drawing has been started
@Override
public void mousePressed(MouseEvent event) {
// Make sure command is from left clicks only to avoid call exceptions.
if (SwingUtilities.isLeftMouseButton(event)) {
// Decide which shape to draw depending on current shape type.
if (shapeMode == LINE_MODE) {
currentShape = new Line(event.getX(), event.getY(), event.getX(), event.getY(), shapeColor, lineWidth, isGradient, gradientColor, isDashed, dashLength);
}
else if (shapeMode == RECT_MODE) {
currentShape = new Rectangle(event.getX(), event.getY(), event.getX(), event.getY(), shapeColor, lineWidth, isGradient, gradientColor, isDashed, dashLength, isFilled);
}
else if (shapeMode == OVAL_MODE) {
currentShape = new Oval(event.getX(), event.getY(), event.getX(), event.getY(), shapeColor, lineWidth, isGradient, gradientColor, isDashed, dashLength, isFilled);
}
// Tell JVM to call paintComponent( g )
repaint();
}
}
// Mouse release indicates the new shape is finished
@Override
public void mouseReleased(MouseEvent event) {
if (SwingUtilities.isRightMouseButton(event)) {
// Cancel current drawing.
currentShape = null;
// Update panel.
repaint();
}
// Make sure command is from left clicks only to avoid call exceptions.
else if (SwingUtilities.isLeftMouseButton(event) && currentShape != null) {
// Update ending coordinates and switch color to current selected color
currentShape.setX2(event.getX());
currentShape.setY2(event.getY());
currentShape.setColor(shapeColor);
// Add the new shape to linked list containing all shapes.
shapes.addLast(currentShape);
// Clear redoStack after new shape is created, redo is now in another branch, discarded.
redoStack.clear();
// Get ready for the next shape to be drawn
currentShape = null;
// Update panel.
repaint();
}
}
// As mouse is dragged, update ending coordinates of currentShape and statusBar
@Override
public void mouseDragged(MouseEvent event) {
if (currentShape != null) {
currentShape.setX2(event.getX());
currentShape.setY2(event.getY());
repaint();
}
statusBar.setText(String.format("(%d, %d)", event.getX(), event.getY()));
}
// As mouse is moved, just update the statusBar
@Override
public void mouseMoved(MouseEvent event) {
statusBar.setText(String.format("(%d, %d)", event.getX(), event.getY()));
}
// handle event when mouse exits JPanel. Clear the status bar.
@Override
public void mouseExited( MouseEvent event ) {
statusBar.setText("(Mouse Outside)");
}
}
// This method is called automatically by the JVM when the window needs to be (re)drawn.
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Call the draw() method for each shape object in the array
Shape shape = null;
int size = shapes.size();
for (int counter = 0; counter < size; counter++) {
shape = shapes.removeFirst();
shapes.addLast(shape);
shape.draw(g);
}
// If a shape is in progress, draw it on top of all others
if (currentShape != null) {
currentShape.draw(g);
}
}
}