Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Programming in Java 6 with Swing and Servlets Part 1 Exercise: Threads and Exception Handling This exercise teaches what threads are, and why they are useful in Java applications. The lab focuses on incorporating threads within Java applets, a common technique used by applet programmers. Without the use of threads, processes that should work in the background will often, in reality, monopolize all the resources in the system. If an applet needs a piece of code that may run for a long period of time, such as an animation loop or a complex computation, it should be put in a thread. The Java virtual machine running with the browser calls the applet’s init(), start(), stop(), and destroy() methods, and expects them to return after performing their tasks. A common mistake made by beginning applet programmers is to place code in the init() or start() methods (or a method called by them) to build a GUI interface and wait for a user event. When this code executes, the methods are prevented from returning control to the browser, which puts the applet in a deadlocked state. The only way to stop the applet when this happens is to issue a kill, interrupt, or break instruction from the command line. The way to avoid this problem is to place the code called by init() or start() in a separate thread, thereby allowing control to return to the browser. This exercise illustrates this technique. Part One: A Simple Applet Create an applet that simply displays the time and date. 1. For ModuleSeven create the c:\labs\ModuleSeven directory. 2. Create a new Java application called DigClock.java that extends a Swing JApplet object. Import the following packages. Access to Swing classes is obtained by importing the javax.swing package. 3. Add these two instance variables to the class for a font and date. Override JApplet’s init(), start() and stop() methods (we’ll use these later). In the paint() method add code to paint the current date and time to the applet’s window. Your new JApplet should look something like this: Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 2 import java.awt.*; import java.util.Date; import javax.swing.*; public class DigClock extends JApplet { private Font fnt = new Font("Helvetica", Font.BOLD, 16); private Date theDate = new Date(); public void init() { super.init(); getContentPane().setSize(400,100); } public void start() { } // the applet is running. public void stop() { } // the applet is stopping public void paint(Graphics g) { super.paint(g); g.setFont(fnt); g.drawString(theDate.toString(),5,40); } } 4. Use your text file to create another HTML page and embed the DigClock applet. (copy MyApplet.html from ModuleThree and modify it if you like). The new DigClock.html should look like the following: Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 3 <HTML> <HEAD> <TITLE>DigiClock</TITLE> </HEAD> <BODY> <APPLET code="DigClock.class"> </APPLET> <p>The Digital Clock </p> </BODY> </HTML> 5. View DigClock in your browser or use the appletviewer that comes with the java development kit. DigClock displays a digital clock that only changes when the applet is refreshed or after browsing to another web page and using the browser’s Back button. The clock is only refreshed when the paint() method is called. DigClock looks something like this when running: Writing Applets Using Threads The clock can be made to update once per second by adding a thread of execution that sleeps for a second then calls the applet’s paint() method. Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 4 6. Make the applet runnable by implementing the Runnable interface. Runnable requires that we add a method called run(). An instance variable for a thread is added that will execute the run method in a separate thread of execution. The threaded version of the DigClock is shown in the box below: import java.awt.*; import java.util.Date; import javax.swing.*; public class DigClock extends JApplet implements Runnable { private Font fnt = new Font("Helvetica", Font.BOLD, 16); private Date theDate = new Date(); Thread myThread; private volatile boolean keepRunning = true; public void init() { super.init(); getContentPane().setSize(400,100); } public void start() { if (myThread == null) { myThread = new Thread(this); keepRunning = true; myThread.start(); } } public void run() { while( keepRunning ) { theDate = new Date(); repaint(); try { Thread.sleep(1000); } // pause for 1000 milliseconds (1 second) catch (InterruptedException e) { /* ignored */ } Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 5 } } public void stop() { if (myThread != null) { keepRunning = false; // this will stop the while loop in the run method myThread = null; } } public void paint(Graphics g) { super.paint(g); g.setFont(fnt); g.drawString(theDate.toString(),5,40); } } 7. Save your file and compile the DigClock.java. 8. Use your browser or the appletviewer to load MyApplet.html. The digital clock now updates once per second. Threads allow the applet to display the date in a separate thread without interfering with the browser. Note that even though a method from the Thread class (sleep) is used to pause the execution of the thread, the applet itself is not affected. The internal thread stops when we browse to another web page and restarts if we return to the DigClock page. The sleep() method is a static method of the Thread class used to pause execution of a program. The volatile boolean variable keepRunning is used to start and stop the thread. Threads should be stopped in a controlled way, such as using a controlling variable, as in this exercise. The volatile modifier requests that the Java virtual machine always read the shared copy of the variable and forces synchronized access to the variable when it is accessed from concurrent running threads. The stop() method does two things: it stops the thread from executing, and it sets the thread’s variable myThread to null. Setting the variable to null makes the Thread object it previously contained available for removal from memory at the java virtual Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 6 machine’s discretion. If the viewer comes back to this Web page with this applet, the start() method creates a new thread, and the clock begins running again.. Part Two: Using Threads in Animation This example illustrates how threads are used to implement simple animations in applets. The program will draw an alternately expanding and shrinking circle using thread techniques and some basic graphics routines from the Abstract Windowing Toolkit. The circle will expand to fill the application area. Define the applet width and height to be of size 300. The program will create an expanding and shrinking solid red circle on a blue background. The following code sets the background color: setBackground(Color.blue); prior to running the loops that control the expanding and shrinking. A solid red circle is created by the fillOval() method in the java.awt.Graphics class. Consider an oval to be a rectangle with overly rounded corners. The fillOval()method takes these four arguments: the x and y coordinates of the top left corner of the overly-rounded rectangle, and the width and height of the oval itself. To create a circle, make the width and height equal. When the circle expands or shrinks, the top left corner coordinate will travel along a diagonal from the center of the applet region to the top left corner of the applet region. For example, this instruction creates a solid circle having a diameter of 300 and whose top left corner is at (0,0): g.fillOval(0,0,300,300); Call the applet that runs the thread Balloon. Because it uses threads, Balloon will implement the Runnable interface. The Balloon class will have these four methods: start(), stop(), run(), and paint(). The start() and stop() methods behave as described above in Part One for applets that run threads. The run() method contains the body of the applet. The run() method should set the initial background color. Then it should contain code for two loops that execute alternately, one for the expanding circle, and one for the shrinking circle. Each loop should call repaint() to display the recalculated circle. The paint() method performs the display, setting the color of the circle using this method: g.setColor(Color.red); and then displaying the circle using the fillOval() method described above. The circle should continue to expand and shrink as long as the applet is running. Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 7 1. Create a new java application called Balloon.java that extends a Swing Applet and implements Runnable. 2. Ignore the error at the line defining the Balloon class. This error indicates that the run() method has not yet been implemented. Add the following import statement: import java.awt.*; 3. Add the following instance variables: private private private private Thread myThread = null; int xydiag, diam; int rad = 150; volatile boolean keepRunning = true; 4. Add these start() and stop() methods: public void start() { if (myThread == null) { myThread = new Thread(this); keepRunning = true; myThread.start(); } } public void stop() { if (myThread != null) { keepRunning = false; myThread = null; } } 5. Modify the init() method to set the size of the applet as follows: public void init() { super.init(); getContentPane.setSize(rad*2, rad*2); } 6. Implement the run() method: public void run() Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 8 { setBackground(Color.blue); while(keepRunning) { for(xydiag = rad; xydiag >= 0; xydiag -= 5) { diam = 2 * (rad - xydiag); repaint(); try { Thread.sleep(100); } catch (InterruptedException e){} } for(xydiag = 0; xydiag <= rad; xydiag += 5) { diam = 2 * (rad – xydiag); repaint(); try{ Thread.sleep(100); } catch (InterruptedException e){} } } } 7. Implement the paint() method: public void paint(Graphics g) { super.paint(g); g.setColor(Color.red); g.fillOval(xydiag, xydiag, diam, diam); } 8. Save your work and compile the program. 9. Create another web page to contain the new applet. An example web page is shown below: <html> <head> <title>Balloon</title> </head> <body> <applet code="Balloon.class" width="400" height="400"> </applet> <p> Balloons </p> Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 9 </body> </html> 10. Open the web page in your browser or use the appletviewer and you should see the red circle expanding and contracting. Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 10 Solutions DigClock.java import java.awt.*; import java.util.Date; import javax.swing.*; /** * A threaded applet that displays a working digital clock * on its panel. */ public class DigClock extends JApplet implements Runnable { /** the digital clock face is rendered in this font */ private Font fnt = new Font("Helvetica", Font.BOLD, 16); /** the initial date displayed on the clock */ private Date theDate = new Date(); /** thread that runs the clock */ Thread myThread; /** as long as this is true the thread will continue running. It is * declared volatile since multiple threads may access its value. */ private volatile boolean keepRunning = true; /** * Override JApplet.init to set the size of * the content panel. */ public void init() { super.init(); getContentPane().setSize(400, 100); } /** * Override JApplet.start to create and start a thread. */ public void start() { if(myThread == null) { Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 11 myThread = new Thread(this); keepRunning = true; myThread.start(); } } /** * Implementation of the Runnable interface. This method * runs the digital clock. */ public void run() { while(keepRunning) { theDate = new Date(); repaint(); try { Thread.sleep(1000); } catch(InterruptedException e) {} } } /** * Override JApplet.stop to kill the running thread. */ public void stop() { if(myThread != null) { keepRunning = false; myThread = null; } } /** * Draw the clock on the applets panel. * @param g The graphics context. */ public void paint(Graphics g) { super.paint(g); Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 12 g.setFont(fnt); g.drawString(theDate.toString(), 5, 40); } } DigClock.html <html> <head> <title>DigClock</title> </head> <body> <applet code="DigClock.class" width="400" height="125"> </applet> <p> The Digital Clock </p> </body> </html> Balloon.java import java.awt.*; import javax.swing.*; /** * A threaded applet that draws ballons (circles) on its * primary graphics panel. */ public class Balloon extends JApplet implements Runnable { private Thread myThread = null; private int xydiag; private int diam; private int rad = 150; private volatile boolean keepRunning = true; /** * Override JApplet.init to set the size of * the content panel. */ public void init() { Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 13 super.init(); getContentPane().setSize(rad * 2, rad * 2); } /** * Override JApplet.start to create and start a thread. */ public void start() { if(myThread == null) { myThread = new Thread(this); keepRunning = true; myThread.start(); } } /** * Override JApplet.stop to kill the running thread. */ public void stop() { if(myThread != null) { keepRunning = false; myThread = null; } } /** * Implementation of the Runnable interface. This method * runs the balloon application. */ public void run() { setBackground(Color.blue); while(keepRunning) { for(xydiag = rad; xydiag >= 0; xydiag -= 5) { diam = 2 * (rad - xydiag); repaint(); try Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 14 { Thread.sleep(100); } catch(InterruptedException e) {} } for(xydiag = 0; xydiag <= rad; xydiag += 5) { diam = 2 * (rad – xydiag); repaint(); try { Thread.sleep(100); } catch(InterruptedException e) {} } } } /** * Draw the applets main panel. * @param g The graphics context. */ public void paint(Graphics g) { super.paint(g); g.setColor(Color.red); g.fillOval(xydiag, xydiag, diam, diam); } } Balloon.html <html> <head> <title>Balloon</title> </head> <body> <applet code="Balloon.class" width="400" height="400"> Copyright ©2008, Custom Training Institute. All rights reserved. Threads and Exception Handling -Exercise: Page 15 </applet> <p> Balloons </p> </body> </html> Copyright ©2008, Custom Training Institute. All rights reserved.