Blinking Letters 2
Volume Number: 12
Issue Number: 9
Column Tag: Getting Started
The Peter Lewis Applet, After
By Dave Mark
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
Last month, we went through the first version of my color blinking text applet. As I
told you then, I showed the applet to Peter Lewis (he of Anarchie and other cool
Internet software fame) and he rewrote it. This month, we’ll take a look at Peter’s
rewrite. As you read through Peter’s code, bear this in mind. This applet definitely is
not the only way to do things. Far more importantly, this version of CWBlink
introduces a number of important Java topics, all of which you should learn about and
eventually master. We’ll aim to cover each topic in more detail in the coming months.
For now, just enjoy.
The New CWBlink Project
The new version of CWBlink extends last month’s example with a pushbutton that adds
the ability to turn blinking on and off, and also offers a convenient, well-defined place
to drop into your debugger. Figure 1 shows CWBlink with color blinking turned on.
The new CWBlink project is based on two Java source files instead of one. The
first file, CWBlink.java, contains the heart of the applet, and is divided into two
classes. The class CWBlink extends java.applet.Applet, and is the applet itself. The
class BlinkingText extends the Canvas class (a generic drawing component class),
implements the Runnable interface (which means it can be a thread - see last month’s
column), and defines a generic blinking text object. The CWBlink class creates and
starts the BlinkingText object.
The second file, AppletFrame.java, is needed only if you want your applet to run
standalone, replacing the applet frame with your own frame. This source file is
definitely worth understanding. We’ll start off by listing both source code files (along
with the associated HTML file), then cover the highlights of each file.
Figure 1. The CWBlink applet with color blinking turned on
If you like the experience of creating your project from scratch (as I do), launch
CodeWarrior, create a new project using the Java Applet stationery, then create three
new source code files. Here’s the source code for CWBlink.java:
package com.metrowerks.example.CWBlink;
import java.awt.*;
public class CWBlink extends java.applet.Applet
{
private Button blinkButton;
private BlinkingText blinkText;
public String getParameter(String name)
{
String result = null;
try
{
result = super.getParameter(name);
}
catch ( Exception e )
{
result = null;
}
return result;
}
public void init()
{
Panel tempPanel;
String att = getParameter("speed");
int speed = (att == null) ?
500 : (1000 / Integer.valueOf(att).intValue());
setLayout( new BorderLayout() );
att = getParameter("blinker");
String blinkString = (att == null) ?
"CodeWarrior!!!" : att;
blinkButton = new Button( "Blink" );
tempPanel = new Panel();
tempPanel.add( blinkButton );
this.add( "North", tempPanel );
blinkText = new BlinkingText( blinkString, speed );
tempPanel = new Panel();
tempPanel.add( blinkText );
this.add( "Center", tempPanel );
resize( 570, 170 );
}
public void start()
{
blinkText.start();
}
public void stop()
{
blinkText.stop();
}
public boolean action(Event evt, Object arg)
{
if ( "Blink".equals(arg) )
{
blinkText.ToggleBlinking();
}
return true;
}
public static void main(String args[])
{
com.metrowerks.AppletFrame.startApplet(
"com.metrowerks.example.CWBlink.CWBlink",
"Blink", args);
}
}
class BlinkingText extends Canvas implements Runnable
{
private Thread blinkThread = null;
private String blinkString;
private Font font;
private int speed;
private boolean isBlinking = false;
private Color[] letters;
private boolean[] is_black;
private int current_letter = 0;
private int old_width, old_height;
private Color RandomColor()
{
int red, green, blue;
do {
red = (int)(Math.random() * 256);
} while ( red > 0x8000 );
do {
green = (int)(Math.random() * 256);
} while ( green > 0x8000 );
do {
blue = (int)(Math.random() * 256);
} while ( blue > 0x8000 );
return new java.awt.Color( red, green, blue );
}
public BlinkingText( String blinkString, int speed )
{
this.blinkString = blinkString;
this.speed = speed / blinkString.length();
this.font = new java.awt.Font( "TimesRoman",
Font.PLAIN, 64 );
this.letters = new Color[blinkString.length()];
this.is_black = new boolean[blinkString.length()];
for ( int i = 0; i < letters.length; i++ )
{
letters[i] = RandomColor();
is_black[i] = true;
}
resize( 530, 70 );
repaint();
}
public synchronized void ToggleBlinking()
{
isBlinking = ! isBlinking;
notify();
}
public synchronized void PaintLetter( int the_letter )
{
Rectangle b = bounds();
int width = b.width;
int height = b.height;
Graphics g = getGraphics();
if ( old_width == width && old_height == height )
{
int x = 0;
int y = height;
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
for (int index=0; index
{
int w = fm.charWidth(blinkString.charAt(index));
x += w;
}
int w = fm.charWidth(blinkString.charAt(the_letter));
g.setColor( isBlinking ?
letters[the_letter] : Color.black );
g.clearRect( x, 0, w, height );
g.drawString( blinkString.substring(
the_letter,the_letter+1), x, y );