-
Notifications
You must be signed in to change notification settings - Fork 0
/
Canvas.java
250 lines (229 loc) · 7.77 KB
/
Canvas.java
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
package ch.hslu.prg1.allg.hanoi;
import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.*;
/**
* Canvas is a class to allow for simple graphical drawing on a canvas.
* This is a modification of the general purpose Canvas, specially made for
* the BlueJ "shapes" example.
*
* @author: Bruce Quig
* @author: Michael Kölling (mik)
*
* @version 2011.07.31
*/
public class Canvas
{
// Note: The implementation of this class (specifically the handling of
// shape identity and colors) is slightly more complex than necessary. This
// is done on purpose to keep the interface and instance fields of the
// shape objects in this project clean and simple for educational purposes.
private static Canvas canvasSingleton;
/**
* Factory method to get the canvas singleton object.
*/
public static Canvas getCanvas()
{
if(canvasSingleton == null) {
canvasSingleton = new Canvas("The Towers of Hanoi", 720, 300,
new Color(40, 40, 40));
}
canvasSingleton.setVisible(true);
return canvasSingleton;
}
// ----- instance part -----
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColor;
private Image canvasImage;
private List<Object> objects;
private HashMap<Object, ShapeDescription> shapes;
/**
* Create a Canvas.
* @param title title to appear in Canvas Frame
* @param width the desired width for the canvas
* @param height the desired height for the canvas
* @param bgColor the desired background color of the canvas
*/
private Canvas(String title, int width, int height, Color bgColor)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
frame.setLocation(30, 30);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColor = bgColor;
frame.pack();
objects = new ArrayList<Object>();
shapes = new HashMap<Object, ShapeDescription>();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* @param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background color
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColor);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(visible);
}
/**
* Draw a given shape onto the canvas.
* @param referenceObject an object to define identity for this shape
* @param color the color of the shape
* @param shape the shape object to be drawn on the canvas
*/
// Note: this is a slightly backwards way of maintaining the shape
// objects. It is carefully designed to keep the visible shape interfaces
// in this project clean and simple for educational purposes.
public void draw(Object referenceObject, String color, Shape shape)
{
objects.remove(referenceObject); // just in case it was already there
objects.add(referenceObject); // add at the end
shapes.put(referenceObject, new ShapeDescription(shape, color));
redraw();
}
/**
* Erase a given shape's from the screen.
* @param referenceObject the shape object to be erased
*/
public void erase(Object referenceObject)
{
objects.remove(referenceObject); // just in case it was already there
shapes.remove(referenceObject);
redraw();
}
/**
* Set the foreground color of the Canvas.
* @param newColor the new color for the foreground of the Canvas
*/
public void setForegroundColor(String colorString)
{
if(colorString.equals("red")) {
graphic.setColor(new Color(235, 25, 25));
}
else if(colorString.equals("black")) {
graphic.setColor(Color.black);
}
else if(colorString.equals("darkGrey")) {
graphic.setColor(new Color(25, 25, 25));
}
else if(colorString.equals("fairGrey")) {
graphic.setColor(new Color(200, 200, 200));
}
else if(colorString.equals("blue")) {
graphic.setColor(new Color(100, 160, 230));
}
else if(colorString.equals("yellow")) {
graphic.setColor(new Color(230, 230, 0));
}
else if(colorString.equals("green")) {
graphic.setColor(new Color(80, 160, 60));
}
else if(colorString.equals("lila")) {
graphic.setColor(new Color(120, 80, 200));
}
else if(colorString.equals("orange")) {
graphic.setColor(new Color(255, 150, 50));
}
else if(colorString.equals("magenta")) {
graphic.setColor(Color.magenta);
}
else if(colorString.equals("white")) {
graphic.setColor(Color.white);
}
else {
graphic.setColor(Color.black);
}
}
/**
* Wait for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* @param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/**
* Redraw ell shapes currently on the Canvas.
*/
private void redraw()
{
erase();
for(Object shape : objects) {
shapes.get(shape).draw(graphic);
}
canvas.repaint();
}
/**
* Erase the whole canvas. (Does not repaint.)
*/
private void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
}
/************************************************************************
* Inner class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
/**
* ID
*/
private static final long serialVersionUID = 1L;
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
/************************************************************************
* Inner class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class ShapeDescription
{
private Shape shape;
private String colorString;
public ShapeDescription(Shape shape, String color)
{
this.shape = shape;
colorString = color;
}
public void draw(Graphics2D graphic)
{
setForegroundColor(colorString);
graphic.fill(shape);
}
}
}