Ned's Dreamhouse

Canvas.java 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import javax.swing.*;
  2. import java.awt.*;
  3. import java.util.List;
  4. import java.util.*;
  5. /**
  6. * Canvas is a class to allow for simple graphical drawing on a canvas.
  7. * This is a modification of the general purpose Canvas, specially made for
  8. * the BlueJ "shapes" example.
  9. *
  10. * @author: Bruce Quig
  11. * @author: Michael Kölling (mik)
  12. *
  13. * @version: 1.6 (shapes)
  14. */
  15. public class Canvas
  16. {
  17. // Note: The implementation of this class (specifically the handling of
  18. // shape identity and colors) is slightly more complex than necessary. This
  19. // is done on purpose to keep the interface and instance fields of the
  20. // shape objects in this project clean and simple for educational purposes.
  21. private static Canvas canvasSingleton;
  22. /**
  23. * Factory method to get the canvas singleton object.
  24. */
  25. public static Canvas getCanvas()
  26. {
  27. if(canvasSingleton == null) {
  28. canvasSingleton = new Canvas("BlueJ Shapes Demo", 300, 300,
  29. Color.white);
  30. }
  31. canvasSingleton.setVisible(true);
  32. return canvasSingleton;
  33. }
  34. // ----- instance part -----
  35. private JFrame frame;
  36. private CanvasPane canvas;
  37. private Graphics2D graphic;
  38. private Color backgroundColour;
  39. private Image canvasImage;
  40. private List<Object> objects;
  41. private HashMap<Object, ShapeDescription> shapes;
  42. /**
  43. * Create a Canvas.
  44. * @param title title to appear in Canvas Frame
  45. * @param width the desired width for the canvas
  46. * @param height the desired height for the canvas
  47. * @param bgClour the desired background colour of the canvas
  48. */
  49. private Canvas(String title, int width, int height, Color bgColour)
  50. {
  51. frame = new JFrame();
  52. canvas = new CanvasPane();
  53. frame.setContentPane(canvas);
  54. frame.setTitle(title);
  55. canvas.setPreferredSize(new Dimension(width, height));
  56. backgroundColour = bgColour;
  57. frame.pack();
  58. objects = new ArrayList<Object>();
  59. shapes = new HashMap<Object, ShapeDescription>();
  60. }
  61. /**
  62. * Set the canvas visibility and brings canvas to the front of screen
  63. * when made visible. This method can also be used to bring an already
  64. * visible canvas to the front of other windows.
  65. * @param visible boolean value representing the desired visibility of
  66. * the canvas (true or false)
  67. */
  68. public void setVisible(boolean visible)
  69. {
  70. if(graphic == null) {
  71. // first time: instantiate the offscreen image and fill it with
  72. // the background colour
  73. Dimension size = canvas.getSize();
  74. canvasImage = canvas.createImage(size.width, size.height);
  75. graphic = (Graphics2D)canvasImage.getGraphics();
  76. graphic.setColor(backgroundColour);
  77. graphic.fillRect(0, 0, size.width, size.height);
  78. graphic.setColor(Color.black);
  79. }
  80. frame.setVisible(visible);
  81. }
  82. /**
  83. * Draw a given shape onto the canvas.
  84. * @param referenceObject an object to define identity for this shape
  85. * @param color the color of the shape
  86. * @param shape the shape object to be drawn on the canvas
  87. */
  88. // Note: this is a slightly backwards way of maintaining the shape
  89. // objects. It is carefully designed to keep the visible shape interfaces
  90. // in this project clean and simple for educational purposes.
  91. public void draw(Object referenceObject, String color, Shape shape)
  92. {
  93. objects.remove(referenceObject); // just in case it was already there
  94. objects.add(referenceObject); // add at the end
  95. shapes.put(referenceObject, new ShapeDescription(shape, color));
  96. redraw();
  97. }
  98. /**
  99. * Erase a given shape's from the screen.
  100. * @param referenceObject the shape object to be erased
  101. */
  102. public void erase(Object referenceObject)
  103. {
  104. objects.remove(referenceObject); // just in case it was already there
  105. shapes.remove(referenceObject);
  106. redraw();
  107. }
  108. /**
  109. * Set the foreground colour of the Canvas.
  110. * @param newColour the new colour for the foreground of the Canvas
  111. */
  112. public void setForegroundColor(String colorString)
  113. {
  114. if(colorString.equals("red"))
  115. graphic.setColor(Color.red);
  116. else if(colorString.equals("black"))
  117. graphic.setColor(Color.black);
  118. else if(colorString.equals("blue"))
  119. graphic.setColor(Color.blue);
  120. else if(colorString.equals("yellow"))
  121. graphic.setColor(Color.yellow);
  122. else if(colorString.equals("green"))
  123. graphic.setColor(Color.green);
  124. else if(colorString.equals("magenta"))
  125. graphic.setColor(Color.magenta);
  126. else if(colorString.equals("white"))
  127. graphic.setColor(Color.white);
  128. else
  129. graphic.setColor(Color.black);
  130. }
  131. /**
  132. * Wait for a specified number of milliseconds before finishing.
  133. * This provides an easy way to specify a small delay which can be
  134. * used when producing animations.
  135. * @param milliseconds the number
  136. */
  137. public void wait(int milliseconds)
  138. {
  139. try
  140. {
  141. Thread.sleep(milliseconds);
  142. }
  143. catch (Exception e)
  144. {
  145. // ignoring exception at the moment
  146. }
  147. }
  148. /**
  149. * Redraw ell shapes currently on the Canvas.
  150. */
  151. private void redraw()
  152. {
  153. erase();
  154. for(Iterator i=objects.iterator(); i.hasNext(); ) {
  155. ((ShapeDescription)shapes.get(i.next())).draw(graphic);
  156. }
  157. canvas.repaint();
  158. }
  159. /**
  160. * Erase the whole canvas. (Does not repaint.)
  161. */
  162. private void erase()
  163. {
  164. Color original = graphic.getColor();
  165. graphic.setColor(backgroundColour);
  166. Dimension size = canvas.getSize();
  167. graphic.fill(new Rectangle(0, 0, size.width, size.height));
  168. graphic.setColor(original);
  169. }
  170. /************************************************************************
  171. * Inner class CanvasPane - the actual canvas component contained in the
  172. * Canvas frame. This is essentially a JPanel with added capability to
  173. * refresh the image drawn on it.
  174. */
  175. private class CanvasPane extends JPanel
  176. {
  177. public void paint(Graphics g)
  178. {
  179. g.drawImage(canvasImage, 0, 0, null);
  180. }
  181. }
  182. /************************************************************************
  183. * Inner class CanvasPane - the actual canvas component contained in the
  184. * Canvas frame. This is essentially a JPanel with added capability to
  185. * refresh the image drawn on it.
  186. */
  187. private class ShapeDescription
  188. {
  189. private Shape shape;
  190. private String colorString;
  191. public ShapeDescription(Shape shape, String color)
  192. {
  193. this.shape = shape;
  194. colorString = color;
  195. }
  196. public void draw(Graphics2D graphic)
  197. {
  198. setForegroundColor(colorString);
  199. graphic.fill(shape);
  200. }
  201. }
  202. }