Drawing Demo First Extension

What do computer programmers do? I wrote the first page as a visual aid, and used it when I spoke at Career Day at my daughter's school. It runs a simple drawing applet, and also shows the source code. Today's kids being pretty familiar with computers, they pointed out a bunch of features it was lacking. I decided to grow it into a set of pages, adding the requested features, and hopefully showing something of the development process.

This is the first extension. It adds a few things but there is more to come. (It also adds a bug, because this version flickers when you are drawing. I left the bug in, and we can fix it in the next version.)

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 change the drawing color or line thickness.

You cannot run applets

/** Extended from the DoodlePad example in Exploring Java,
 * by Patrick Niemeyer and Joshua Peck,
 * First edition Copyright 1996 O'Reilly Publishing.  */

import java.awt.*;
import java.applet.*;

public class Doodle1 extends Applet {

  DrawingPad1 dPad;

  Button
         clearButton,
         biggerButton, smallerButton,
         undoButton;

  Checkbox
	 writeHButton, writeVButton,
         redButton, yellowButton, greenButton, blueButton;

  CheckboxGroup
	 writeHVGroup = new CheckboxGroup (),
         colorsGroup = 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) {

      Doodle1 cd = new Doodle1 ();

      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 DrawingPad1 ());

     Panel np = new Panel ();
     np.setLayout (new GridLayout (0, 1));

     np.add (clearButton = new Button ("Clear"));

/* Note set/getCurrent deprecated now set/getSelectedCheckbox */

     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);

/* Must requestFocus to get key strokes */

     dPad.requestFocus ();

     return true;
  }

}

class DrawingPad1 extends Canvas {

  Image di;
  Graphics dg;
  int xpos, ypos, xold, yold;

  int hv = 0;

  DrawingPad1 () {
      setBackground (Color.white);
      setForeground (Color.blue);
  }

  public void setPaint (Color fg) { dg.setColor (fg); }

  public void setHV (int m) { hv = m; }


  public boolean mouseDown (Event e, int x, int y) {

     xold = x; yold = y;

     return true;
  }


  public boolean mouseDrag (Event e, int x, int y) {
     if (dg == null) return false;

/* Add another line segment to the offscreen image. */

     xpos = x; ypos = y;
     dg.drawLine (xold, yold, xpos, ypos);
     xold=xpos; yold=ypos;

/* We need a repaint */

     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);

     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);
   }

}
Download the Doodle1 source code. We can still add some useful features to it.

My Other Java..

Please also visit my home page.

Was this Helpful?

Was this Helpful? Suggestions? Was it what you were looking for? How did you find this page? Search result, following a link, recommendation? Please let me know. morris_hirsch@brown.edu

Legalities

This software is provided free of charge with no support. Email me if you do have a problem, and I will try to help, but I cannot promise to.

Except as otherwise noted, this work is Copyright (C) 2000 by Morris Hirsch. In particular, 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. 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:

DISCLAIMER

This software is provided free of charge with no support.
This software is provided in source format; You are advised to examine it and understand it, before putting it to use.
This software uses only algorithms and coding techniques that are available to the public in the open literature. You are however, advised to make your own determination of legality, for your intended use.
This software is provided by the Author and Contributors ``AS IS'' and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose, are disclaimed.
In no event shall the Author or Contributors, or their Agents, be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
1