Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: Applets
Expertise: Beginner
Mar 19, 1997

Applet Takes Up CPU Time

Question:
I am trying to make an HTML page with many applets running concurrently. Unfortunately, an applet that I created uses up much of the CPU time and slows all the other applets down. Most of the time my applet is just sleeping. I have it set to MIN_PRIORITY. Here is the entire code:

        import java.awt.*;

        import java.applet.*;





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





        public String Profit = "Profits";

        public String Better = "Better Web Sites";

        public String Quick = "Quick Service";

        Color green = new Color((float)0,(float).5,(float)0);

        Color ltgreen = new Color((float)0,(float).8,(float)0);

        Font theFont;

        int done=0;



        public void init(){

             setBackground(ltgreen);

             setFont(theFont);

             done = 1;

        }



        public void run(){

                Thread billboard = new Thread(this);

                billboard.setPriority(Thread.MIN_PRIORITY);

                billboard.start();

                repaint();

        }



        public void paint(Graphics g){

             g.setColor(green);

             g.clearRect( 0,0,size().width, size().height);

             g.drawString(Profit,45,20);



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

                     {Thread.yield();};

             g.clearRect( 0,0,size().width, size().height);

             g.drawString(Better,15,20);

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

                     {Thread.yield();};

             g.clearRect( 0,0,size().width, size().height);

             g.drawString(Quick,25,20);

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

             {Thread.yield();};

             repaint();

        }

    }

Answer:
This is an interesting little puzzle because it shows how the somewhat confusing directions in the Java documentation can really lead you astray.

When you run the code in this applet, it works fine, alternating between the three strings. However, the code doesn't actually use a separate thread. You are calling paint() over and over. Each call to paint() is really busy--it takes up 6 seconds, making the rest of the user interface thread pretty sluggish. The run() method never executes. (You can put a print statement into it to verify that it doesn't get called.)

Let's fix this up. To have the run() method get called, we need to make a new thread in the start() method:


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

        private Thread runner;



        public void start(){

             runner = new Thread(this);

             runner.start();

        }



        public void stop(){

             runner.stop();

        }

        . . .

    }

Next, let's think what the run() method of the thread should actually do. It should rotate among the strings and call repaint(). Then it should go to sleep for a little while. That goes on forever (or actually, until the thread is killed.)




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

     private String[] messages = new String[3];

     private current_message = 0;



public void init(){

     messages[0] = "Profits";

     messages[1] = "Better Web Sites";

     messages[2] = "Quick Service";

     . . .

}



public void run(){

     while (true) {

        current_message = (current_message + 1) % messages.length;

        repaint();

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

     }

. . .



}

Now the paint() method is short and snappy, as it should be:




public void paint(Graphics g){

     g.setColor(green);

     g.clearRect( 0,0,size().width, size().height);

     g.drawString(messages[current_message],45,20);

}

Try it out--you will find the result much more responsive.

In general, you want to work backwards from the paint() procedure. Each call to paint() should do a little bit of work and then return. It shouldn't call repaint(). The run() procedure should contain an infinite loop that sets up the data for the next painting, calls repaint and then sleeps. This recipe lies at the core of all animation applets.

DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date