Vous êtes sur la page 1sur 11

Java Programming ...

From the Grounds Up


With Java, it's possible to write some very sophisticated applets with a relatively small amount of code. Here's how. Wildly popular due to its interactive multimedia capabilities, Java programming leads the list of Internet development skills in current commercial demand. In this first half of our two-part tutorial on Java applet development, we explore the essentials of Java's components. These include how Java development tools relate to each other and--most importantly--how they are used to provide content that executes on the client side instead of on your server. Before Sun Microsystems introduced Java, most Web interactivity was accomplished via CGI (Common Gateway Interface) scripting. This is frequently utilized in forms or guestbooks where users type entries into text fields, then submit this information via their browser back to a host server. The host server then passes the information to an external program running on the Web server's machine. The output of this external program is then passed from the server back to the browser. CGIs must execute at least one round trip from the browser to the server and back. In contrast, when a Java-compatible browser accesses a Java-powered page, an applet--a small program written in Java--is copied to the browser's machine and executes there. It does not execute on the server the way a CGI program does. This local execution makes possible a much greater level of Web interaction and multimedia effects, unhampered by HTML restrictions or network bandwidth. Java programs can display slick animations, invite users to play games, show step-by-step tutorial instructions, or run demonstration versions of computer software. When a browser accesses a standard HTML page, the result is usually a static display. When it runs a Java applet, however, the results are limited only by the creativity of the applet's developer. The applet is a nearly independent application running within the browser.

Getting Started
Java is an object-oriented programming language that resembles a simplified form of C++. Java code displays graphics, accesses the network, and interfaces with users via a set of capabilities-known as classes--that define similar states and common methods for an object's behavior. Unlike other programming languages, though, Java programs are not compiled into machine code; instead, they are converted into an architecture-neutral bytecode format. This collection of bytes represents the code for an abstract Java virtual machine (VM). In order for these bytes to execute on a physical machine, a Java interpreter running on that physical machine must translate those bytes into local actions, such as printing a string or drawing a button. To run Java applets, you'll need a Java-enabled browser (such as Sun's HotJava, Netscape 2.0 or greater, or Internet Explorer 3.0 or greater) or you can use the appletviewer utility in Sun's Java Development Kit (JDK). The JDK also includes an interpreter for standalone Java applications (called simply java), as well as a debugger and compiler, called jdbg and javac respectively. Java applets use a subset of the full Java VM, with a variety of features disabled for security reasons. You can add Java applets to your Web pages with the <APPLET> tag, which can include attributes for the applet's height, width, and other parameters. Java-capable browsers treat Java applets like other media objects in an HTML document: they are loaded with the rest of the page, then verified and executed.

Java Classes and Methods


Java utilizes the basic object technology found in C++. In a nutshell, the Java language supports the idea of data packaging, or encapsulation, through its mechanism. A Java class is an association between data elements and/or functions, much like an extended struct in C (or a C++ class). In fact, there are no structs in Java at all; the mechanism of grouping together similar

elements is achieved only by creating a class. The functional members of a class are referred to as the class methods. Just as a C struct may contain other structs within it, a Java class may be built on top of another class--although only one at a time--and inherit that class's behaviors as well. Java has its own syntax for describing methods and classes. It supports public class members, which are visible outside the class; protected members, which are visible only within the class and its subclasses; and private members, which are only visible within that particular class. Java supports abstract (virtual) classes, in which some or all of the member functions are declared, but not defined--they have no function body, so that only subclasses which fully define those functions may be used. If you have some experience with C++ programming, many of these concepts will be familiar to you. However, there are several striking differences between C++ and Java. Much of the implicit behavior that C++ takes for granted is absent in Java. For example, there are no default constructors: a Java program must explicitly call the operator new to create a new instance of a class. In addition, arithmetic operators such as "+" or "= =" may not overload in Java. There is no way for the programmer to extend the behavior of "+" beyond what Java provides intrinsically. Another highly visible departure from C and C++ is that there are no pointers (and logically, no pointer arithmetic) in Java. The code, boss...the code! Figure 1 shows the Java code listing for an application that can generate prime numbers. At the beginning of the code, a class called Primes is declared. This class has a private variable called start that will set the value at which the program starts looking for primes, and a public variable known as count that tracks the number of primes it should find. Line 11 shows that within the class, the method Primes takes a single-integer argument which is used to initialize the private variable start. This is the only way that start can be set, since a private variable is inaccessible outside its class. FIGURE 1 Primes.java, the source code for a Java application that generates prime numbers.

1: /** 2: Prime number generator 3: @author Mark C. Reynolds 4: @version 1.0 5: */ 6: 7: class Primes { 8: private int start; // no default 9: public int count = 100; // default value 10: 11: Primes(int sta) { // constructor with one arg 12: start = sta; 13: } 14: 15: private boolean isPrime(int p) { 16: int i; 17: for(i=2;i<(p/2);i++) { 18: if ( i*(p/i) == p ) return(false); 19: } 20: return(true); 21: } 22: 23: public void Generate(int arr[]) { // make 24: primes 25: int sta = start;

26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: } 68:

int cnt = count; int idx = 0; while ( cnt > 0 ) { if ( isPrime(sta) ) { arr[idx++] = sta; cnt; } sta++; } }

class Mclass { public static void main(String argv[]) { Primes p; int arrp[]; int len; int sta = 2; int cnt = 0; int i;

// dummy default

len = argv.length; if ( len > 0 ) { sta = Integer.parseInt(argv[0]); if ( len > 1 ) { cnt = Integer.parseInt(argv[1]); } } p = new Primes(sta); if ( len > 1 ) p.count = cnt; // set if user specified a count arrp = new int[p.count]; p.Generate(arrp); for(i=1;i<=p.count;i++) System.out.println("Prime " + i + " is " + arrp[i-1]);: }

Line 11 also shows an example of a method (Prime) having the same name as its class (Prime). This special kind of method, called a constructor, permits the programmer to initialize an object in the Primes class before using it. In line 15, the method isPrime takes an integer p and returns a boolean value (set to true or false) indicating whether or not that integer is prime, using brute force procedures. If we had developed a highly sophisticated method of testing for primality, it might be in our commercial interests to retain the rights to that algorithm, so in that spirit the method isPrime has been declared private. The public method Generate accepts an array name and generates count primes by methodically incrementing up through the integers beginning at the value set for start and testing each one to see if it is prime. Any primes found are loaded into the array passed as the argument to Generate. Since Generate is a public method, it may be called freely by any Java code. Since it is also part of the Primes class, it is permitted to call the private isPrime method. A Java programmer using the Primes class may therefore create a list of primes, but is not permitted to access the function that tests for primality.

This class definition is followed by the definition of the Mclass class. This class contains a single member, a method function known as main. This function is akin to the main() at the heart of C and C++, except that it takes a single argument, an array of elements of type String. Java handles much of its string handling capabilities within its String classes. The section Advanced Java Classes explains the predefined Java classes used in this example in greater detail. This part of the tutorial is kind of a class about classes...

A Touch of Class
Note that main must occur as the class method in Java. In this example, the main method occurs within the Mclass definition, rather than at the top level as in C. This is because there are no freestanding functions within Java--every method must occur with the scope of a class. The main method is also identified as static, which means that it may not be changed within instances of this class--another departure from C, which uses static for scoping as well as permanence. The presence of a method named main identifies this code as a standalone Java application, rather than an applet. The main method parses its command line arguments in such a way as to allow zero, one or two arguments--which, as we'll show below, will prove very useful to us. The construction argv.length extracts the length of the array argv[], and will work with any array. Arrays are structured entities in Java; for example, an array always knows its length. If the argv[] array has at least one element, then the method parseInt in the Integer class (another predefined Java class) is called to convert that argument to an integer and store it in sta. If a second argument also is present then its value is assigned to cnt. Note that sta is initialized to 2. Since sta is a required argument for the constructor method Primes(), it must always have a value assigned to it. The next four statements actually do the work. The statement "p = new Primes(sta);" creates a new instance of the Primes class, known as p, with the private value of start set to the specified starting value sta. In Java, as in C++, the operator new is used to create new instances of classes. If the number of arguments is greater than one, the statement on line 57 sets the class member count of the instance p to the user-specified count; otherwise, it retains its default value of 100. In either case, p.count will maintain the number of primes generated. On line 60, we allocate an integer array large enough to hold that number of elements, again using the operator "new". The primes are actually generated by the call to p.Generate(), which invokes the Generate method within the instance p of the class Primes. The results are then printed using System.out.println, which prints a string followed by a newline. It uses the println method of the out member of System (another predefined Java class) to achieve its action. Although this listing is really not a very practical example--for starters, there's no good reason why start should be a private class member while count is public--it was mainly intended to illustrate the basic use of classes and their member variables and methods. This code demonstrated how to create a class--this example used two, Primes and Mclass--and also used the predefined Java classes System, Integer, and String. The next section provides greater detail on how these libraries provide functionality for dealing with network access and graphics. Packaging up your code

Advanced Java Classes


The collection of Java classes is structured as a tree, in which each node has exactly one parent. Since Java classes can only inherit from one class at a time, it is said to support a single-class inheritance hierarchy.

FIGURE 2 Important components of the Java hierarchy.

java.lang Boolean Long String Number System java.awt Button Choice Event Graphics Label MenuBar Point Scrollbar Window

Character Float Class Object Thread Canvas Color FileDialog Image List MenuItem Polygon TextArea

Integer Double Math Process

Checkbox Dimension Font Insets Menu Panel Rectangle TextField

java.io DataInput DataOutput File FilenameFilter PrintStream

DataInputStream DataOutputStream FileInputStream FilterInputStream RandomAccessFile

InputStream OutputStream FileOutputStream FilterOutputStream StreamTokenizer ServerSocket URLStreamHandler

java.net ContentHandler InetAddress URL URLConnection java.applet Applet AudioClip

java.util BitSet Date Enumeration Hashtable Random Stack Vector

Dictionary Properties StringTokenizer

The top of the Java class hierarchy is organized into a set of related classes, called packages. The main Java packages are java.lang, java.net, java.io, java.awt, java.util, and java.applet. The java.lang package implements the basic components of the Java language, including string manipulation, mathematical functions, and conversion operations such as the simple string-tointeger one seen in Primes.java. The java.net package contains the network access functions, including those associated with opening a URL and getting its contents. The java.io package handles all kinds of input and output, implementing various forms of streaming (much like stdin and stdout in C or cin and cout in C++). Graphics are handled by java.awt. "AWT" is said to stand for "Another Window Toolkit" or "Advanced Window Toolkit," depending on who you ask. The AWT implements standard graphic components such as menus, panels, buttons, and checkboxes. The AWT also implements a number of sophisticated image manipulation functions within the java.awt.image subpackage. If you have ever programmed Windows or Macintosh graphics, used X or a higher level toolkit such as Tk, then AWT will seem very familiar. The java.util package has additional utility functions for string, vector and stack manipulation, hashing, date conversion, and a number of other goodies. Finally, java.applet is a very special package that actually creates a subclass of Applet whenever a new applet is produced.

Running applications and creating applets

Running a Java Application


Now that we've stepped through Primes.java, the source code for our prime number generator, let's compile and run the application. You'll need javac, the Java compiler in the JDK, to compile the source code:

The Java compiler places each class in its own output file. Since Primes.java defined two classes-Primes and Mclass--compiling the source code will produce Primes.class and Mclass.class. Our examination of the source code showed that Mclass contained the main class method for this program. As a result, you'll need to run java, the Java interpreter in the JDK, on Mclass.class. You'll also need to assign values for where the Primes application should start looking for primes and for how many primes it should find in total. If you wanted the Primes application to start at the number 14 and continue until 105 primes have been found, you'd enter at the command line:

javac Primes.java

As we've seen, it's not possible to execute Java source directly--it must be compiled into its bytecode format first. When a browser accesses a Java page, it receives and executes the bytecode stored in the .class file. Therefore, you'll need the Java Development Kit--or at least javac--to create Java content and Java Web pages. What's less obvious is how our prime number generator makes use of Primes.class. As we've seen, Primes.class is created as a separate file from Mclass.class when Primes.java is compiled. When a browser or the Java interpreter reads in Mclass, it will discover unresolved references to the Primes class (and also to Java classes such as System). It then has to find the file Primes.class to resolve those references. The browser or Java interpreter makes use of class loading; it dynamically loads the Primes bytecode from the Primes.class file and also loads unresolved Java classes in the same way. If for some reason you had renamed Primes.class, the Java interpreter would be unable to continue; it would be unable to locate the resources it needed. This proves to be particularly important when developing Java applets; all class files and subsidiary files, such as GIFs, referenced by an applet must follow a set of naming and organizational conventions, as our next example below shows.

java Mclass 14 105

Creating Java Applets


Java applets are similar to standalone Java applications, but are embedded within Web pages. We will examine two simple applets in order to see how HTML, Java, and its classes can be combined to deliver executable content. Figure 3 shows the Java code for a Variable Hello applet. A variation of the standard programmer's "Hello, World" program, the Variable Hello applet shows the basic structure of an applet and its interaction with HTML and the browser environment. FIGURE 3 The Variable Hello Java Applet.

1: 2: 3: 4: 5: 6: 7: 8: 9:

/** A simple Java applet to issue an HTML-specified greeting @author Mark C. Reynolds @version 1.0 */ import java.awt.*; import java.net.*;

10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:

public class VH extends java.applet.Applet implements Runnable { String msg1; String msg2; public void init() { String who; String where; URL uwhere; who = getParameter("who"); if ( who == null ) who = "world"; uwhere = getDocumentBase(); where = uwhere.toString(); msg1 = "Hello, " + who + ","; msg2 = "from " + where;

public void paint(Graphics g) { g.setColor(Color.blue); g.drawString(msg1, 10, 15); g.drawString(msg2, 10, 30); } public void run() { resize(preferredSize()); repaint(); }

The code begins with two import statements. These alert the Java compiler that this applet will use classes from the java.awt and java.net packages. The asterisk is a wildcard character indicating that everything within those packages should be imported. For simplicity's sake, we've used the wildcard instead of being more selective and designating only those classes that will be required. In line 11, we declare a public class VH as a subclass of the Applet class with the extends clause. For this applet to function, we need to add executability functionality to the VH class. Since this is not something inherited by the Applet class--and remember, Java only has single inheritance--we will use the implements clause to fill in missing elements from a Java interface named Runnable. Interfaces such as Runnable are a useful workarounds for situations where single inheritance is a drawback. Applet programmers must provide an init() method and a run() method within their Applet subclass. A class declaration that extends Applet and implements Runnable is mandatory in all applets; it is the equivalent of the main() entry point for applications. The VH class has two class variables, msg1 and msg2, and three methods. The init() method is called once when an instance of VH is created. The run() method is called whenever the applet is activated. The paint() method is what displays the graphics. A Web browser will call init() when it first loads the applet's page, and it will call run() whenever the page is visited or revisited. The paint() method is called whenever the applet needs to draw something. There is a default paint() method, unlike init() and run(), but many applets will want to provide their own version of paint in order to perform their own specific graphical operations.

The VH init() method starts out by calling getParameter() to obtain the value of a parameter named who. getParameter() is a Java method for obtaining information from the HTML which defines a Web page. And finally...how to embed applets in your HTML pages! A simple HTML file that loads the Variable Hello applet is shown in Figure 4. The applet specification begins with an <APPLET> tag, which has three modifiers. The code modifier specifies the name of the Java bytecode file VH.class. The width and height modifiers specify a default area which the browser should allocate in order to display the applet's graphics. Any number of <PARAM> tags may be specified between <APPLET>'s opening and closing tags. Our example shows a single parameter with the name who and the value "all you Java programmers". The name and value modifiers are always interpreted as strings. FIGURE 4 The Variable hello HTML file.

<title>Variable Hello</title> <'hr> <applet code="VH.class" width=300 height=100> <param name=who value="all you Java programmers"> </applet> <hr> <a href="VH.java">The source.</a>
Since this HTML specified a value for the who parameter, the getParameter() method will place its value in the String variable who. Had there had been no <PARAM> tag defining a who parameter, then getParameter() would have returned null, and the second line of code in init() would have given the variable who the predictable default value "world". The init() next calls the method getDocumentBase() from the java.net package, and stores the result in the local variable uwhere. This variable is of type URL, and will contain a description of this page's URL. A printable representation of the URL is obtained using the toString() method. Finally, init() constructs two greeting messages and places them in the class variables msg1 and msg2.

msg1 contains the fixed string "Hello", followed by the value of who and another comma. msg2 reports the source of the greeting by combining "from" and the string form of the URL. As in Primes.java, "+" is used to join strings together. The run() and paint() methods are both very simple. The run() method gets the default size of the applet using the preferredSize() method, and then calls resize(). This is a polite request to the browser to restore the applet's drawing area to 300x100, in case the window size has been modified in some way. run() then calls the Java method repaint(), which will arrange to completely redraw the applet's drawing area. By a series of circuitous internal steps, this call to repaint() will ultimately invoke the paint() method, which we have overridden. paint() is called with a Graphics context g as its argument. We can now use a number of methods in the Graphics class to alter the drawing area. Here, we will simply change the text color to blue and then draw

the two Strings msg1 and msg2, one below the other. Figure 5 shows the resulting output using appletviewer, the Java applet viewer from the JDK. This example is extremely simple, but is does have all the components required of a fully functioning applet. It does not have any user interaction, however. Figure 6 shows an upgraded version of the VH applet which will respond to a user's mouse click. The HTML file that loads it is shown in Figure 7. FIGURE 6 The interactive version of the Variable Hello applet.

1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:

/** A simple Java applet to issue an HTML-specified greeting, with a tiny bit of user interaction @author Mark C. Reynolds @version 1.0 */ import java.awt.*; import java.net.*; public class VH2 extends java.applet.Applet implements Runnable { String String String Image boolean msg1; msg2; imgnam = null; img; doimg = false;

public void init() { String who; String where; URL uwhere; who = getParameter("who"); if ( who == null ) who = "world"; uwhere = getDocumentBase(); where = uwhere.toString(); imgnam = getParameter("image"); if ( imgnam != null ) { img = getImage(uwhere, "image/" + imgnam + ".gif"); } msg1 = "Hello, " + who + ","; msg2 = "from " + where; } public boolean mouseDown(Event e, int x, int y) { doimg = true; repaint(); return(true); } public void paint(Graphics g) { Dimension d = size(); g.drawRect(0, 0, d.width - 1, d.height - 1); g.setColor(Color.blue);

47: 48: 49:

50: 51: 52: 53: 54: 55: } 56: 57: public void run() { 58: resize(preferredSize()); 59: repaint(); 60: } 61: }

g.drawString(msg1, 10, 15); g.drawString(msg2, 10, 30); g.drawString("Click anywhere to see mouse event tracking", 10, 45); if ( doimg == true && imgnam != null ) { g.drawImage(img, 10, 60, this); g.setColor(Color.red); g.drawString("Squeek!", 10, 70 + img.getHeight(this)); }

FIGURE 7 HTML for the Variable Interactive Hello page.

<title>Variable Interactive Hello</title> <hr> <applet code="VH2.class" width=300 height=300> <param name=who value="all you Java programmers"> <param name=image value="mouse"> </applet> <hr> <a href="VH2.java">The source.</a>

Adding Interaction
This Variable Interactive Hello applet has init(), run() and paint() methods, as before. It also has a mouseDown() method, which overrides the built-in method of that name. The init() method for this VH2 class is almost the same as the init() method in VH, except that it also looks for a parameter named image. If it is found, then the class variable imgnam will hold its value. In this case, the init() method also attempts to access that image using the getImage() method. The first argument to that method is the URL of the current page, stored in uwhere; the second specifies a relative pathname for the image. Since our HTML gives the value of imgnam as "mouse," a file named mouse.gif in the subdirectory image will be retrieved, if possible. The mouseDown() method is called whenever a mouse button has been pressed. This method sets the class variable doimg to true, and then calls repaint to redraw the applet. Note that doimg is initialized to false, and is only toggled to true in the event of a user mouse click. The method returns true to indicate that it has handled the event. The paint() method used here is significantly different than in VH. It begins by determining the current size of the Applet's drawing area via a call to size(). It then uses the drawRect method of the Graphics class to draw a blank rectangle covering the entire drawing area (a quick-and-dirty way to clear it). As in VH, the applet then sets the text color to blue and prints the two greeting strings, followed by an invitation to the user to click anywhere. If the class variable doimg is true and the class variable imgnam is not null, then the image retrieved during the init() method will be displayed, followed by the message "Squeek!" in red. The method call img.getHeight(this) returns the height of the image. This is used in the calculation of the y coordinate of the "Squeek!" string, so that it will appear just below the mouse GIF. Logically, how does this work? When the page is first loaded, init() is called, followed by run(). The run() method calls repaint(), which generates its own call to paint(). At this point, doimg will still

10

have its initial value of false. Therefore, only the two greeting strings will be drawn, followed by the enticing invitation to click anywhere. The applet will then sit in an event loop, waiting for something to happen. If the user accepts the invitation and clicks within the applet's drawing area, then the mouseDown() method will be called by AWT's event handler. Our mouseDown() method will then set doimg to true and call repaint(). This forces a second pass through the paint() method. This time the three strings will again be drawn, but the image and the final red "Squeek!" will be displayed as well. The user has caused a GIF and a string to appear by clicking within the applet.

For More Information . . .


Even though this example uses less than 50 lines of code, it still manages to illustrate some of the interactive power of Java. One of Java's great advantages is that it incorporates many of the most common user interface, network and parsing tools within its extensive class hierarchy. For this reason it is possible to build up much more sophisticated applets without requiring vast amounts of code. In the second part of this article we will explore some of these capabilities in greater depth. Until then, there are several places you can explore to learn more about Java. The ultimate resource is Sun's own Java home page, where documentation links lead to the Java Programmer's Manual, complete specifications for every class within the Java class hierarchy, and a specification for the Java Virtual machine, among other documents of interest. Netscape's home page also contains several interesting links to Java applet code and other Java resources. One final note of caution: This examples in this article used the Beta 2 version of the Java language, classes and tools. When browsing the Web you will undoubtedly encounter earlier versions, including the Beta 1, "Pre-Beta" and Alpha-3 versions of Java. While the Beta and PreBeta versions are quite similar, the differences between the Alpha-3 version and the others are particularly severe. If you see HTML documents with an <APP> tag, or Java source attempting to import awt.* rather than java.awt.*, beware--these are no longer supported.

11

Vous aimerez peut-être aussi