TweetFollow Us on Twitter

Blinking Letters
Volume Number:12
Issue Number:8
Column Tag:Getting Started

Blinking Letters, Before

By Dave Mark

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

I just got back from the World Wide Developer’s Conference, where I got very little sleep but had a fantastic time. I saw Gil Amelio’s long-awaited speech, reunited with friends I only get to see a few times a year, got a chance to hone my Java skills, smoked some cigars, and even took a small side trip to Napa Valley.

Before I got to the show, I wrote a small applet for this month’s column. All puffed up with pride, I showed the applet to Peter Lewis (if you don’t know Peter, check out Anarchie, along with his other cool Internet shareware, and peruse the May 1996 issue of MacTech™ Magazine, in which he features heavily), and asked him if he had any comments. What I got back from Peter was a complete rewrite that had a better design, and ran a lot faster to boot!

So here’s what I’m going to do. This month, we’ll go over my original applet, step by step. Once you understand the applet, take some time to think about how you might improve the design. Next month, we’ll take a look at Peter Lewis’ rewrite.

The Original Applet

My applet started life as one of the standard sample Java applets that ships with the JDK. The original Blink was written by Arthur van Hoff (thanks, Arthur) and is shown in Figure 1. It paints a specified string in the applet window, then repeatedly and randomly redraws the words in the window in a series of related colors. (Some words are drawn in the background color, rendering them invisible.)

Figure 1. The original Blink,
as found in the Sun Java sample applets

I rewrote Blink so that it would display its string in a bigger font, blinking the individual letters in completely random colors, as opposed to the related colors used by original Blink. Since I used CodeWarrior to build the applet, I renamed it CWBlink.

Figure 2. My rewrite of Blink, now called CWBlink

Creating the CWBlink Applet

Here’s how I created the CWBlink applet. I started in the CodeWarrior IDE. Since CodeWarrior uses a front-end/back-end architecture (front-end drop-ins for language, back-end drop-ins for target machines), they use the same IDE and debugger for Java as they use for C, C++, and Pascal.

Inside the IDE, I created a new project, using the Java Applet stationery (Figure 3).

Figure 3. The New Project dialog box,
showing the Java Applet stationery

Figure 4. The new Java Applet project window,
before we replace the .html and .java files

Once the project was created (Figure 4), the next step was to replace the .html and .java files with our own. First, I double-clicked the file <replace me Applet>.html in the Project window. When the stationery file opens (notice that it is marked as read-only), I selected Save As... from the File menu and saved the file as CWBlink.html. Next, I replaced the text in the .html file with the following:

<title>Blinking CodeWarrior</title>
<hr>
<applet codebase="CWBlink Classes" code="CWBlink.class" width=530 height=100>
<param name=blinker value="CodeWarrior!!!">
<param name=speed value=1000>
</applet>
<hr>
<a href="CWBlink.java">The source.</a>

Once your HTML is typed in, save the code and close the file.

The HTML code should look familiar. Note that the codebase attribute tells the Java virtual machine the name of the folder containing your class files. The code attribute tells the VM the name of the class file to start with. The blinker parameter is the string that does the blinking. The speed parameter lets you change the speed of the blinking.

Next, double-click the file <replace me Applet>.java. Save the file as CWBlink.java. Replace the contents of the file with the following:

import java.awt.*;

public class CWBlink extends java.applet.Applet
 implements Runnable
{
 Thread blinkThread;
 String blinkString;
 Font   font;
 int    speed;

 public void init()
 {
 font = new java.awt.Font(
 "TimesRoman", Font.PLAIN, 64);
 
 String att = getParameter("speed");
 speed = (att == null) ? 400 :
 (1000 / Integer.valueOf(att).intValue());
 
 att = getParameter("blinker");
 blinkString = (att == null) ? "CodeWarrior!!!" : att;
 }
  
 public void paint(Graphics g)
 {
 int x = 0, y = font.getSize()-10;

 g.setColor(Color.black);
 g.setFont(font);
 FontMetrics fm = g.getFontMetrics();
 
 for (int index=0; index<blinkString.length(); index++ )
 {
 int red = (int)(Math.random() * 256);
 int green = (int)(Math.random() * 256);
 int blue = (int)(Math.random() * 256);
 
 char character = blinkString.charAt(index);
 int w = fm.charWidth(character);
   
 g.setColor( new java.awt.Color( red, green, blue ) );
 
 Character c = new Character( character );
 g.drawString(c.toString(), x, y );
 x += w;
 }
 }

 public void start()
 {
 blinkThread = new Thread(this);
 blinkThread.start();
 }

 public void stop()
 {
 blinkThread.stop();
 }

 public void run()
 {
 while (true)
 {
 try {Thread.currentThread().sleep(speed);}
 catch (InterruptedException e){}
 repaint();
 }
 }
}

