Doodle is taken from the DoodlePad example in Exploring Java, by Patrick Niemeyer and Joshua Peck, first edition copyright 1996 by O'Reilly and Associates. It lets you draw with the mouse. Use the buttons to clear the picture, or to select other features.
/** Extended from the DoodlePad example in Exploring Java, * by Patrick Niemeyer and Joshua Peck, * First edition Copyright 1996 O'Reilly Publishing. *Download the Doodle2 source code. Now what? You may want to experiment with further changes and additions. You can copy and then edit the source files, then compile them and run them on your machine. To do that, you need to get The Java Development Kit, a free download JDK for PC from Sun or JDK for Apple from Apple. Have fun! The SDK downloads provide installation instructions, documentation, and even tutorials, plus there is lots more to be found on the web. Also many fine books to choose from.* Object-oriented shape drawing from OOPDraw2.java, * Written By: Sunit Katkar * E-Mail:sunitkatkar@hotmail.com * Home-Page : www.vidyut.com/sunit * Java Page : www.vidyut.com/sunit/JavaPage.html */ import java.awt.*; import java.applet.*; public class Doodle2 extends Applet { DrawingPad2 dPad; Button clearButton, biggerButton, smallerButton, undoButton; Checkbox writeHButton, writeVButton, drawButton, lineButton, rectangleButton, ovalButton, redButton, yellowButton, greenButton, blueButton; CheckboxGroup writeHVGroup = new CheckboxGroup (), colorsGroup = new CheckboxGroup (), modesGroup = new CheckboxGroup (); /** To run as an application, * construct it and show it in a frame. * This must be a static (class not instance) method, * because the instance won't exist until we construct it here. * When run as an applet, * the browser provides the frame, * and calls the constructor and init methods. */ public static void main (String []argv) { Doodle2 cd = new Doodle2 (); Frame ff = new Frame ("Doodle"); ff.setBounds (100, 100, 600, 300); ff.add (cd); cd.init (); ff.show (); } /** Make everything, * a drawing surface and some controls. */ public void init () { /* A big central drawing area and some controls on the edges */ setLayout (new BorderLayout ()); add ("Center", dPad = new DrawingPad2 ()); Panel np = new Panel (); np.setLayout (new GridLayout (0, 1)); np.add (clearButton = new Button ("Clear")); np.add (drawButton = new Checkbox ("draw")); drawButton.setCheckboxGroup (modesGroup); np.add (lineButton = new Checkbox ("line")); lineButton.setCheckboxGroup (modesGroup); np.add (ovalButton = new Checkbox ("oval")); ovalButton.setCheckboxGroup (modesGroup); np.add (rectangleButton = new Checkbox ("rectangle")); rectangleButton.setCheckboxGroup (modesGroup); /* Note set/getCurrent deprecated now set/getSelectedCheckbox */ modesGroup.setCurrent (drawButton); add ("West", np); Panel sp = new Panel (); sp.setLayout (new GridLayout (0, 1)); sp.add (biggerButton = new Button ("bigger")); sp.add (smallerButton = new Button ("smaller")); sp.add (writeHButton = new Checkbox ("Write Horiz")); writeHButton.setCheckboxGroup (writeHVGroup); sp.add (writeVButton = new Checkbox ("Write Vert")); writeVButton.setCheckboxGroup (writeHVGroup); writeHVGroup.setCurrent (writeHButton); sp.add (yellowButton = new Checkbox ("yellow")); yellowButton.setCheckboxGroup (colorsGroup); sp.add (redButton = new Checkbox ("red")); redButton.setCheckboxGroup (colorsGroup); sp.add (greenButton = new Checkbox ("green")); greenButton.setCheckboxGroup (colorsGroup); sp.add (blueButton = new Checkbox ("blue")); blueButton.setCheckboxGroup (colorsGroup); colorsGroup.setCurrent (blueButton); add ("East", sp); } /** Handle the button and say we did */ public boolean action (Event e, Object o) { if (e.target == clearButton) dPad.clear (); if (e.target == biggerButton) dPad.bigger (); if (e.target == smallerButton) dPad.smaller (); if ((e.target == redButton) && redButton.getState ()) dPad.setPaint (Color.red); if ((e.target == yellowButton) && yellowButton.getState ()) dPad.setPaint (Color.yellow); if ((e.target == greenButton) && greenButton.getState ()) dPad.setPaint (Color.green); if ((e.target == blueButton) && blueButton.getState ()) dPad.setPaint (Color.blue); if ((e.target == writeHButton) && writeHButton.getState ()) dPad.setHV (0); if ((e.target == writeVButton) && writeVButton.getState ()) dPad.setHV (1); if ((e.target == drawButton) && drawButton.getState ()) dPad.setMode (0); if ((e.target == lineButton) && lineButton.getState ()) dPad.setMode (1); if ((e.target == rectangleButton) && rectangleButton.getState ()) dPad.setMode (2); if ((e.target == ovalButton) && ovalButton.getState ()) dPad.setMode (3); /* Must requestFocus to get key strokes */ dPad.requestFocus (); return true; } } class DrawingPad2 extends Canvas { Image di; Graphics dg; int xpos, ypos, xold, yold; int mode = 0, hv = 0; DragShape2 dragShape = null; DrawingPad2 () { setBackground (Color.white); setForeground (Color.blue); } public void setPaint (Color fg) { dg.setColor (fg); } public void setMode (int m) { mode = m; } public void setHV (int m) { hv = m; } public boolean mouseDown (Event e, int x, int y) { switch (mode) { case 0: dragShape = null; break; case 1: dragShape = new DragLine2 (x, y); break; case 2: dragShape = new DragRect2 (x, y); break; case 3: dragShape = new DragOval2 (x, y); break; } xold = x; yold = y; return true; } public boolean mouseDrag (Event e, int x, int y) { if (dg == null) return false; /* Any current dragShape, * update it but do not draw it yet, * we do that in the paint method. */ if (null != dragShape) dragShape.setEnd (x, y); /* Direct drawing mode, * add another line segment to the offscreen image. */ else { xpos = x; ypos = y; dg.drawLine (xold, yold, xpos, ypos); xold=xpos; yold=ypos; } /* Either way we need a repaint */ repaint (); return true; } /* Any current dragShape, * update it one last time, * draw it into the offscreen image, * and get rid of it. */ public boolean mouseUp (Event e, int x, int y) { if (null != dragShape) { dragShape.setEnd (x, y); dragShape.draw (dg); dragShape = null; repaint (); } return true; } /** Prevent pre-clear since we fill whole space anyway */ public void update (Graphics g) { paint (g); } public void paint (Graphics g) { if (di == null) { di = createImage (size ().width, size ().height); dg = di.getGraphics (); } /* Everything from the accumulated offscreen image */ g.drawImage (di, 0, 0, null); /* Any current dragShape, * draw it to screen in current color. */ if (null != dragShape) { g.setColor (dg.getColor ()); dragShape.draw (g); } g.setColor (Color.black); g.drawRect (0, 0, size ().width-1, size ().height-1); } public void clear () { di.getGraphics ().clearRect (0, 0, size ().width, size ().height); repaint (); } /* There is no keyClick just Down and Up. * "Keypress:C:NN" * C is String [1] for the key character if defined else "?". * NN is String [2 or more] for the numeric key code, * high numbers > 1000 are control keys. */ public boolean keyDown (Event evt, int key) { if (dg == null) return false; if (key > 1000) return false; // System.out.println ("Keypress:"+String.valueOf ((char)key)+":"+String.valueOf (key)); String ks = String.valueOf ((char)key); FontMetrics fm = dg.getFontMetrics (); dg.drawString (ks, xold, yold); /* Advance either across or down */ if (0 == hv) xold += fm.stringWidth (ks); else yold += fm.getHeight (); repaint (); return true; } /** Must requestFocus to get key strokes */ public synchronized boolean mouseEnter (Event me, int x, int y) { requestFocus (); return true; } /** This **always** gives a newFont with getSize as requested, * but they may be displayed as the same size anyway. * and NOT change size on our Unix box, * although fine on a Windows/NT box. */ public void bigger () { changeFont (2); } public void smaller () { changeFont (-2); } void changeFont (int delta) { Component pcomp = getParent (); Font oldFont = getFont (); if ((null == oldFont) && (null != pcomp)) oldFont = pcomp.getFont (); if (null == oldFont) return; Font newFont = new Font (oldFont.getName (), oldFont.getStyle (), oldFont.getSize () + delta); /* Existing dg won't see it so tell them */ setFont (newFont); dg.setFont (newFont); } } /** There's no such shape as ''Shape'' * just as there's no such bird as ''Bird'' * but they all have some things in common... */ abstract class DragShape2 { int x = 0, y = 0, xx = 0, yy = 0; DragShape2 (int x, int y) { this.x = x; this.y = y; } public void setEnd (int xx, int yy) { this.xx = xx; this.yy = yy; } public abstract void draw (Graphics g) ; } class DragLine2 extends DragShape2 { DragLine2 (int x, int y) { super (x, y); } public void draw (Graphics g) { g.drawLine (x, y, xx, yy); } } class DragOval2 extends DragShape2 { DragOval2 (int x, int y) { super (x, y); } // All this jugglery because we do not want to draw oval // outside the applet area. Also we should be able to draw // the oval even if our starting point is at bottom right // and end point is at top left of the applet. Note that // top-left to top right is the positive x axis and top left // to left bottom is the positive y axis. public void draw (Graphics g) { int minx = Math.min (x, xx), miny = Math.min (y, yy), maxx = Math.max (x, xx), maxy = Math.max (y, yy); g.drawOval (minx, miny, maxx-minx, maxy-miny); } } class DragRect2 extends DragShape2 { DragRect2 (int x, int y) { super (x, y); } public void draw (Graphics g) { int minx = Math.min (x, xx), miny = Math.min (y, yy), maxx = Math.max (x, xx), maxy = Math.max (y, yy); g.drawRect (minx, miny, maxx-minx, maxy-miny); } }
Please also visit my home page.
Except as otherwise noted, this work is Copyright (C) 2000 by Morris Hirsch. All rights reserved, except as granted here.
Redistribution and use in source and binary forms, with or without modification, for any purpose, are permitted, except as may be restricted by original copyright holders, provided that the following conditions are met: