You are on page 1of 15

Visual Programming

http://www.rgcetmca2.blogspot.com UNIT V

Unit V

Visual J++: Introduction to VJ++ - Applet Wizard Handling events Multithreading Animation Techniques Animating images Applets and networking. 1. INTRODUCTION TO VJ++ 1.1 JAVA APPLET WIZARD The VJ++ Java Applet Wizard walks you through a set of option pages to create the classes and code for a Java applet and provides a sample HTML file for browsing the applet. The framework for the Wizard-created applet supports multithreading, image animation, mouse event handling, and parameters read from the HTML. After the Wizard is finished and you compile the applet, you can test it with Internet Explorer (IE) 3.0 or later, with other browsers that support Java, or with VJ++'s standalone interpreter, jview.exe. In the current version of VJ++, IE is the only browser you can use for debugging. (Before you can install VJ++ from http://www.microsoft.com/visualj, you must install IE 3.0 from http://www.microsoft.com/ie.) When you first run VJ++, you will see menu bars typical of those in VC++ and a project workspace window with InfoView (a powerful integrated Help system). To begin the Java Applet Wizard, select the File menu and click New. Double-click the Project Workspace option to display the New Project Workspace dialog box, as shown in Screen 1. SCREEN 1: SCREEN 2:

Displaying the Java Applet Wizard's New Project Workspace dialog box

Selecting how you want to run your program

In the Type list, select Java Applet Wizard. Enter a name for your project in the Name text box (I used boingi, short for "boing image") and click Create. The Java Applet Wizard - Step 1 of 5 dialog box appears, as in Screen 2.

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

Select As an applet only for how you want to run your program. (If you plan to use jview.exe to test your applet, you must choose As an applet and as an application.) Click Next, and the Java Applet Wizard - Step 2 of 5 dialog box appears, as in Screen 3.

SCREEN 3:

SCREEN 4:

Creating the HTML debugging file and changing the size of your applet

Specifying multithreading and animation support

Selecting Yes, please to Would you like a sample HTML file? creates the HTML file for debugging. The initial size fields (Width, Height) let you change the size of the applet. Click Next, and the Java Applet Wizard - Step 3 of 5 dialog box appears. Our example includes animation, so keep the default option, Yes, please, for both multithreading and animation support, as shown in Screen 4. Click Next, and the Java Applet Wizard - Step 4 of 5 dialog box appears, as in Screen 5. Enter the applet parameters from Table 1 on this screen. SCREEN 6:

SCREEN 5:

Entering the applet parameters

Viewing the information the applet returns to the browser

TABLE 1: Boingi Applet Parameters

Visual Programming

http://www.rgcetmca2.blogspot.com DefDescription Value 2 min speed in either x or y 10 max speed in either x or y

Unit V

Name

Member

Type

minSpeed m_minSpeed int maxSpeed m_maxSpeed int

Click Next, and the Java Applet Wizard - Step 5 of 5 dialog box appears, as in Screen 6. This dialog box shows the information the applet will return to the browser. Click Finish, and the New Project Information dialog box displays a summary of specifications for the project. Click OK to complete the Wizard and return to the main VJ++ window. From the Build menu, select Build boingi to build the project. To run it, select Debug from the Build menu and Go from the Debug submenu (or simply press F5). If you are asked to specify the path to a browser, I recommend you use IE 3.0 or later, but the applet will run properly with Netscape and other browsers that support Java. The applet the Wizard will create animates a series of .gif files as a spinning globe. Applet with Attitude The spinning globe example the Wizard creates is OK, but let's extend the example by bouncing the globe around, changing its direction and speed whenever it hits the applet's boundary. Let's jump right into the code by opening the boingi.java file (part of which is in Listing 1) that the Wizard generated. At callout A in Listing 1, add the instance data shown in Listing 2. The program uses this instance data to keep track of the previous position and to calculate the next position of the image as it moves across the applet. Next, at the end of the public void init() method (in Listing 3), comment out (// signals a comment line) the call to resize() and save the range of the applet in m_rng, as follows: //resize(320,240); m_rng = size(); // save the applet's range

Now move down two more methods in the boingi.java file to the private void displayImage(Graphics g) method. Modify the code to appear as in Listing 4, and you're ready to compile and test the new Java code. The displayImage() method in Listing 4 first clears the previous image. Then the method displays a new image at the current position (m_nImgX, m_nImgY). Finally, the method calls the travelImage() method to calculate a new position to display the next image. The Wizard-generated code (commented out in Listing 4) displays the image in the center of the applet; the new code moves the image on each call to the displayImage() method. The travelImage() method saves the previous image coordinates and calls the checkForTurnaround() method to calculate a new vector (m_incX, m_incY) when the image is about to hit the applet's boundary. The checkForTurnaround() method checks

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

whether the image is out-of-bounds; if so, it calculates a new speed in the opposite direction. 2. HANDLING EVENTS Java events are part of the Java AWT package. An event is the way that the AWT communicates to you, as the programmer, and to other Java AWT components that something has happened. That something can be input from the user (mouse movements or clicks, keypresses), changes in the system environment (a window opening or closing, the window being scrolled up or down), or a host of other things that might, in some way, be interesting to the operation of the program. In other words, whenever just about anything happens to a Java AWT component, including an applet, an event is generated. Some events are handled by the AWT or by the browser without your needing to do anything. paint() methods, for example, are generated and handled by the browserall you have to do is tell the AWT what you want painted when it gets to your part of the window. Some events, however (for example, a mouse click inside the boundaries of your applet), you might need to know about. Writing your Java programs to handle these kinds of events enables you to get input from the user and have your applet change its behavior based on that input.

Mouse Clicks
Now start with the most common event you might be interested in: mouse clicks. Mouseclick events occur when the user clicks the mouse somewhere in the body of your applet. You can intercept mouse clicks to do very simple thingsfor example, to toggle the sound on and off in your applet, to move to the next slide in a presentation, or to clear the screen and start overor you can use mouse clicks in conjunction with mouse movements to perform more complex motions inside your applet.

mouseDown and mouseUp


When you click the mouse once, the AWT generates two events: a mouseDown event when the mouse button is pressed, and a mouseUp event when the button is released. Why two individual events for a single mouse action? Because you might want to do different things for the "down" and the "up." For example, look at a pull-down menu. The mouseDown extends the menu, and the mouseUp selects an item (with mouseDrags betweenbut you'll learn about that one later today). If you have only one event for both actions (mouseUp and mouseDown), you cannot implement that sort of user interaction. Handling mouse events in your applet is easyall you have to do is override the proper method definition in your applet. That method will be called when that particular event occurs. Here's an example of the method signature for a mouseDown event:

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

public boolean mouseDown(Event evt, int x, int y) { ... }

The mouseDown() method (and the mouseUp() method as well) takes three parameters: the event itself and the x and y coordinates where the mouseDown or mouseUp event occurred. The event argument is an instance of the class Event. All system events generate an instance of the Event class, which contains information about where and when the event took place, the kind of event it is, and other information that you might want to know about this event. Sometimes having a handle to that event object is useful, as you'll discover later in this section. The x and the y coordinates of the event, as passed in through the x and y arguments, are particularly nice to know because you can use them to determine precisely where the mouse click took place. For example, here's a simple method that grabs the current x and y positions when a mouseDown event occurs:
public boolean mouseDown(Event evt, int x, int y) { m_iMousex = x; m_iMousey = y; return true;

By including this method in an applet, every time the user clicks the mouse inside your applet, the data members m_iMousex and m_iMousey will be updated. Note that this method, unlike the other system methods you've studied thus far, returns a Boolean value instead of not returning anything (void). This will become important later today when you create user interfaces and then manage input to these interfaces; having an event handler return true or false determines whether a given UI component can intercept an event or whether it needs to pass it on to the enclosing component. The general rule is that if your method deals with the event, it should return true.

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

Mouse Movements
Every time the mouse is moved a single pixel in any direction, a mouse move event is generated. There are two mouse movement events: mouse drags, where the movement occurs with the mouse button pressed down, and plain mouse movements, where the mouse button isn't pressed. To manage mouse movement events, use the mouseDrag() and mouseMove() methods.

mouseDrag and mouseMove


The mouseDrag() and mouseMove() methods, when included in your applet code, intercept and handle mouse movement events. The mouseMove() method, for plain mouse pointer movements without the mouse button pressed, looks much like the mouseclick methods:
public boolean mouseMove(Event evt, int x, int y) { ... }

The mouseDrag() method handles mouse movements made with the mouse button pressed down (a complete dragging movement consists of a mouseDown event, a series of mouseDrag events for each pixel the mouse is moved, and a mouseUp event when the button is released). The mouseDrag() method looks like this: Keyboard events are generated whenever users press a key on the keyboard. By using key events, you can get hold of the values of the keys that were pressed to perform an action or merely to get character input from the users of your applet.

The keyDown and keyUp Methods


To capture a keyboard event, use the keyDown() method:
public boolean keyDown(Event evt, int key) { ... }

The keys generated by keyDown events (and passed into keyDown() as the key argument) are integers representing ASCII character values, which include alphanumeric characters, function keys, tabs, returns, and so on. To use them as characters (for example, to print them), you need to cast them to characters:
currentchar = (char)key;

Here's a simple example of a keyDown() method that does nothing but set the data member m_cLastKey to the character value of the key you just typed.

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

public boolean keyDown(Event evt, int key) { m_cLastKey = (char)key; return true; }

As with mouse clicks, each keyDown event also has a corresponding keyUp event. To intercept keyUp events, use the keyUp() method:
public booklean keyUp(Event evt, int key) { ... }

Table 13.1. Standard keys defined by the event class. Class Variable Represented Key Event.HOME Event.END Event.PGUP Event.PGDN Event.UP Event.LEFT Event.RIGHT The Home key The End key The Page Up key The Page Down key The up arrow The left arrow The right arrow

Event.DOWN The down arrow

3. MULTITHREADING The Java language contains one feature that is so dangerous, so difficult to avoid using, so hard to use correctly, and so pervasively used incorrectly that it has to rank as a serious

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

design flaw. That feature is multithreading. Experienced programmers are aware of the hazards associated with multithreading, and employ various strategies to ameliorate the problem. 3.1 THE EXTENT OF MULTITHREADING IN VISUAL J++ Languages and environments other than Java permit the use of multiple threads. But Java applications are virtually impossible to write without using them, and most apps use a lot of them. Even the most trivial applet will have three threads: the applet's main run loop, the Java virtual machine's event loop, and the Java display manager's paint loop. To this we can probably add even more threads for applications with animation timing loops, sound, and network communication. There can be no argument that Java's runtime environment is replete with threads, all running simultaneously and manipulating the same data. To deal with this chaos, Java provides just one low-level construct: the synchronized keyword. 3.2 THE HAZARDS OF SYNCHRONIZATION Synchronization is both necessary and sufficient to control the execution of multithreaded code, but that's akin to saying a raft and an oar are enough to cross any body of water. Sure, you can do it. In practice, however, synchronization is very difficult to use correctly. Here's a list of some of the problems inherent with synchronization:

If you don't use synchronization enough, and in the right places, your program will execute using inconsistent sets of data, and thus will produce unpredictable results. This situation is called a data race, because multiple threads race each other to produce and/or consume their common data. This kind of problem typically manifests itself in your programs as random, nonreproducible bugs which, if you investigate the situation, appear to result from "impossible" configurations of your data, such as
if(a==1) { b=2; }

if((a==1)&&(b!=2)) { throw new Error("impossible error!"); }

If you use synchronization too much, or in the wrong places, your threads can deadlock, with two or more processes permanently blocked because they are waiting for each other to relinquish some resource they both want to use. This kind of problem typically results in the application "locking up."

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

Threads that temporarily have nothing to do must be suspended and resumed when there is something for them to do again. If a thread should be resumed, but no other thread issues the command, a permanently stalled thread can result.

3.3 COMMON STRATEGIES FOR DEALING WITH MULTIPLE THREADS There are some good rules of thumb that are commonly used in Java programming.

Do all of your drawing in one place: either do all your drawing in the paint method, or do all your drawing in your run loop, and use the paint method only to set a "needs to be painted" flag. Conversely, do not do any drawing directly in response to various mouse, button, and network events. Use semaphores to indicate when data is ready to be consumed by another thread. Do as little as possible within synchronized methods. In particular, do not do anything that will not finish after some clearly foreseeable series of actions. Do not do anything inside synchronization that might block indefinitely, particularly I/O. Use local variables rather than global variables. Try to organize your code so each piece of data is manipulated in exactly one thread. Any data that is not shared between threads is guaranteed to be safe. Synchronize code that you know will be used by multiple processes and that uses state that may be shared among the processes.

4. ANIMATION TECHNIQUES Many Java applets perform animation, whether it's the classic, cartoon-style animation of Duke waving, program-generated lines such as flowing sine waves, or simply moving static images across the screen. No comprehensive, direct-manipulation tools exist (yet) for creating Java animations. 4.1 BASIC ANIMATION TECHNIQUES Many forms of animation are possible in Java. What all of them have in common is that they create some kind of motion on the screen by drawing successive frames at a relatively high speed (usually about 10-20 times per second). We will start by creating a simple template applet for doing animations and slowly elaborate it until we arrive at a fairly complete applet.

4.2 USING A THREAD To update the screen multiple times per second, you need to create a new Java thread that contains an animation loop. The animation loop is responsible for keeping track of the

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

current frame and for requesting periodic screen updates. To implement a thread, you must either create a subclass of thread or adhere to the runnable interface. A common mistake is to put the animation loop in the paint( ) method of an applet. Doing so will have strange side effects because it holds up the main AWT thread, which is in charge of all drawing and event handling. 4.3 KEEPING A CONSTANT FRAME RATE In the example above, the applet simply sleeps for a fixed amount of time between frames. This has the drawback that you sometimes wait too long. To get 10 frames per second you should not wait 100 milliseconds between frames, because you lose some time just running the thread. 4.3.1 OVERRIDING THE UPDATE( ) METHOD When the AWT receives a repaint request for an applet, it calls the applet's update( ) method. By default, the update( ) method clears the applet's background and then calls the paint() method. By overriding the update( ) method to include the drawing code that used to be in the paint( ) method, we avoid having the applet's entire area cleared with every repaint. Now that the background is no longer cleared automatically, we need to do it ourselves in the update( ) method. 4.3.2 DOUBLE BUFFERING Another way of reducing the flashing between frames is to use double buffering. This technique is used in many animation applets. The general principle is that you create an offscreen image, you draw a frame into the image, and then you slap the entire image onto the screen with one call to drawImage(). The advantage is that most of the drawing is done offscreen. The final painting of the offscreen image onto the screen is usually much more efficient than painting the frame directly to the screen. The sine wave applet with double buffering is shown in Example6Applet. You will see that the animation is pretty smooth and you don't need any special tricks when drawing the frame. The only disadvantage is that you have to allocate an offscreen image that is as large as the drawing area. If the drawing area is very large, this may demand quite a lot of memory. The Java applet is a different sort of beast from the typical application that executes on your PC or workstation. For one thing, it doesn't sit quietly on the hard drive waiting for your attention; a Java applet sits on the other side of a network connection waiting for you (and many others) to pull it across the network. Once the applet has made the journey, it comes to life and begins to download the resources it needs. Unfortunately, all of this network activity results in one thing: delay. In contrast to an application on your hard drive, an applet must expect, and deal constructively with network delay.

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

For this reason, the Java class library was designed to support asynchronous loading of media, such as images. Asynchronous loading means that loading occurs out of step with the rest of the application -- in another thread -- in the background. In fact, what might be thought of as one operation, the loading of an image from across the network, actually occurs in two distinct stages, which often occur asynchronously. These stages are: image definition and the actual downloading of the image. In this column, I will take a close look at the mechanics of image loading from the perspective of a Java applet or similar network-based Java application. I will also provide a step-by-step demonstration of how to load and draw images within an applet. 5. ANIMATING IMAGES 5.1 GETTING THE PICTURE WITH THE IMAGE CLASS An instance of the Image class represents image data. The image data does not need to reside locally; it may exist on another computer. In fact, it may not exist at all. An instance of the Image class is more like a reference to image data, than a container for image data. Consider an image on a computer across a network. The creation of an instance of the Image class on a local computer does not cause the image data to be pulled across the network. This is true because instantiation of the Image class does not cause reconstruction of the image data. The Image class doesn't even provide methods for initiating image reconstruction. (This class does, however, provide access to an ImageProducer object that does provide such methods -- I will talk about image producers next month.) Although the Image class doesn't store image data, it does provide methods for obtaining information about an image. The following methods return such information: intget Height (ImageObserverobs); intget Width (ImageObserverobs); Object getProperty (String nm, ImageObserver obs); The height and width values returned from the first two methods indicate the size of the image, in pixels. Properties, on the other hand, are image-format-specific pieces of information about an image, and are retrieved by name. The only property mentioned specifically in the Image class API is the comment property. It should contain a description of the image, or something similar. These methods return invalid values (the getHeight( ) and getWidth( ) methods both return -1 and the getProperty( ) method returns null) if the desired information is currently unavailable.

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

All three methods require an instance of a class that implements the ImageObserver interface as a parameter. An image observer is an object that expects to be notified when information about an image becomes available (I will talk about image observers next month). The Applet class implements this interface and we'll be using it as the image observer throughout this column. Image objects are not created by instantiating the Image class directly. Instead, other classes in the Abstract Windowing Toolkit (AWT) provide methods for creating images. For example, the Applet class provides methods for creating instances of the Image class from a URL: Image getImage(URL url); Image getImage(URL url, String nm); You can also create an instance of the Image class with methods provided by the Component class: Image createImage(ImageProducer prod); Image createImage(int w, int h); 5.2 DRAWING IMAGES WITH THE GRAPHICS CLASS As you might expect, the Graphics class plays a pivotal role in the use of images. It would be impossible for me to include a thorough discussion of the Graphics class and its role in the space I have available Along with methods for drawing text and simple geometric shapes, the Graphics class provides methods for drawing images. In fact, it provides four related methods: boolean drawImage(Image i, int x, int y, ImageObserver obs); boolean drawImage(Image i, int x, int y, Color c, ImageObserver obs); boolean drawImage(Image i, int x, int y, int w, int h, Color c, ImageObserver obs); boolean drawImage(Image i, int x, int y, int w, int h, ImageObserver obs); These methods have several parameters in common. Each method requires an instance of the Image class and the x and y coordinates at which to draw the image. Each method also requires an instance of a class that implements the ImageObserver interface. 6. APPLETS AND NETWORKING

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

At the example applet's core is public-key cryptography, introduced earlier in this series. Code signed using the private key of the signer can be run on client machines once the public key corresponding to the signer is deemed as trusted on the respective machine. We'll also discuss how policy files, which accord permissions and keystore, can be used as a repository for public and private keys. Moreover, we'll highlight the Java 2 SDK security tools and Netscape's sign tool, since they enable deployment. This series does not intend to provide a comprehensive guide to computer security. Computer security is a multifaceted issue touching several disciplines, departments, and cultures. Investments in technologies should be followed up with investments in personnel training, strict enforcement of policies, and periodic review of the overall security policy. 6.1 APPLICATION SECURITY Let's begin our investigation by looking at application security First, a quick note about writeFile.java, the code used in this article to illustrate the security features in Java 2. This program is a slightly modified version of the applet code provided by Sun, available over the Web to illustrate some of the features of Java 2 security. The program, modified to provide application support, attempts to create and write a file on the local file system. Access to a local filesystem is screened by the security manager. We will see throughout this article how this particular operation can be permitted in a secure manner. Running the byte code generated in a Java 2 Runtime Environment, Standard Edition (JRE) will let the application modify the file on the local file system by default, since the default policy does not subject Java 2 applications to a security manager. This policy is justified because applications are typically locally generated code and not downloaded over the network. The cases illustrated above represent extreme examples of security policy. In the former case, the application was not subject to any control; in the latter, it was subject to a very rigid control. In most cases it will be necessary to set the policy somewhere in between. You can accomplish an in-between policy using a policy file. To do so, create a policy file called all policy in the working directory: Running the same piece of code with the following command line will allow modification of the local filesystem: $ java -Djava.security.manager -Djava.security.policy=all.policy writeFile

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

6.1.1 NETWORKING APPLETS In this example, the application was subject to the security manager, but the overall policy was governed by the policy file, which allowed all files on the local filesystem to be modified. A stricter policy might have been to allow modification of only the relevant file.. Let us take a look at applet security and contrast it with application security. Any user sitting behind a corporate firewall or proxy server and use Netscape Navigator as their primary Web browser. These users cannot make use of Java applets that connect back to the applet's originating server because of Java applet security restrictions. For example, the applet-based site java.sun.com:81 and various applets that reside on the www.gamelan.com site, or are linked to from it, are not accessible to users behind a firewall. The typical error that comes up is: "# Security Exception: socket.connect:www.machine_name.com->www.machine_name.com." To get around this security restriction, all you need to do is edit your local Domain Name Service (DNS) resolver configuration. For most Unix and Windows systems, this is often done by editing your local HOSTS file:

Under Unix-like systems, this HOSTS file is "/etc/hosts" Under Windows 3.x and 95 systems, this file is "c:\windows\hosts" Under Windows NT systems, this file is "c:\Winnt_version\system32\drivers\etc\hosts," where Winnt_version is specific to the NT version.

Simply map the "machine_name" where the applet came from to some arbitrary Internet address. That is, add a line like the following to your HOSTS file: "www.machine_name.com 1.2.3.4." Then restart your Navigator browser, and you'll find that now you can use applets from www.machine_name.com. 6.1.2 A REAL EXAMPLE As stated above, with Navigator, when a firewall/proxy server is present and the internal network does not provide external DNS resolution users cannot access the Java appletbased site at java.sun.com:81. The typical circumstance involves a user not having the capability to do external DNS resolution. Most (if not all) companies do NOT provide external DNS resolution. Simply by adding the line "1.2.3.4 java.sun.com" to their HOSTS file, users can now fully access java.sun.com: 81. 6.1.3 HOW IT ALL WORKS

Visual Programming

http://www.rgcetmca2.blogspot.com

Unit V

I believe the reason adding a line to the HOSTS file gives users access to the site is because of a small security glitch in how the applet security manager checks to see what IP address the applet came from. In the example above, the site of origin is java.sun.com, which maps to an IP address of 1.2.3.4 on my machine. Then when the applet wants to connect back to java.sun.com for whatever reason, the applet security manager again checks to see what IP address the applet wants to connect back to. Once again, java.sun.com will map to 1.2.3.4. The applet security manager then compares the identical 1.2.3.4 responses and allows the connection to be made. The security glitch occurs at the point that this second applet request is made: What is supposed to happen based on any secondary applet request is that the URL request should be rewritten from http://java.sun.com/whatever to http://1.2.3.4/whatever before the request gets passed from the applet to the browser and then to the firewall/proxy server. But the URL request does not get rewritten. The applet requests keeps the URL request as http://java.sun.com, which forces the proxy to do another DNS resolution.

You might also like