The last step in setting up your project is to tell CodeWarrior how you want your applet classes saved. Select Preferences from the Edit menu. When the Preferences dialog appears (Figure 5), select the Java Project item under the Project heading. Make sure “Class Folder” is selected from the Project Type popup. Now type CWBlink Classes in the Folder Name field. This tells CodeWarrior to save all of your classes as .class files in a folder named CWBlink Classes, which is what’s expected by the HTML you typed in earlier.

Figure 5. The Java Project pane from
CodeWarrior’s Preferences dialog

Select Make from the Project menu to compile your .java file and save out your new .class file. Once your code compiles, CodeWarrior will create a new folder called CWBlink Classes, then create a new class file named CWBlink.class inside the CWBlink Classes folder. Once that happens, drag your HTML file onto the Metrowerks Java application. Metrowerks Java will parse your HTML code and run your brand new blinking applet.

Let’s take a look at the source code.

CWBlink Source Code

CWBlink.java starts by importing the java.awt classes. Next, the CWBlink class is defined. Notice that CWBlink extends the Applet class (you’ve seen this before) and also implements the Runnable interface (something new). Here’s what the Sun HTML doc has to say about the java.lang.Runnable interface:

“This interface is designed to provide a common protocol for Objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread. Being active simply means that a thread has been started and has not yet been stopped.

“In addition, Runnable provides the means for a class to be active while not subclassing Thread. A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target. In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.”

Basically, extending an existing class is the traditional subclassing mechanism you are used to from C++. An interface defines a set of methods and variables that will be available from within any class implementing that interface. For example, to implement the Runnable interface, you must provide a method named run() that gets executed when your object is activated. As the HTML summary indicates, the Runnable interface is implemented by the Thread class. The run() method is where the thread’s action takes place.

import java.awt.*;

public class CWBlink extends java.applet.Applet
 implements Runnable
{
 Thread blinkThread;
 String blinkString;
 Font   font;
 int    speed;

The init() method is called when the applet is created. We’ll start off the initialization process by creating a Font object that defines how the blinking text will appear. Next, we’ll load the speed and blinker parameters. Note that speed gets a default value of 400 (otherwise, the value is 1000 divided by the provided value) and blinkString gets a default value of "CodeWarrior!!!".

 public void init()
 {
 font = new java.awt.Font(
 "TimesRoman", Font.PLAIN, 64);
 
 String att = getParameter("speed");
 speed = (att == null) ? 400 :
 (1000 / Integer.valueOf(att).intValue());
 
 att = getParameter("blinker");
 blinkString = (att == null) ? "CodeWarrior!!!" : att;
 }

paint() gets called when the applet’s pane gets an update event. We’ll draw the blinkString at the x and y coordinates. We use the font’s point size to calculate the point where we draw the string in the applet’s pane.

 public void paint(Graphics g)
 {
 int x = 0, y = font.getSize()-10;

We’ll set the foreground color to black and the current font to font. We’ll also build a FontMetrics object from the current Graphics environment. To learn about FontMetrics, see the HTML file java.awt.FontMetrics. This will give us access to methods like charWidth() which lets us calculate the proper x-coordinate for the next letter to be drawn, based on the width of the current character.

 g.setColor(Color.black);
 g.setFont(font);
 FontMetrics fm = g.getFontMetrics();

Next, we’ll step through the blinkString, one letter at a time. For each letter, we’ll calculate a random value for red, green, and blue. We’ll store the current character in character, then calculate the character’s width.

 for (int index=0; index<blinkString.length(); index++ )
 {
 int red = (int)(Math.random() * 256);
 int green = (int)(Math.random() * 256);
 int blue = (int)(Math.random() * 256);
 
 char character = blinkString.charAt(index);
 int w = fm.charWidth(character);

We’ll set the current color using our random red, green, and blue values. Next, we’ll create a new Character object (note that Character is different from char - see java.lang.Character), which gives us an easy way to convert a single character to a string. We need a string to pass to drawString(), and the Character wrapper gives us an easy way to get there. If anyone out there can think of a simpler way to draw the character on the screen at the specified x and y location, please let me know. Just be sure you test your theory before you write!

Once we draw the character, we’ll bump x by the width of the character.

 g.setColor( new java.awt.Color( red, green, blue ) );
 
 Character c = new Character( character );
 g.drawString(c.toString(), x, y );
 x += w;
 }
 }

start() is similar to init(), but gets called when the applet’s document is visited. We’ll create a new Thread object and call its start() method. When the applet’s document is no longer on the screen, the stop() method is called. In our case, we’ll call the Thread’s stop() method to stop the thread.

 public void start()
 {
 blinkThread = new Thread(this);
 blinkThread.start();
 }

 public void stop()
 {
 blinkThread.stop();
 }

Remember that the run() method contains the body of the thread we are starting up. Our thread enters an infinite loop. The loop tries a sleep() for speed milliseconds. We catch the InterruptedException exception (which occurs when another Thread interrupts this thread), but we do nothing about it. The loop ends by forcing a repaint of the applet.

 public void run()
 {
 while (true)
 {
 try {Thread.currentThread().sleep(speed);}
 catch (InterruptedException e){}
 repaint();
 }
 }
}

