Feedback Search Top Backward Forward
EDM/2

OOPS Avenue - The Java Language

Written by Gordon Zeglinski

 

Preamble

It has been a while since I've written this OS/2 column. The last couple of months have been totally crazy in both good and bad ways. Things are finally getting back to quasi-normal, though the amount of time I spend programming OS/2 applications is decreasing.

Introduction

What better way to get back into the swing of things than by taking a look at one of the hottest topics today. IBM has been porting Java to OS/2 for a fair bit of time. The September 9 build is far more stable than previous builds. In this issue, we will take a quick look at the Java language and how to create a simple Java applet.

The Java Language

Java is an OOP language similar in syntax to C++. It has "built in objects" to store integral, floating point and string data. All higher level abilities are provided through various objects. Java allows the programmer to define both classes and interfaces. Classes are used to create objects (like C++ classes), while interfaces are used to define a set of functions a class must implement (similar to abstract classes in C++).

Programs written in Java can be either stand alone applications or applets. Applets are the most common type of Java program. They run within an applet viewer or a Java enabled WWW browser. We'll take a quick look at creating Java applets by creating a simple test applet. Before we can start, we'll take a look at how the Java API is implemented.

The Java API is divided into packages. Each package contains classes and implementations to perform a similar set of operations. Applets have the following packages available to them:

  • java.applet
  • java.awt
  • java.awt.image
  • java.awt.peer
  • java.io
  • java.lang
  • java.net
  • java.util

The first two packages are used in every applet. The java.applet package provides the classes and interfaces used to create an applet. The java.awt package contains all the classes used to create a graphical interface for the user. The java.lang package contains objects to perform threading, and various other classes/interfaces related the the Java language specification.

To create an applet, one subclasses as least the class java.applet.Applet. Any class which is to be used as the target of a thread must implement the runnable interface. Our sample applet will do both. We will now look at creating a simple applet.

Creating a Simple Applet

First, we specify which packages and classes we are going to use in our applet. This is done by using the import keyword.


   // import the whole java.awt package
   import java.awt.*;
   // import the Thread class
   import java.lang.Thread;
   import java.net.URL;
   import java.net.URLConnection;
   import java.net.MalformedURLException;
   import java.io.IOException;
   import java.io.DataInputStream;
   import java.io.EOFException;

We want to create a class called "BillBoard" which will be an applet and is capable of acting as the target of a Thread class. The BillBoard class will draw a series of alternately blinking LEDs around its edges.


