Using
Images and Timers
The Waba foundation
classes contain methods and classes to deal with images and timers. We'll
explain the basics here along with some sample code that should give you a feel
for how they can be used.
Loading Images
Let's start with images.
The Image class in the waba.fx package represents an image.
In this example, we load
an image called "hello.bmp" and draw it at location 10, 10 in the
application window:
public class MyApp extends MainWindow
{
Image img;
public void onStart()
{
img = new Image("hello.bmp");
}
public void onPaint(Graphics g)
{
g.drawImage(img, 10, 10);
}
So, how did we create the hello.bmp image? The hello.bmp
image is a Microsoft BMP format image. BMP is a standard image format for
bitmap images.
Waba supports 2, 16 and 256 color uncompressed BMP images.
These image types are supported by most paint programs.
If you could use the Paint program that comes with Windows
95 or NT, you can save an image out as a "Monochrome Bitmap" BMP
image to use it in a Waba program. In Paint Shop Pro (from JASC, Inc), you
could save out an image as "BMP - OS/2 or Windows Bitmap" and
"Windows RGB Encoded".
If you load BMP images in your program, you should include
them in your program's WARP file.
Here is an example of executing a command to "warp
up" all the classes and images in the current directory into a single WARP
file:
> warp c /q Hello *.class *.bmp
Using Images in Java Applets
If you distribute your Waba program as a Java applet,
there is something you should know if your Waba program uses images: the image
files should not be included in a JAR file.
Before we explain this in detail, let's review how to put
a Waba program on the web so it can run as a Java applet in a web page.
You can put a Waba program up on the web as a Java applet
by placing all your program's classes and all the Waba foundation classes in
the WabaSDK up on the web under a directory such that the directory hierarchy
looks like this:
/index.html
/hello.bmp
/MyApp.class
/waba/applet/Applet.class
/waba/applet/Frame.class
..
/waba/ui/PenEvent.class
/waba/ui/Welcome.class
The following HTML code would make the applet appear in
the index.html page:
<applet code=waba/applet/Applet.class
width=160 height=160>
<param name=appClass value="MyApp">
</applet>
To make the applet load faster, it's common to create a
JAR file containing the applet's classes. A "jar" program is used to
create and manage JAR files. The jar program is part of Java Development Kit
distributions like the JDK from Sun Microsystems.
You can make a JAR file containing the Waba program as you
normally would, but the trick is the JAR file should not contain the images
used by your program.
It should only contain the program's classes:
> jar cvf MyApp.jar *.class waba/applet/*.class
waba/fx/*.class waba/io/*.class waba/sys/*.class
waba/ui/*.class
The image files should be placed on the web site separate
from the JAR file as follows:
/index.html
/hello.bmp
/MyApp.jar
Then the HTML code that references the applet can be
changed to load the applet from a JAR file:
<applet code=waba/applet/Applet.class
width=160 height=160 archive=MyApp.jar>
<param name=appClass value="MyApp">
</applet>
The image files can't be in the JAR file because some web
browsers don't expect anything but .class files to exist in a JAR file.
Creating Images
There are times where you don't want to load an image and,
instead, just want to create an image and draw in it yourself. One common use
of off-screen images is as a drawing buffer to perform double-buffered drawing.
In this example, we create a 10x10 image with a black
background and draw a white X in the image:
Image img = new Image(10, 10);
Graphics g = new Graphics(image);
g.setColor(0, 0, 0);
g.fillRect(0, 0, 10, 10);
g.setColor(255, 255, 255);
g.drawLine(0, 0, 9, 9);
g.drawLine(0, 9, 9, 0);
Notice that we filled the image with a black background
before drawing lines inside of it. The contents of an image are initially
undefined.
When you want to draw an image to the screen, you don't
have to draw the whole image. You can draw portions of it using the
Graphics.copyRect() method. There are also various copy "modes"
available to copy it with logical OR, AND and XOR functions.
The extended drawing modes are not available when running
with the Java bridge classes (those in the WabaSDK). They are only available
when running under a native WabaVM.
Timers
Now let's take a look at timers. Timers are associated
with user-interface controls. Any user-interface control in a Waba program can
have its own timer.
Timers are created and destroyed using two methods in the
Control class:
Timer Control.addTimer(int millis);
boolean Control.removeTimer(Timer timer);
When a timer ticks, it posts a ControlEvent.TIMER event to
the control associated with the timer.
Here we create a new control by subclassing the Control
class. The control contains methods to start and stop blinking. The blinking
timer fires 5 times a second (every 200 milliseconds).
public class MyControl extends Control
{
Timer timer;
public void startBlinking()
{
timer = addTimer(200);
}
public void stopBlinking()
{
removeTimer(timer);
}
public void onEvent(Event event)
{
if (event.type == ControlEvent.TIMER)
blinkTheControl();
}
The timer does not interrupt your program in the middle of
an operation. It is scheduled along with other events. So, if your program is
in the middle of computing something when the timer is supposed to tick, it
will tick as soon as it can.
Time Stamps
Another method that is timing related but not directly
related to timers is the method:
int Vm.getTimeStamp();
This method returns a time stamp in milliseconds. It is a
running timestamp which means when the value goes beyond the value 1073741824
(which is 1 << 30), it wraps around to 0. It has no connection to the
current time, it is only useful when calculating relative times.
The current time is available by using the Time class.