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

Tidy Up 5.3.7 - Find duplicate files and...
Tidy Up is a full-featured duplicate finder and disk-tidiness utility. Features: Supports Lightroom: it is now possible to search and collect duplicates directly in the Lightroom library. Multiple... Read more
Pinegrow 5.97 - Mockup and design web pa...
Pinegrow (was Pinegrow Web Designer) is desktop app that lets you mockup and design webpages faster with multi-page editing, CSS and LESS styling, and smart components for Bootstrap, Foundation,... Read more
BlueStacks 4.210.0 - Run Android applica...
BlueStacks App Player lets you run your Android apps fast and fullscreen on your Mac. Feature comparison chart How to install Bluestacks on your Mac Go to MacUpdate and click the green "Download"... Read more
WhatsApp 2.2027.10 - Desktop client for...
WhatsApp is the desktop client for WhatsApp Messenger, a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS. WhatsApp Messenger is available for... Read more
Art Text 4.0.1 - $29.99
Art Text is graphic design software specifically tuned for lettering, typography, text mockups and various artistic text effects. Supplied with a great variety of ready to use styles and materials,... Read more
Adobe Dreamweaver CC 2020 20.2 - Build w...
Dreamweaver CC 2020 is available as part of Adobe Creative Cloud for as little as $20.99/month (or $9.99/month if you're a previous Dreamweaver customer). Adobe Dreamweaver CC 2020 allows you to... Read more
Adobe Acrobat DC 20.009.20074 - Powerful...
Acrobat DC is available only as a part of Adobe Creative Cloud, and can only be installed and/or updated through Adobe's Creative Cloud app. Adobe Acrobat DC with Adobe Document Cloud services is... Read more
beaTunes 5.2.10 - Organize your music co...
beaTunes is a full-featured music player and organizational tool for music collections. How well organized is your music library? Are your artists always spelled the same way? Any R.E.M. vs REM?... Read more
DiskCatalogMaker 8.1.5 - Catalog your di...
DiskCatalogMaker is a simple disk management tool which catalogs disks. Simple, light-weight, and fast Finder-like intuitive look and feel Super-fast search algorithm Can compress catalog data for... Read more
Meteorologist 3.4.1 - Popular weather ap...
Meteorologist is a simple interface to weather provided by weather.com. It provides the ability to show the weather in the main menu bar, displaying more detail in a pop-up menu, whose contents are... Read more

Latest Forum Discussions

See All

Steam Link Spotlight - Disco Elysium
Steam Link Spotlight is a feature where we look at PC games that play exceptionally well using the Steam Link app. Our last entry was Signs of the Sojourner Read about how it plays using Steam Link over here. | Read more »
Distract Yourself With These Great Mobil...
There’s a lot going on right now, and I don’t really feel like trying to write some kind of pithy intro for it. All I’ll say is lots of people have been coming together and helping each other in small ways, and I’m choosing to focus on that as I... | Read more »
Pokemon Go's July Community Day wil...
Pokemon Go developers have announced the details concerning the upcoming Gastly Community Day. This particular event was selected by the players of the game after the Gas Pokemon came in second place after a poll that decided which Pokemon would... | Read more »
Clash Royale: The Road to Legendary Aren...
Supercell recently celebrated its 10th anniversary and their best title, Clash Royale, is as good as it's ever been. Even for lapsed players, returning to the game is as easy as can be. If you want to join us in picking the game back up, we've put... | Read more »
Detective Di is a point-and-click murder...
Detective Di is a point-and-click murder mystery set in Tang Dynasty-era China. You'll take on the role of China's best-known investigator, Di Renjie, as he solves a series of grisly murders that will ultimately lead him on a collision course with... | Read more »
Dissidia Final Fantasy Opera Omnia is se...
Dissidia Final Fantasy Opera Omnia, one of Square Enix's many popular mobile RPGs, has announced a plethora of in-game events that are set to take place over the summer. This will include several rewards, Free Multi Draws and more. [Read more] | Read more »
Sphaze is a neat-looking puzzler where y...
Sphaze is a neat-looking puzzler where you'll work to guide robots through increasingly elaborate mazes. It's set in a visually distinct world that's equal parts fantasy and sci-fi, and it's finally launched today for iOS and Android devices. [... | Read more »
Apple Arcade is in trouble
Yesterday, Bloomberg reported that Apple is disappointed in the performance of Apple Arcade and will be shifting their approach to the service by focusing on games that can retain subscribers and canceling other upcoming releases that don't fit... | Read more »
Pixel Petz, an inventive platform for de...
Pixel Petz has built up a sizeable player base thanks to its layered, easy-to-understand creative tools and friendly social experience. It revolves around designing, trading, and playing with a unique collection of pixel art pets, and it's out now... | Read more »
The King of Fighters Allstar's late...
The King of Fighters ALLSTAR, Netmarble's popular action RPG, has once again been updated with a plethora of new content. This includes battle cards, events and 21 new fighters, which increases the already sizeable roster even more. [Read more] | Read more »

Price Scanner via MacPrices.net

$219 Apple AirPods Pro are back at Verizon, s...
Verizon has Apple AirPods Pro on sale again for a limited time for $219.99 on their online store. Their price is $30 off Apple’s MSRP, and it’s the lowest price we’ve seen for AirPods Pro. Available... Read more
Apple’s $779 13″ MacBook Air deal returns to...
Apple has clearance, Certified Refurbished, 2019 13″ MacBook Airs available again starting at $779. Each MacBook features a new outer case, comes with a standard Apple one-year warranty, and is... Read more
$200 13″ MacBook Pro discounts are back at Am...
Amazon has 2020 13″ 2.0GHz MacBook Pros on sale again today for $150-$200 off Apple’s MSRP. Shipping is free. Be sure to purchase the MacBook Pro from Amazon, rather than a third-party seller, and... Read more
Deal Alert! Apple AirPods with Wireless Charg...
Sams Club has Apple AirPods with Wireless Charging Case on sale on their online store for only $149.98 from July 6, 2020 to July 9, 2020. Their price is $50 off Apple’s MSRP, and it’s the lowest... Read more
Xfinity Mobile promo: Apple iPhone XS models...
Take $300 off the purchase of any Apple iPhone XS model at Xfinity Mobile while supplies last. Service plan required: – 64GB iPhone XS: $599.99 save $300 – 256GB iPhone XS: $749.99 save $300 – 512GB... Read more
New July 2020 promo at US Cellular: Switch an...
US Cellular has introduced a new July 2020 deal offering free 64GB Apple iPhone 11 smartphones to customers opening a new line of service. No trade-in required, and discounts are applied via monthly... Read more
Apple offers up to $400 Education discount on...
Apple has launched their Back to School promotion for 2020. They will include one free pair Apple AirPods (with charging case) with the purchase of a MacBook Air, MacBook Pro, iMac, or iMac Pro (Mac... Read more
July 4th Sale: Woot offers wide range of Macs...
Amazon-owned Woot is blowing out a wide range of Apple Macs and iPads for July 4th staring at $279 and ranging up to just over $1000. Models vary from older iPads and 11″ MacBook Airs to some newer... Read more
Apple Pro Display XDR with Nano-Texture Glass...
Abt Electronics has Apple’s new 32″ Pro Display XDR model with the nano-texture glass in stock and on sale today for up to $144 off MSRP. Shipping is free: – Pro Display XDR (nano-texture glass): $... Read more
New 2020 Mac mini on sale for up to $100 off...
Amazon has Apple’s new 2020 Mac minis on sale today for $40-$100 off MSRP with prices starting at $759. Shipping is free: – 2020 4-Core Mac mini: $759 $40 off MSRP – 2020 6-Core Mac mini: $998.99 $... Read more

Jobs Board

Physical Therapist Assistant - *Apple* Hill...
Physical Therapist Assistant - Apple Hill Rehab - Full Time Tracking Code 62519 Job Description General Summary: Under the direct supervision of a licensed Physical Read more
Operating Room Assistant, *Apple* Hill Surg...
Operating Room Assistant, Apple Hill Surgical Center - Full Time, Day Shift, Monday - Saturday availability required Tracking Code 62363 Job Description Operating Read more
Perioperative RN - ( *Apple* Hill Surgical C...
Perioperative RN - ( Apple Hill Surgical Center) Tracking Code 60593 Job Description Monday - Friday - Full Time Days Possible Saturdays General Summary: Under the Read more
Product Manager, *Apple* Commercial Sales -...
Product Manager, Apple Commercial Sales Austin, TX, US Requisition Number:77652 As an Apple Product Manager for the Commercial Sales team at Insight, you Read more
*Apple* Mac Product Engineer - Barclays (Uni...
Apple Mac EngineerWhippany, NJ Support the development and delivery of solutions, products, and capabilities into the Barclays environment working across technical Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.