public class BillBoard
   extends java.applet.Applet
   implements Runnable {

To smoothen the animation, we use the age old method of double buffering the screen updates. That is, the image is built off screen before it is displayed. Keeping this in mind, we define the data members.


   Graphics        offScreenGraphic;
   Image           offScreenImage;
   Dimension       mysize;
   String          Text;
   int             ledSize,
                   ledSpace,
                   CircX,
                   CircY,
                   xOffset,
                   yOffset;

   Thread          clockThread;

   int             Count;

There are four functions we should overload in the BillBoard class. The functions init, start and stop are declared in the Applet base class. The function run is declared in the Runnable interface. The function paint is declared in the java.awt.Component class. We will look at each function in depth below.

The init function is called when the applet is loaded. All initialization should occur in this function.


   public void init(){
      int     i;

      Count=0;
      clockThread=null;

      mysize=new Dimension();
      mysize=size();

      ledSize=12;
      ledSpace=3;

      CircX=mysize.width/(ledSpace+ledSize);
      CircY=mysize.height/(ledSpace+ledSize);

      mysize.height=CircY*(ledSpace+ledSize)-ledSpace;
      mysize.width=CircX*(ledSpace+ledSize)-ledSpace;

The createImage function is inherited from java.awt.component. It creates an off screen image buffer that will be used for double buffering. To actually draw in the image, we need a graphics object that is associated with the image. The getGraphics function returns an instance to a Graphics object that can be used to draw in the image.


   offScreenImage= createImage(mysize.width,
                               mysize.height);
   offScreenGraphic=offScreenImage.getGraphics();

For testing purposes, a diagonal line is drawn across the image.


    offScreenGraphic.drawLine(0,
                              0,
                              mysize.width,
                              mysize.height);

A bright red color is created. Then it is turned to a darker red and the current color is set to dark red.


    Color curColor=new Color(255,0,0);

    curColor=curColor.darker();
    offScreenGraphic.setColor(curColor);

Dark red circles are drawn around the edge of the image to represent the LEDs in the off state.


    for(i=0;i<CircX;i++){
       offScreenGraphic.fillOval(i*(ledSpace+ledSize),
                                 0,
                                 ledSize,
                                 ledSize);
       offScreenGraphic.fillOval(i*(ledSpace+ledSize),
                                 mysize.height-ledSize,
                                 ledSize,
                                 ledSize);
    }

    for(i=1;i<CircY-1;i++){
       offScreenGraphic.fillOval(0,
                                 i*(ledSpace+ledSize),
                                 ledSize,
                                 ledSize);

      offScreenGraphic.fillOval(mysize.width-ledSize,
                                i*(ledSpace+ledSize),
                                ledSize,
                                ledSize);
   }

   xOffset=(size().width-mysize.width)/2;
   yOffset=(size().height-mysize.height)/2;

The Java API documents are extremely vague on font manipulation. In theory, the next few lines should create a 14pt. bold version of the current font, set it as the current font, and then display the text "Test". Unfortunately, most of the font specific objects are left as being platform and browser specific. The only result that is guaranteed, is that the string will be displayed.


      Font myfont=new Font(getFont().getName(),Font.BOLD,14);

      offScreenGraphic.setFont(myfont);
      offScreenGraphic.drawString("Test",
                                  ledSpace+ledSize,
                                  mysize.height
                                    -(ledSpace+ledSize));
   }

The start function is called whenever the applet receives focus. In the BillBoard class, a thread is started to animate the "turning on and off" of the LEDs.


    public void start(){
       if(clockThread==null){
          clockThread=new Thread(this);
          clockThread.start();
       }
    }

The stop function is called whenever the applet looses focus. In the BillBoard class, the animation thread is stopped.


    public void stop(){
       if(clockThread!=null){
          clockThread.stop();
          clockThread=null;
       }
    }

The paint function is called whenever the applet needs to be repainted. The implementation of paint for BillBoard simply copies the offscreen image to the applet's window.


    public void paint(Graphics g){
       g.drawImage(offScreenImage,xOffset,yOffset,this);
    }

The run function is called by an instance of the thread class when the thread is started. In OS/2 C/C++ speak, the run function is the entry point of the thread. In BillBoard, the run function continuously loops, alternately turning on and off the LEDs.


   public void run(){
      while (true){
         LightLED(Count,true);

         if(Count+1>=2*(CircX+CircY))
            LightLED(0,true);
         else
            LightLED(Count+1,true);

To access a member of a parent class, one uses the "super." construct. Below, the repaint function of a parent class is explicitly called. It's not really needed here because repaint isn't overloaded.


    super.repaint();

We sleep the current thread for 30 msec. Note: the exception syntax in Java is the same as in C++.


         try {
            Thread.sleep(100);
         }
         catch (InterruptedException e) {
         }

         LightLED(Count,false);
         if(Count+1>=2*(CircX+CircY))
            LightLED(0,false);
         else
            LightLED(Count+1,false);

         Count++;
         if(Count>=2*(CircX+CircY))
            Count=0;

         super.repaint();
      }
   }

This concludes our quick look at Java. More information on Java can be found at http://java.sun.com/.

Wrapping Things Up

In this issue, we took a quick look at creating Java applets. Even so, only the surface of Java programming has been covered. In future issues, we will revisit Java programming and take an indepth look at certain areas.