Week 12 - April 6, 1999

Transfering parameters to Java applets
Creating new windows
Multi-threads

Transfering parameters to Java applets

Sometimes we need to use the same applet with different parameters. Instead of setting some constants and the recompiling the code, we can define different html pages that will call the same applet with different sets of parameters. To set some parameters for a Java applet, we use the <param> tag between <applet> and </applet>. For example

<applet code="infoBtn.class" width=140 height=140>
<param name="name" value="Instructions...">
<param name="title" value="Test for the InfoWindow Applet">
<param name="content" value="some text">
</applet>

will call the infoBtn applet with three parameters: name, title and content. These parameters will be transfered to Java as strings, so, if you need numbers, you can convert them later.

Inside the Java applet, we use the getParameter("parameter_name") method to read the parameter called parameter_name. This method will return null if there is no definition for that parameter.

Creating new windows

When you want to create a new window, you have to create a new class that extends the Frame class. This class has exactely the same mechanisms as the Applet class. You have to be careful about the constructor method, paint method and handleEvent method. These methods are performing the same tasks as in the Applet class. The constructor here, instead of being called init, has to be called with the same name as the class.

This new windows has its own Graphics class, so, if you want to write or draw something, you have to call the getGraphics method and get the handle of that class.

Suppose we defined a class that extends the Frame class, and we called our class InfoWindow. The constructor receives three parameters, first two being Strings and the third one being a handle to the parent class (in this way it will be possible to have some interaction between the window and the parent applet). In the main applet, we will generate the window by calling the constructor

InfoWindow my_new_window = new InfoWindow ("text1","text2",this);

In this way, the windows will be created in the memory. Note that the window will not be displayed untill we call two other methods: pack() and show(). We will call these methods later in the applet, when we will be willing to display the window:

my_new_window.pack();
my_new_window.show();

To hide the window (without freeing the memory) we call the hide() methd:

my_new_window.hide();

Let's tale a look at the following example:

import java.applet.*;
import java.awt.*;

public class infoBtn extends Applet
{
 
        InfoWindow window;
        Label mlabel;
        String title;
        String bname;
        String content;
        Button mbutton;
        

        public void init()
        {

                if ((title = getParameter("title"))==null)
                {
                        title="Info Window";
                }
                if ((bname = getParameter("name"))==null)
                {
                        bname="Info...";
                }
                if ((content = getParameter("content"))==null)
                        content = "ERROR!!! No data assigned for this applet!";
                mbutton = new Button(bname);
                mlabel = new Label ("                  ");
                this.setLayout(new PackerLayout());
                this.add("l;side=top;anchor=n;expand=true;fill=x",mlabel);
                this.add("b;side=top;anchor=n;expand=true;fill=x",mbutton);
                window= new InfoWindow(title,content,this);
        }

        public boolean handleEvent(Event e)
        {
                if ((e.id==e.ACTION_EVENT) && (e.target == mbutton))
                {
                        window.pack();
                        window.show();
                        return true;
                }
                return super.handleEvent(e);
        }
}

class InfoWindow extends Frame
{
        TextField text = new TextField(30);
        Label mlabel = new Label("                  ");
        Button mbutton = new Button("Set Parent Text");
        Button mqbutton = new Button ("Close this window...");
        infoBtn mparent;

        InfoWindow(String title, String theText, infoBtn parent)
        {
                super(title);
                mparent=parent;
                this.setLayout(new PackerLayout());
                this.add("t;side=top;expand=true;fill=x;anchor=n",text);
                this.add("l;side=top;expand=true;fill=x;anchor=n",mlabel);
                this.add("b;side=top;expand=true;fill=x;anchor=n",mbutton);
                this.add("qb;side=top;expand=true;fill=x;anchor=n",mqbutton);
                mlabel.setText(theText);
        }

                
        public void paint(Graphics g)
        {
                // methods to redraw the windows, if necessary
        }

        public boolean handleEvent(Event e)
        {
                if (e.id==e.WINDOW_DESTROY)
                {
                        this.hide();
                        return true;
                } else 
                if (e.id==e.ACTION_EVENT) 
                {
                        if (e.target==mbutton) 
                        {
                                mparent.mlabel.setText(text.getText());
                                return true;
                        }
                        if (e.target==mqbutton)
                        {
                                this.hide();
                                return true;
                        }
                }
                return super.handleEvent(e);
        }
}

This applet will be called using the following HTML file

<applet code="infoBtn.class" width=140 height=140>
<param name="name" value="Instructions...">
<param name="title" value="Test for the InfoWindow Applet">
<param name="content" value="some text">
</applet>

Do you want to see what it does?

Multi-threads

We use multi-treads when we want to start a process in paralel with our applet. Sometime we want to do some animation or some time consumming process without taking the control from the GUI for a long time. This is the moment when we want to use Threads. When our applet has a particular process that runs in parallel with the main program, we have to declare that it implements Runnable. We will define inside our applet three new methods: start(), stop() and run(). These methods will take care of our paralel process. Let's discuss together the following example and see how this works.

import java.applet.*;
import java.awt.*;

public class threads extends Applet implements Runnable {

private Thread mthread = null;
Button mbutton = new Button ("Start counter");
Label mlabel = new Label("0");
int counter = 0;
boolean mrun=false;
        
public void init() {
        this.setLayout(new PackerLayout());
        this.add("l;side=top;expand=true;fill=x;padx=5;pady=5",mlabel); 
        this.add("l;side=top;expand=true;fill=x;padx=5;pady=5",mbutton);
}



public void run() {
        while(mrun) {
                mlabel.setText(String.valueOf(counter++));
                try {Thread.sleep(1000);} catch (InterruptedException e){};
        }
}

public void stop() {
        if ((mthread!=null) && mthread.isAlive())
                mthread.stop();
        mthread=null;
}

public boolean handleEvent(Event e) {
        if ((e.id==e.ACTION_EVENT) && (e.target==mbutton))
        {
                if (mthread==null) {
                        mbutton.setLabel("Stop counter");
                        mthread = new Thread(this);
                        mrun=true;
                        mthread.start();
                } else {
                        mbutton.setLabel("Start counter");
                        mrun=false;
                        this.stop();
                }
                return true;
        }
        return super.handleEvent(e);
}
}

The HTML file that calls this applet is

<applet code="threads.class" width=140 height=140>
</applet>

and the applet can be found here.