BlinkingObjects
Example
Drawable
and Blinkable
Drawable
and Blinkable
import java.awt.Graphics; interface Drawable { void draw (Graphics g); } interface Blinkable extends Runnable, Drawable { float MAXRATE = 10; // maximum blinking rate is 10 flashes per second float MINRATE = 0.1f; // minimum blinking rate is 1 flash per 10 seconds void startBlinking(); void stopBlinking(); void setBlinkingRate(float r); float getBlinkingRate(); }
import java.awt.*; class ScreenCharacter implements Drawable { ... public void draw(Graphics g) { ... } }The definition of the class is the same as before.
import java.applet.Applet; import java.awt.*; class BlinkingCharacter extends ScreenCharacter implements Blinkable { Applet applet; float blinkingRate = MAXRATE; int laptime = (int) (1/blinkingRate); private Thread blinker = null; private boolean isVisibleQ = true; BlinkingCharacter(Applet applet) { // constructor for default initialization this("a", 12, 0, 0, applet); } BlinkingCharacter(String name, int fontsize, int x, int y, Applet applet) { // constructor to initialize letter and position super(name, fontsize, x, y); this.applet = applet; } void randomize() { int laptime = randomNumber(500,2000); setBlinkingRate((float) 1/laptime); super.randomize(); } public void draw(Graphics g) { if (isVisibleQ) { super.draw(g); } } public void run () { while (blinker != null) { applet.repaint(); ... isVisibleQ = !isVisibleQ; } } public void startBlinking () { ... } public void stopBlinking () { ... } public float getBlinkingRate () { return blinkingRate; } public void setBlinkingRate (float r) { blinkingRate = Math.max(MINRATE, Math.min(r, MAXRATE)); } }
import java.applet.Applet; import java.awt.*; class BlinkingLetter extends BlinkingCharacter { String letterCase; BlinkingLetter (Applet applet) { this("a", 12, 0, 0, "lowercase", applet); } BlinkingLetter (String name, int fontSize, int x, int y, String letterCase, Applet applet) { super(name, fontSize, x, y, applet); setCase(letterCase); } void toLowercase() { letterCase = "lowercase"; name = name.toLowerCase(); } void toUppercase() { letterCase = "uppercase"; name = name.toUpperCase(); } void randomize() { // random name int i = randomNumber(0,25); name = "abcdefghijklmnopqrstuvwxyz".substring(i,i+1); // random case if (randomNumber(0,1) == 0) { toLowercase(); } else { toUppercase(); } // random other properties super.randomize(); } }
import java.applet.Applet; import java.awt.*; class BlinkingDigit extends BlinkingCharacter { BlinkingDigit (Applet applet) { this("1", 12, 0, 0, applet); } BlinkingDigit(String name, int fontsize, int x, int y, Applet applet) { super(name, fontsize, x, y, applet); } void randomize() { // random digit int i = randomNumber(0,9); name = "0123456789".substring(i,i+1); // random other properties super.randomize(); } }
import java.applet.Applet; import java.awt.*; import java.util.*; public class BlinkingObjectsApplet extends Applet { Vector objects = new Vector(); ... public void init() { add(new Button("new object")); newObject(this); } public void start() { Enumeration e = objects.elements(); Blinkable obj; while (e.hasMoreElements()) { // step through all vector elements obj = (Blinkable) e.nextElement(); obj.startBlinking(); } } public void stop() { Enumeration e = objects.elements(); Blinkable obj; while (e.hasMoreElements()) { // step through all vector elements obj = (Blinkable) e.nextElement(); obj.stopBlinking(); } } public boolean action(Event e, Object arg) { newObject(this); repaint(); return(true); } public void paint(Graphics g) { update(g); } public void update(Graphics g) { ... Enumeration e = objects.elements(); Blinkable obj; while (e.hasMoreElements()) { // step through all vector elements obj = (Blinkable) e.nextElement(); obj.draw(offGraphics); } //Paint the image onto the screen. g.drawImage(offImage, 0, 0, this); } void newObject(Applet applet) { BlinkingCharacter c; BlinkingShape s; if (0 == (int) Math.round(Math.random())) { // select character if (0 == (int) Math.round(Math.random())) { c = new BlinkingLetter(applet); } else { c = new BlinkingDigit(applet); } c.randomize(); // choose random properties of character c.startBlinking(); objects.addElement(c); } else { // select shape if (0 == (int) Math.round(Math.random())) { s = new BlinkingOval(applet); } else { s = new BlinkingRectangle(applet); } s.randomize(); // choose random properties of shape s.startBlinking(); objects.addElement(s); } } }In the source code, in the methods
start
, stop
, and
update
, you can see that we step each time through the vector of
blinkable objects. Let us look more closely at the code for the
start
method
Enumeration e = objects.elements(); Blinkable obj; while (e.hasMoreElements()) { // step through all vector elements obj = (Blinkable) e.nextElement(); obj.draw(offGraphics); }In the first line, all elements of the vector
object
are
placed in an Enumeration
object. This is a container for
objects, and here we mean literally instances of the Object
class. We want to specify that the objects present in this container have the
property of being Blinkable
. We declare the
Blinkable
object obj
so that whenever we select an
element in the container, we can cast its type to Blinkable
,
assign it to the variable obj
and we can send messages of the
Blinkable
interface to this object without knowing whether it
is a blinking character, blinking oval shape, or a blinking rectangle.