As our civilization becomes increasingly dependent upon computers, many people foresee a shortage of programmers. Foresee? It's here! And those of us in the industry have to be the ones to do something about it. One solution that seems to be firming up is the concept of component architectures. In this model, programmers build sophisticated software components-small tools that do various jobs. Then end users, or others who are not professional programmers, put these components together into an application.
Netscape supports component architectures with their LiveConnect technology. With LiveConnect, Netscape gives sophisticated end users a way to control complex components (plug-ins and Java applets) from a relatively simple language-JavaScript, bringing component architecture to the Web.
Part V of this book, "LiveConnect," describes LiveConnect itself. This chapter describes Java, the centerpiece of LiveConnect. Since Java is a platform-independent language, Java applets can be written once and run on any supported platform, including OS/2 Warp, Macintosh, UNIX, and Windows. Navigator supports the direct use of Java applets-you do not need to know about LiveConnect in order to use an applet on your page.
"The more things change, the more they stay the same." In the early days of computing, every computer manufacturer had its own operating system. If you wrote a program for an IBM mainframe, it wouldn't run on a DEC minicomputer. Over the years, open standards such as UNIX emerged. Today you can write a C or C++ program that will run on dozens of different hardware platforms, if you stick with the open UNIX standard (called POSIX).
Alas, in the desktop computer market, UNIX is at best a minor player. If you write a C++ program for Windows 95, it won't necessarily run on Windows 3.1. If you write a program for OS/2 Warp, it won't run on the Macintosh. While the C++ language is highly portable from one operating system (OS) to the next, the library calls are OS-specific. Although there are techniques to make it less difficult to port from one platform to another, nobody claims it's easy.
Sun Microsystems, of course, is a major player in the UNIX market. Some of the most important innovations on the Internet have come from Sun. If a platform independent library existed, Sun could move some of their technology from the narrow UNIX market to the broader desktop market of Macs, OS/2 Warp, and Windows (in all its flavors).
Sun Microsystems developed Java to serve as a vehicle for moving its technology to a broader market. The Java language compiles into bytecodes that run on the Java Virtual Machine (JVM). Any platform with an implementation of the JVM can run compiled applications of Java bytecodes. This fact means that you, as a Java programmer, can truly "write once, run anywhere."
While you can write full applications in Java, the most common use of the language so far is to write applets-small programs that are intended to be embedded in an HTML page. This way, you can use applets as one component of a Netscape ONE network-centered application.
You can also integrate Java applets with Navigator plug-ins and JavaScript by using Netscape's LiveConnect technology (described in Part V). In a typical Netscape ONE application development team, you can use professional programmers to write Java applets and Navigator plug-ins and have team members with less programming experience write JavaScript and HTML. Using LiveConnect in this way is an example of component technology.
Once you have written an applet (or have an applet that someone else has written), you include it in your Web page by using the <APPLET> tag. The example coming up later in this chapter will show the following line:
<APPLET CODE="hello.class" WIDTH=120 HEIGHT=120></APPLET>
Depending upon what information needs to be passed to the applet, you may need to include additional parameters. For example, you might write:
<APPLET CODEBASE="http://example.applet.net/html/classes" CODE="zee.class" HEIGHT=120 WIDTH=120> <PARAM LOOP="true"> <PARAM ZEE="bar"> <HR> <P> If you had a <STRONG>Java</STRONG>-enabled browser you would see a zee applet here. </P> <HR> </APPLET>
This code says to look at http://example.applet.net/html/classes for the classes of the applet that starts in zee.class. The resulting applet window will have the dimensions given in the HEIGHT and WIDTH attributes.
When the applet starts, the browser will pass two parameters to it-LOOP and ZEE, with the values given. All parameters are passed as strings.
If the browser understands the <APPLET> tag, it ignores any HTML code between <APPLET> and </APPLET>. Only those users whose browser does not understand <APPLET> will see the HTML, which suggests that they might want to get a Java-aware browser.
To get started with Java, you need a Java development environment.
The Java Development Kit (JDK) is available from Sun. While you'll
need additional components from Netscape to write LiveConnect-compliant
Java applets, you can get started with only the components of
the JDK.
Note |
The programming world is quickly filling with Java development tools. Borland has included Java capability in Borland C++ 5. Metroworks, the developer of the leading Macintosh development environment, offers a Java compiler in its Discover Java kit; that compiler is also part of Metrowork's CodeWarrior Gold with Java Tools. Several companies, including Symantec (developers of Café) and Natural Intelligence (developers of Roaster) offer complete graphical environments. You can develop the examples shown in this chapter with the JDK alone or with any of the commercial tools. The instructions given in this chapter assume you are using the JDK-follow the instructions that come with your commercial toolkit if you choose one of those environments. |
Start by writing a Java "Hello, world!" program. The text file for this program is shown in Listing 7.1.
Listing 7.1 -The Java "Hello, world!"
Program
import java.applet.*; import java.awt.*; public class hello extends Applet { public void init() { } public void paint (Graphics g) { g.drawString("Hello", 10, 50); } }
Don't worry about what these lines do-this chapter goes through this applet line by line just a bit later.
You can compile the applet from the command line with the following:
javac hello.java
The Java compiler, javac, produces a file with Java bytecodes that may be run in a browser like HotJava or Navigator. This output file is called hello.class. You can run it by writing a small HTML file, and then typing this line:
appletviewer hello.html
The file hello.html need have only a single line:
<APPLET CODE="hello.class" WIDTH=120 HEIGHT=120></APPLET>
The finished product should resemble Figure 7.1.
Figure 7.1 : Use the appletviewer to get a quick look at your applets.
Now let's go through hello.java line by line.
Just as you do in C++, as a Java programmer, you usually can find some base class to serve as a starting point for your program so that you don't have to write everything from scratch. Sun conveniently supplies class Applet, so we derive hello from Applet. (Note that Java, like C++, is case-sensitive.)
Java uses the following notation to access a specific method:
packageName.className.methodName
Therefore, to access the drawString() method of an instance of class Graphics (part of the package named java.awt), you import the class java.awt.Graphics and then call drawString() on an instance of class Graphics. You can get all methods on all of the classes in a package by placing * in the className position.
Start by telling the Java compiler that Applet is defined in another file, in the classes\java\Applet subdirectory. Java's import directive strongly resumes the #include directive commonly used in C and C++. The following line tells the Java compiler to include all of the methods of class Applet:
import java.applet.*;
All your applets will start with this line.
Most applets do some kind of drawing to the window, so you usually
want to use class
Graphics, part of Sun's Abstract
Windowing Toolkit (AWT). (The AWT is described in more detail
later in the chapter.) Graphics
is defined in the java\awt\Graphics subdirectory. For convenience,
you bring in all of these useful classes by including the entire
AWT:
import java.awt.*;
By default, Java classes are not public.
Because you want to be able to access class hello
from the outside world, declare it to be public.
You also declare that it is derived from class Applet
so that it inherits the behavior necessary to allow it to interface
with the Web browser.
Tip |
When a class name is made public, the class must be defined in a file of the same name. Therefore, class hello must be saved to a file named hello.java. If your Java file includes a line like public class hello extends Applet the name of the Java file must match the name of the class-in this case, hello. |
Just like C++ classes in class libraries, such as Microsoft Foundation Classes (MFC), Java classes have methods that the outside world calls. When the class is constructed, its init() method is called. You define init() as a stub-anything that should be done by the class when it is constructed can go in here.
public void init() { }
If you've programmed in C or C++, you'll recognize much of this syntax. The keyword public means the method is accessible to other classes outside of hello. The keyword void declares that this method does not return any result. The name of the method is init(), and it does not take any parameters.
Just as Windows sends the message WM_PAINT every time a window needs to be redrawn, so Java calls your class's method paint() when the window has to be displayed. paint() takes an AWT Graphics object as its parameter, as follows:
public void paint(Graphics g) { g.drawString("Hello, world!", 10, 50); }
Much of this declaration resembles init(), but paint() takes one parameter-an AWT Graphics object. The formal name of the parameter, g, is used inside the method implementation in order to call the Graphics.drawstring() method.
To access the applet from Navigator, rather than just from AppletViewer,
copy the line from hello.html into the HTML file of your Web page.
Now you have a (very simple) Java applet on your page.
ON THE WEB |
You can download the latest version of Sun's Java Developer's Kit (JDK) online at http://java.sun. com/products/JDK/index.html. The Netscape modifications are also available online, at http://home.netscape.com/eng/mozilla/3.0/handbook/plugins/wr3.html as part of the Navigator plug-ins Web site. You can also use commercial packages, such as the ones mentioned earlier in this chapter, but you'll need the classes from Netscape's version of the kit if you want to make your applets work with LiveConnect. You'll also need Netscape's special version of javah (also part of the plug-ins material). |
The example in the last section shows you how to build a simple applet and install it on your HTML page. This section describes a series of increasingly sophisticated Java programming techniques that you can use in your applets. Even if you use all the techniques described here, you'll still just be scratching the surface of Java. Be sure to read the on-line documentation and one of the books on Java (both of which are described later in the chapter) to take full advantage of this powerful programming language.
Extending Classes One of the most powerful tools in object-oriented programming is subclassing. Java comes with a large number of class libraries (called packages)-Netscape and third-party developers are releasing even more. You can use the classes in these libraries as-is, or you can derive your own class from one of the stock classes. The process of deriving a new class from an existing base class is called subclassing.
The examples later in this chapter show several examples of subclassing, in which the class is declared with a line such as
class myThread extends Thread
That line says that a new class, myThread, has been declared by the programmer, and that myThread is derived from the base class Thread (built into Java).
Things to Do in init() Recall that the Java runtime environment will call the init() method of any class when you build an instance of that class. For your top-level class (such as hello in the example earlier in this chapter), you can count on init() being run when the applet is loaded. Here are some calls you may want to make in init():
Public Variables You can also declare variables at the class level, outside of any function. These variables are accessible by any function. Listing 7.2 shows an example of a public variable, I.
Listing 7.2 -This Java Applet Shows an Example of
a Public Variable
import java.applet.*; import java.awt.*; public class expub1 extends Applet { int i; public void init() { resize(300,500); } public void paint (Graphics g) { g.drawString("i's current value is " + i, 10, 50); } public boolean mouseUp(Event theEvent, int x, int y) { i++; repaint (); return true; } }
Compile expub1.java and install it in an HTML page. Note that
as you click the mouse, i
is incremented and the applet window is repainted (causing paint()
to be called again).
Note |
Class Applet contains the prototype for mouseup() and requires that it return a Boolean value. For now, it's convenient to return true. |
You can put public variables to a more practical use by using them to pass information from one method to the next. Consider the Java class shown in Listing 7.3.
Listing 7.3 -This Java Applet Shows Public Variables
Being Used to Pass Information from One Method to Another
import java.applet.*; import java.awt.*; public class expub2 extends Applet { int fromX; int fromy; int fromOrTo; int toX; int toY; public void init() { resize(300,500); } public void paint (Graphics g) { g.Line(fromX, fromY, toX, toY); } public boolean mouseUp(Event theEvent, int x, int y) { if (fromOrTo == 0) { fromX = x; fromY = y; fromOrTo = 1; } else { toX = x; toY = y; fromOrTo = 0; repaint(); } return true; } }
Java initializes integer variables to zero, so when paint() is called initially, Java runs drawline(0,0,0,0)-no line is displayed. (You can explicitly initialize a variable to any value you like by using the assignment operator.) Every subsequent call to paint() is triggered by the odd calls to mouseup(), so fromX, fromY, toX, and toY all have values in them that represent the coordinates of the mouse clicks. Compile expub2 and install it to see how it works.
Sun's AWT can do much more than draw text strings and lines. This section describes a few of the methods available in the AWT and other standard packages.
The AWT can support about the same range of windows activities as you would see in a graphical operating system such as Windows or Mac OS. Many of the more interesting applets work with images. Recall that one of the functions you may want to call in init() is getImage(). If you store the result of that function call in a global Image variable, you can display it by passing it to the drawImage() member of the Graphics() class. Listing 7.4 shows an example that displays such an image.
Listing 7.4 -This Java Applet Loads and Displays
an Image
import java.applet.*; import java.awt.*; public class eximg1 extends Applet { Image anImage; public void init() { anImage = getImage(getCodeBase(), "theImage.gif"); resize(300,500); } public void paint (Graphics g) { g.drawImage(anImage, 10, 15, this); } }
Of course, if all you want to do is display an image, the <IMAGE> tag works quite well. Listing 7.5 shows an advanced use of drawImage()-animation.
Listing 7.5 -This Java Applet Loads and Displays
a Series of Images
import java.applet.*; import java.awt.*; public class eximg2 extends Applet { Image theImage[]; int i; public void init() { theImage = new Image[17]; for (i=1; i<=17; i++) { theImage[i-1] = getImage(getCodeBase(), "T" + i + ".gif"); } i=0; } public void paint (Graphics g) { g.drawImage(theImage[i], 50, 100, this); } public boolean mouseUp(Event theEvent, int x, int y) { repaint(); i++; if (i == 17) i = 0; return true; }
If you read through this code (or if you compile it, install it, and run it), you'll discover that this applet gives pretty sluggish animation-you have to click the mouse button to advance from one frame to the next. (One of those frames is shown in Figure 7.2.) Of course, we could modify mouseUp() so that it runs through all of the frames, one after the other. We could even modify init() so that it starts the animation and runs it continuously once the applet is loaded. If we were to do that, however, the applet would take over the machine and would not yield to any other mouse clicks or keystrokes. If you've had experience with multitasking operating systems, you know what you want-a new thread.
Figure 7.2 : Repeated calls to drawImage( ) gives you one way to put up animation.
Whenever you need a thread, you have to declare that the class
implements Runnable and add
a new class method: run().
Caution |
If you add implements Runnable to the class declaration but make no other changes, you'll get an obscure error message, class xyz must be declared abstract. The class is missing a run() member. Just add the run() member and the error message will go away. If you add implements Runnable and add run(), your class will compile without error, but you still won't have a new thread. You need to remember to declare a thread and call start() on that thread before you have a new thread for your applet. |
Note |
In many operating systems, separate paths of execution with spaces are called processes. A "light-weight process" that shares address space with its parent goes by the special name, "thread." By that definition, Java implements processes but calls them threads. |
A Single-Threaded Example Listing 7.6 shows a simple implementation of a multithreaded applet. The method showStatus() puts a message in the status line at the bottom of the browser window.
Listing 7.6 -This Java Applet Runs in Its Own Thread
import java.applet.*; import java.awt.*; public class eximg1 extends Applet implements Runnable { Thread t; int i; public void init() { t = new Thread(); t.start(); } public void run() { showStatus("Running"); while (true) { i++; repaint(); } } public void paint(Graphics g) { g.drawString("i's value is " + i, 10, 20); } }
To understand the role of each of these new components, "break" the applet in various ways. For example, if you delete the call to t.start(), the applet will compile with a new thread, but run() never gets called. If you take
i++; repaint();
out of the while loop in run(), you'll see i increment to 1 and stop-run() is only called once, so unless you put a loop in it, your run() action is called only one time.
Animation in a Threaded Applet With the thread framework in place, we can now build an improved animation applet, shown in Listing 7.7.
Listing 7.7 -This Java Applet Loads and Displays
an Image
import java.applet.*; import java.awt.*; public class eximg2 extends Applet implements Runnable { Image theImage[]; Thread t; int i, k; Button start, stop, suspend, resume; public void init() { theImage = new Image[17]; for (i=1; i<=17; i++) { theImage[i-1] = getImage(getCodeBase(), "T" + i + ".gif"); } t = new Thread(this); start = new Button("Start"); stop = new Button("Stop"); suspend = new Button("Suspend"); resume = new Button ("Resume"); add(start); add(stop); add(suspend); add(resume); } public void run() { while (true) { repaint(); k++; if (k==17) k = 0; } } public boolean action(Event theEvent, Object theObject) { boolean theResult = false; if ("start".equals(theObject)) { t.start(); theResult = true; } else if ("stop".equals(theObject)) { t.stop(); theResult = true; } else if ("suspend".equals(theObject)) { t.suspend(); theResult = true; } else if ("resume".equals(theObject)) { t.resume(); theResult = true; } return theResult; } public void paint (Graphics g) { g.drawImage(theImage[k], 10, 25, this); } }
A Multithreaded Example The examples in the previous section contain a public variable of type Thread. There's no reason you can't declare more than one such variable or even build them dynamically as the program runs. For example, Listing 7.8 starts a new thread each time the user clicks the mouse.
Listing 7.8 -This Applet Starts a New Thread with
Every Mouse Click
import java.applet.*; import java.awt.*; public class threads1 extends Applet implements Runnable { Thread aThread; public boolean mouseUp(Event theEvent, int x, int y) { aThread = new Thread(this); aThread.start(); return true; } public void run() { while(true) { showStatus(aThread.getName()); } } }
Most of the time, you don't want every thread to do exactly the same work as all the others. You need to derive new classes from Thread and put the new classes to work. Listing 7.9 shows how to derive new classes from Thread.
Listing 7.9 -This Applet Starts a New Thread with
Every Mouse Click
import java.applet.*; import java.awt.*; class myThread extends Thread { int i; threads2 theApplet; public myThread(threads2 a) { theApplet = a; i = 0; } public void run() { while (true) { i++; theApplet.repaint(); } } class yourThread extends Thread { int i; threads2 theApplet; public myThread(threads2 a) { theApplet = a; i = 0; } public void run() { while (true) { i++; theApplet.repaint(); } } } public class threads2 extends Applet implements Runnable { myThread aThread; yourThread anotherThread; public void init(); { aThread = new myThread (this); yourThread = new yourThread (this); aThread.start(); anotherThread.start(); aThread.setPriority(Thread.MIN_PRINORITY); anotherThread.setPriority(Thread.MAX_PRIORITY);\ } public void paint(Graphics g { g.drawString("myThread value: " + aThread.i, 10, 30); g.drawString("yourThread value: " + anotherThread.i, 10, 60); } }
Advanced Techniques Modern programming languages and operating system libraries include mechanisms such as interprocess communication and sophisticated exception handling. Java includes these high-end mechanisms. Listing 7.10 shows an applet that demonstrates these mechanisms.
Listing 7.10 -This Applet Demonstrates Exception
Handling and Inter-Thread Communication
import java.applet.*; import java.awt.*; class myThread extends Thread { hiend theApplet; myThread(hiend a) { theApplet = a; } public void run() { int k ; for (k=0; k<1000;k++) { theApplet.i++; theApplet.repaint(); } theApplet.sendNotify(); theApplet.doWait(); while (k < 2000) { theApplet.i++; theApplet.repaint(); k++; } theApplet.sendNotify(); } } class yourThread extends Thread { hiend anApplet; yourThread(hiend a) { anApplet = a; } public void run() { int m; anApplet.doWait(); do (m=0; m<1000; m++) { anApplet.j++; anApplet.repaint(); } anApplet.sendNotify(); anApplet.doWait(); while (m< 2000) { anApplet.j++; anApplet.repaint(); m++; } } } public class hiend extends Applet { myThread aThread; int i=0; yourThread anotherThread; int j=0; public synchronized void sendNotify() { notify(); } public synchronized void doWait() { try wait(); catch (Exception e) { } } public void init() { aThread = new myThread(this); aThread.start(); anotherThread = new yourThread(this); anotherThread.start(); } public boolean mouseDown(java.awtEvent theEvent, int x, int y) { return true; } public void paint(Graphics g) { g.drawString("Value of i in myThread " + i, 1, 10); g.drawString("Value of j in yourThread " + j, 1, 40); } }
Recall that Sun is a leader in the UNIX workstation market. UNIX workstations are characterized by a layered implementation of a graphical user interface, called the X Window System. The X Window System is an industry-standard software system that allows programmers to develop portable graphical user interfaces. Versions of the X Window System exist for all popular operating systems, but the most common environment is UNIX.
The "plain vanilla" X Window System provides a C language interface known as Xlib. Although some programmers write programs that call Xlib directly, most find this interface tedious and difficult to use correctly. Xlib doesn't provide direct support for scroll bars or minimize, maximize, and close buttons-the basic ingredients of most windows programming.
Many sets of tools were developed to provide an interface between the application program and Xlib. The X Toolkit, which includes the Xt Intrinsics layer and a set of high level widgets, is popular. ("Widgets" and "gadgets" are the names the X community has coined for reusable application-level objects. Widgets implement the scroll bars, menus, buttons, and other controls that are so popular in a graphical user interface.) Most programmers also use a windows manager, such as Motif, to integrate widgets into a consistent look and feel. Figure 7.3 illustrates the relationship between these components. The top layer of the architecture, shown in Figure 7.3, also includes gadgets, which are similar to widgets but have no associated window.
AWT is not based on the X Window System, but Sun's experience with X shows through in their development of AWT. The AWT contains low-level drawing routines that correspond to Xlib, as well as widgets that do useful things on the screen. Here's a partial list of the widgets built into the AWT, with explanations for the less obvious members:
You can add one of these widgets to your applet by calling add, like this:
add(new TextField());
or
add(new Button("stop"));
If the widget is assigned to a variable, the methods of the object can be called. The following sections show key methods for each major AWT widget.
Buttons Suppose you declare a new button, as shown in Listing 7.11.
Listing 7.11 -This Little Applet Adds a Button Dynamically
import java.applet.*; import java.awt.*; public class doButton extends Applet { Button b; public void init() { b = new Button("myButton"); add(b); } }
Once you have a button object (in this case, b), you can call methods:
TextField and TextArea Like Button, you call methods on TextFields and TextAreas through objects:
Listing 7.12 shows a simple applet that uses a TextArea object.
Listing 7.12 -This Applet Uses a TextArea Object
import java.applet.*; import java.awt.*; public class tarea extends Applet { TextArea t; public void init() { t = new TextArea(); add(t); } public boolean handleEvent(Event e) { if (e.target instanceOf TextArea) { t.setForeground(Color.blue); setBackground(Color.red); } else setBackground(Color.blue); repaint(); return false; } }
Choice and List Once you have a Choice or List object, you can add options with addItem()-it takes a string. Use delItem() to remove items. This function takes an integer, which identifies the item to be removed. The first item on the list is the "zeroth" item.
You can specify how many items appear on the list. You can also specify whether or not multiple selection is permitted. For example,
List aList; aList = new List(3, false);
says that the List named
aList shows only three items
and does not permit multiple selections. Read the index of the
current selected item with getSelectedIndex();
read the item name with getSelectedItem().
CountItems() returns the
number of items in the list.
Caution |
The Java specification mentions clear(), which should remove all items on a list. In some runtime environments in the early days of Java, clear() did not work. Test it in your environment(s) or simulate it by calling delItem() the number of times given by CountItems(). |
Scrollbars The constructor for a scrollbar takes five parameters (though there are simplified constructors for scrollbars that default on various items). For example,
Scrollbar s; s = new Scrollbar(Scrollbar.HORIZONTAL, 10, 5, 1, 100);
puts up a horizontal scrollbar with a minimum value of 1 and a maximum value of 100. The scrollbar is initially set at 10. Every time the user uses the scrollbar to move up or down on the "page," the contents will move by 5 units.
You can get and set the value of the scrollbar with getValue() and setValue(), respectively.
When putting up scrollbars, you will usually want to use a BorderLayout. Layouts are described in the next section.
Built-In Layouts You can define controls, such as Buttons and Scrollbars, and place them anywhere you want in the applet's window. If you'd like to start with a predefined description of where the components should be placed, however, use one of Java's built-in layouts.
One of the most popular layouts is BorderLayout. This layout breaks the applet's portion of the screen into five parts: north, south, east, west, and center. You can add controls to any of these parts. Listing 7.13 shows how. Figure 7.4 shows the result of running Listing 7.13 but with the setLayout() function removed and the references to the layout removed from the add() functions. Figure 7.5 shows the result of running useLOut.class with the layout intact.
Figure 7.4 : If you use only the default layout, the result may look a bit stodgy.
Figure 7.5 : This applet was built with BorderLayout.
Listing 7.13 -Use a BorderLayout to Organize Your
Applet's Visual Space
import java.applet.*; import java.awt.*; public class useLOut extends Applet { Button a, b, c, d, e; public void init() { setLayout(new BorderLayout()); a = new Button("a"); b = new Button("b"); c = new Button("c"); d = new Button("d"); e = new Button("e"); add("North", a); add("South", b); add("East", c); add("West", d); add("Center", e); list(); } }
Caution |
If you fill a section of BorderLayout with a button, mouseUp() and mouseDown() calls will be handled by the button and will not get to the Applet class. If you want to have the user click in the center of the window and handle those clicks in mouseUp() or mouseDown(), delete the line add("Center", e); |
The AWT comes with five more layouts besides BorderLayout, including:
Listing 7.14 shows how to use the GridBagLayout.
Listing 7.14 -The GridBagLayout Is Particularly
Flexible
import java.applet.*; import java.awt.*; public class gridBag extends Applet { protected void putButton(String aString, GridBagLayout theLayout, GridBagConstraints theConstraints) { Button theButton = new Button(aString); theLayout.setConstraints(theButton, theConstraints); add(theButton); } public void init() { GridBagLayout theLayout = new GridBagLayout(); GridBagConstraints theConstraints = new GridBagConstraints(); setLayout(theLayout); theConstraints.weightx = 1.0; putButton("a", theLayout, theConstraints); putButton("b", theLayout, theConstraints); putButton("c", theLayout, theConstraints); putButton("d", theLayout, theConstraints); putButton("e", theLayout, theConstraints); } }
Figure 7.6 shows the this applet in action. Be sure to set weightx of the GridBagConstraints to a positive number. Otherwise, all of the buttons appear to "clump." (The default value of weightx is zero. Try it-you won't like it.)
Figure 7.6 : The GridBagLayout is one of the most flexiblie layouts in AWT.
You can play with the methods of GridBagConstraints to get different effects from the GridBagLayout. For example, write theConstraints.fill = GridBagConstraints.BOTH; to stretch the buttons to fill up the gaps. Options are BOTH, HORIZONTAL, and VERTICAL.
You can specify theConstraints.gridWidth = GridBagConstraints.REMAINDER; to expand the row to both vertical sides. Other options are BOTH and RELATIVE.
Your Own Layout Although you cannot subclass java.awt.LayoutManager, you can build your own layout by implementing a custom LayoutManager. Listing 7.15 shows how.
Listing 7.15 -Build Your Own LayoutManager to Make
a Custom Layout
import java.applet.* import java.awt.* class myLayout implements LayoutManager { public void layoutContainer(Container p) { int theComponentCount = p.countComponents(); int i; int x = 1; int y = 10; for (i = 0; i < theComponentCount; i++) { Component c = p.getComponent(i); Dimension d = c.preferredSize(); c.reshape(x, y, d.width, d.height); x = x+d.width+10; y = y+d.height+10; } } public Dimension minimumLayoutSize(Container p) { return (new Dimension(200,300)); } public Dimension preferredLayoutSize(Container p) { return (new Dimension(200,400)); } public void addLayoutComponent(String n, Component c) { } public void removeLayoutComponent(Component c) { } } public class lom extends Applet { Button a, b; TextField c; public void init() { setLayout(new myLayout()); add(a=new Button("a")); add(b=new Button("b, with a longer name than a")); add(c=new TextField("some text", 60); } public boolean mouseUp(Event e, int x, int y) { remove(a); add("New a", new Button("aa")); return true; } }
Figure 7.7 shows our layout in action.
Figure 7.7 : Build a clas that implements LayoutManager to get your own layout.
A typical applet appears in your HTML page and serves up some kind of information. Sometimes that information is built into the applet, sometimes it is retrieved from the local hard drive, and sometimes you will want to fetch that information from the Internet-not a surprising requirement if we are building a Netscape ONE network-centric application.
To build a net-aware applet you need to add two new sets of classes:
import java.net.*; import java.io.*;
Caution |
If you forget to import one of these classes, the Java compiler will complain about class xxx not found in yyy. When you see messages of this form, double-check to be sure that the package containing class xxx has, in fact, been included. |
Listing 7.16 shows a program that loads a file of strings from the network and puts them into a list. This program is careful to check each step (using Java's exception-handling mechanism, try and catch). In your applets you may want to be just as careful, or you may want to put more steps into a single try clause and handle exceptions in a more general catch clause.
Listing 7.16 -This Applet Could Be the Foundation
of a Network-Centric Application
import java.applet.*; import java.awt.*; import java.net.*; import java.io.*; public class net extends Applet { URL theURL; URLConnection theConnection; InputStream theInputStream; DataInputStream theDataInputStream; String aString; public void init() { setLayout(new BorderLayout()); List aList; aList = new List(3000, false); add("Center", aList); add("North", new Button("Start")); } public boolean action (Event e, Object o) { if ("Start".equals(o)) { try { theURL = new URL("http://www.dse.com/books/ONE/chap07/options.dat"); showStatus("URL is initialized"); } catch(MalformedURLException u) { showStatus("Error in URL"); return true; } try { theConnection = theURL.openConnection(); showStatus("Open Connection successful"); } catch(IOException e) { showStatus("Connection failed"); return true; } try { theInputStream = theConnection.getInputStream(); showStatus("Opening URL"); } catch(Exception e) { showStatus("Error reading file."); return true; } try { theDataInputStream = new DataInputStream(theInputStream); showStatus("Connecting to data"); } catch(Exception e) { showStatus("Data error."); return true; } try { while ((aString = theDataInputStream.readLine() != null) { showStatus("String " + aString); aList.addItem(aString); } theDataInputStream.close(); theInputStream.close(); } catch(Exception e) { showStatus("Read String/Add Item not successful"); return true; } } return false; } }
There is much, much more you can do with Java. The examples in this chapter barely scratch the surface. If you are familiar with C++ and the broader world of object-oriented analysis and design, you'll be pleased to know that Java includes provisions for abstract classes and the explicit declaration of interfaces. Java includes many powerful image manipulation functions (in java.awt.image.*), network security routines (in java.net.*), and utilities (in java.lang.* and java.util.*). A proper treatment of Java can easily fill a book-see Special Edition Using Java, Second Edition (Que, 1996) for a well-written example.
Sun has provided a rich set of Java classes. As part of Netscape
ONE, Netscape has built on the Sun classes to provide even more
widgets-the Netscape Internet Foundation Classes (IFC). If your
application requires a more powerful user interface than the ones
supported by AWT, you can call the widgets and components in IFC
and get sophisticated controls and layouts without writing them
from scratch.
Caution |
The IFC contains powerful Java classes. Because Netscape supports integration between Java and other languages, IFC is accessible to plug-in programmers and JavaScript programmers, as well as Java applet programmers. While you can access them from JavaScript, the classes and the documentation assume that the person using them is a professional programmer. If you have written JavaScript but have not yet progressed to writing plug-ins or Java programs, gain some specific Java experience before attempting to use the IFC. |
ON THE WEB |
http://developer.netscape.com/nifcfaq.html This site provides the Frequently Asked Questions (FAQs) list about the IFC and is a good starting point for Netscape ONE developers who want to do more with Java. |
Netscape has announced that IFC will be bundled with every copy of Navigator, starting with version 4, so you can use IFC in your applets and be confident that the end user will have IFC on his or her machine. You can also get it from the Netscape Web site. (See the URL at the end of this chapter.)
The Initial Release Netscape has announced fifteen widgets in version 1.0 of IFC:
Because the IFC consists of Java classes, you can use the classes directly or derive your own classes from them (to inherit general behavior). Netscape has also reported that they are working on a visual builder and application layout tool, called Netscape Constructor, which will support IFC as well as third-part widgets and components.
Future Classes Netscape is planning to include additional features in later releases of IFC, including:
Tip |
For a more in-depth look at Netscape's IFC, visit Chapter 16, "Internet Foundation Classes." |
Netscape describes the role of Java in Netscape ONE at http://developer.netscape.com/library/one/technologies.html#Java. From there, you can get to the classes you need for LiveConnect, in the Navigator Plug-Ins section of the site. Netscape maintains a complete list of documentation at http://developer.netscape.com/library/documentation/javalist.html. Sun provides a tutorial at http://java.sun.com/books/Series/Tutorial/.
In addition to the compiled classes used for LiveConnect, Netscape also offers a no-fee license to the IFC source code. Check out http://developer.netscape.com/library/ifc/index.htmlfor the latest information on IFC. You can get more information about licensing from devedge@netscape.com or by calling Netscape's DevEdge hotline at 415-937-2698.