Till Next Month...

This month’s applet introduced the concept of FontMetrics, type wrappers (in our case, java.lang.Character), and Threads, along with a quick tour of CodeWarrior’s Java environment. Next month, we’ll take a look at Peter Lewis’ rewrite of this applet. Think about how you might improve the design of this applet. What changes would you make? Peter’s changes were very interesting and definitely worth exploring. See you next month.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

A Better Finder Rename 9.52 - File, phot...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
OmniFocus 2.2.3 - GTD task manager with...
OmniFocus helps you manage your tasks the way that you want, freeing you to focus your attention on the things that matter to you most. Capturing tasks and ideas is always a keyboard shortcut away in... Read more
TinkerTool 5.4 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Tinderbox 6.3.1 - Store and organize you...
Tinderbox is a personal content management assistant. It stores your notes, ideas, and plans. It can help you organize and understand them. And Tinderbox helps you share ideas through Web journals... Read more
Parallels Desktop 10.2.2 - Run Windows a...
Parallels Desktop is simply the world's bestselling, top-rated, and most trusted solution for running Windows applications on your Mac. With Parallels Desktop for Mac, you can seamlessly run both... Read more
Adobe Premiere Pro CC 2015 9.0.1 - Digit...
Premiere Pro CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Premiere Pro customer). Premiere Pro CS6 is still available for... Read more
Adobe After Effects CC 2015 13.5.1 - Cre...
After Effects CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous After Effects customer). After Effects CS6 is still available... Read more
Adobe Creative Cloud 2.2.0.129 - Access...
Adobe Creative Cloud costs $49.99/month (or less if you're a previous Creative Suite customer). Creative Suite 6 is still available for purchase (without a monthly plan) if you prefer. Introducing... Read more
Tower 2.2.3 - Version control with Git m...
Tower is a powerful Git client for OS X that makes using Git easy and more efficient. Users benefit from its elegant and comprehensive interface and a feature set that lets them enjoy the full power... Read more
Apple Java 2015-001 - For OS X 10.7, 10....
Apple Java for OS X 2015-001 installs the legacy Java 6 runtime for OS X 10.11 El Capitan, OS X 10.10 Yosemite, OS X 10.9 Mavericks, OS X 10.8 Mountain Lion, and OS X 10.7 Lion. This package is... Read more

Domino Drop (Games)
Domino Drop 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Domino Drop is a delightful new puzzle game with dominos and gravity!Learn how to play it in a minute, master it day by day.Your... | Read more »
OPERATION DRACULA (Games)
OPERATION DRACULA 1.0.1 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0.1 (iTunes) Description: 25% off launch sale!!! 'Could prove to be one of the most accurate representations of the Japanese bullet hell shmup... | Read more »
Race The Sun (Games)
Race The Sun 1.01 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.01 (iTunes) Description: You are a solar craft. The sun is your death timer. Hurtle towards the sunset at breakneck speed in a futile race against time.... | Read more »
Tap Delay (Music)
Tap Delay 1.0.0 Device: iOS Universal Category: Music Price: $4.99, Version: 1.0.0 (iTunes) Description: Back in the “old days”, producers and engineers created delay and echo effects using tape machines. Tap Delay combines the warm... | Read more »
This Week at 148Apps: July 20-24, 2015
July is Heating Up With 148Apps How do you know what apps are worth your time and money? Just look to the review team at 148Apps. We sort through the chaos and find the apps you're looking for. The ones we love become Editor’s Choice, standing out... | Read more »
Red Game Without A Great Name (Games)
Red Game Without A Great Name 1.0.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.3 (iTunes) Description: The mechanical bird is flying through an unfriendly, Steampunk world. Help it avoid obstacles and deadly... | Read more »
Warhammer: Arcane Magic (Games)
Warhammer: Arcane Magic 1.0.2 Device: iOS Universal Category: Games Price: $9.99, Version: 1.0.2 (iTunes) Description: Engage in epic battles and tactical gameplay that challenge both novice and veteran in Warhammer: Arcane Magic, a... | Read more »
Mazes of Karradash (Games)
Mazes of Karradash 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The city of Karradash is under attack: the monsters of the Shadow Realms are emerging from the depths.No adventurer is... | Read more »
Battle Golf is the Newest Game from the...
Wrassling was a pretty weird - and equally great - little wressling game. Now the developers, Folmer Kelly and Colin Lane, have turned their attention to a different sport: golfing. This is gonna be weird. [Read more] | Read more »
Qbert Rebooted has the App Store Going...
The weird little orange... whatever... is back, mostly thanks to that movie which shall remain nameless (you know the one). But anyway it's been "rebooted" and now you can play the fancy-looking Qbert Rebooted on iOS devices. [Read more] | Read more »

Price Scanner via MacPrices.net

2015 13-inch 2.7GHz Retina MacBook Pro on sal...
B&H Photo has the new 2015 13″ 2.7GHz/128GB Retina MacBook Pro on sale today for $1199 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more
2.8GHz Mac mini available for $988, includes...
Adorama has the 2.8GHz Mac mini available for $988, $11 off MSRP, including a free copy of Apple’s 3-Year AppleCare Protection Plan. Shipping is free, and Adorama charges sales tax in NY & NJ... Read more
Updated Mac Price Trackers
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers: - 15″ MacBook Pros - 13″ MacBook... Read more
High-Precision Battery Fuel Gauge IC Extends...
Renesas Electronics Corporation has announced its new lithium-ion (Li-ion) battery fuel gauge IC, the RAJ240500, designed to extend battery life for connected mobile devices such as tablets, notebook... Read more
27-inch 3.3GHz 5K iMac on sale for $1799, $20...
B&H Photo has the 27″ 3.3GHz 5K iMac on sale for $1799 including free shipping plus NY tax only. Their price is $200 off MSRP, and it’s the lowest price available for this model from any Apple... Read more
Twelve South Free Dual Screen Backgrounds Co...
Twelve South has posted a second collection of travel Desktop photos, noting: For the Twelve South team, a vacation is never just a vacation. It’s a time to try out new prototypes on the road, visit... Read more
Apple Refurbished iMacs available for up to $...
The Apple Store has Apple Certified Refurbished iMacs available for up to $380 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 27″ 3.5GHz 5K iMac – $1949 $... Read more
Tablets: Why Microsoft’s Surface Is Soaring W...
In contrast to Apple’s record fiscal third quarter reported this week, Microsoft had a miserable latest quarter with its revenues falling by 5.1 percent, hammered by ongoing weak PC demand, and... Read more
Sale! 13″ 1.6GHz/256GB MacBook Air for $1099,...
B&H Photo has the 13″ 1.6GHz/256GB MacBook Air on sale for $1099 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model. Read more
iPad mini 4 To Be Upgraded To iPad Air 2 Spec...
There’s a certain inevitability about making Apple product predictions this time of year. Come September, we can pretty reliably count on the release of refreshed iPhones, along with the iOS 9... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales. Specialist - Retail Customer Service and Sales. Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Customer Experience (ACE) Leader - A...
…management to deliver on business objectives Training partner store staff on Apple products, services, and merchandising guidelines Coaching partner store staff on Read more
Project Manager - *Apple* Pay Security - Ap...
**Job Summary** The Apple Pay Security team is seeking a highly organized, results-driven Project Manager to drive the development of Apple Pay Security. If you are Read more
*Apple* TV Product Design Internship (Spring...
…the mechanical design effort associated with creating world-class products with the Apple TV PD Group. Responsibilities will include working closely with manufacturing, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.