One of the main goals of object-oriented software development is that objects can be reused, and Java is an excellent language for developing reusable objects. The extensive API provided by the JDK is testimony to this fact. One of the most important factors in making software usable and reusable is good documentation. This is another area where Java excels. The API packages of the JDK are examples of great software documentation. This documentation is automatically generated by the javadoc tool of the JDK.
In this chapter you'll learn how to use javadoc to automate the documentation for your software. You'll cover the basic documentation tags that are used with javadoc. You'll then learn how doclets are used to alter the output of javadoc. Finally, you'll explore JavaHelp, a new documentation technology being developed at JavaSoft. When you finish this chapter, you'll be able to quickly and easily document your software using javadoc.
javadoc examines your source code and generates HTML files that provide a fully integrated set of documentation for your Java software. The HTML files generated by javadoc document the classes, interfaces, variables, methods, and exceptions that you declare and use in your programs. These files describe your software at the package and class level. The linking capabilities of HTML are used to provide extensive cross-referencing between related software components. These links allow you to quickly access all of the documentation that is relevant to a particular topic.
javadoc differs from other documentation generators in that it goes beyond simple comment-scanning, actually parsing your source code to generate documentation that describes the structure and behavior of your programs. It makes judicious use of HTML links to generate documentation that allows you to easily traverse the structure of your software.
The javadoc program recognizes special types of comments that you insert into your source code. When it parses your source code, it combines these comments with the structural information it generates. Your comments then are integrated into your software's HTML description. The special comments recognized by javadoc consist of doc comments, javadoc tags, and HTML tags.
Doc comments are based on the traditional C /* and */ comment delimiters. They are distinguished from ordinary C comments in that they begin with /** instead of /*. However, doc comments still end with */.They are used to identify comments that are to be automatically added to the HTML documentation produced by javadoc.
The javadoc tags are special tags that are embedded in doc comments. These tags allow you to include reference information in your software. For example, you can include a javadoc comment that says See also: class X. Some references result in links being automatically inserted into your software's documentation.
javadoc also allows you to insert HTML tags directly into your source code. However, javadoc recommends that you limit your HTML to small, simple, and correctly formatted HTML elements so as not to conflict with the HTML that it generates. Your HTML tags are combined with those produced by javadoc to create an integrated set of HTML pages.
The best way to understand how javadoc works is by using it and then exploring the documentation that it produces. javadoc is so simple to use that it only requires a single command line to generate integrated software documentation for multiple software packages.
To use javadoc, create a separate appxd directory under your ju path. This directory will be used to store the HTML files that javadoc produces. You could store these files in the same directory in which you store your Java API documentation, but it's not a good idea to clutter up your API directory with other documentation.
NOTE: javadoc is a real memory hog, requiring at least 32MB of RAM. To make more memory available to javadoc, close any other open applications.
To run javadoc, launch a DOS shell, switch to the ju\appxd directory, and enter the following DOS command line:
javadoc -J-mx20m ju.ch09
The -J-mx20m option is passed to the java interpreter. It tells java to allow the heap to grow to a maximum of 20MB. javadoc generates the following output:
Loading source files for ju.ch09 Constructing Javadoc information. Generating tree.html Generating index.html Generating deprecatedlist.html Generating frame.html Generating packages.html Generating packages-frame.html Generating package-ju.ch09.html Generating package-tree-ju.ch09.html Generating package-frame-ju.ch09.html Generating ju.ch09.MessageDialog.html Generating ju.ch09.MyMenu.html Generating ju.ch09.MyMenuBar.html
As the result of that single command line, javadoc generates a complete set of HTML documentation for the menu software you produced in Chapter 9, "Creating Window Applications." This documentation will have the same look and feel as the Java API documentation.
When javadoc has finished producing the documentation, use your browser to view it. (I'll be using Internet Explorer 4.0.)
Launch your browser and use its local file open feature to open the file packages.html, located in the appxd directory. Your browser will display a Sun-style Package Summary page, as shown in Figure D.1.
FIGURE D.1. The Package Summary page.
With your browser open to the Package Summary, click on the Tree link. A Web page showing all the classes in the ju.ch09 package is presented to you. The page shows how your classes fit within the rest of the Java class hierarchy. It also identifies the interfaces that are implemented by your classes. The information presented in the class hierarchy page is extremely useful in understanding the structure of Java programs. See Figure D.2.
FIGURE D.2. The Class Hierarchy description page.
While you have the Class Hierarchy page loaded, click on the Index link. Another great Web page is displayed that contains an alphabetized index of all the fields (variables) and methods declared in the ju.ch09 package. Click around this page to see some of the items that you've used in your programs. When you have finished, click on the Contents link to go back to the Package Summary (see Figure D.3).
From the Package Summary, click on the ju.ch09 link. This will bring you into the Class Summary for the ju.ch09 package. This page documents the classes that are declared in this package (see Figure D.4).
From here, click on the MyMenu link. The class's description is displayed. Notice how it identifies the branch of the class hierarchy leading to the MyMenu class. A list consisting of a single constructor appears under the class hierarchy diagram. Click on the link to find a more detailed description of the constructor (see Figure D.5).
Under the constructor list is a list of the single method that is declared for the MyMenu class. Following that is a list of methods inherited from other classes. Then a detailed description of the MyMenu() constructor and getItem() method are provided.
FIGURE D.3. The Index page.
FIGURE D.4. The ju.ch09 Class Summary page.
FIGURE D.5. The MyMenu class page.
You should now have a pretty good idea of the kind of documentation that can be produced using javadoc. The most remarkable fact about the documentation produced in this section is that you did not have to write a single comment in your source code. It was generated automatically and is far more effective than any traditional program comments. However, if this level of documentation is not enough to satisfy your requirements, you can insert additional comments into your source code that will be integrated with the documentation produced by javadoc.
Doc comments, as discussed in the beginning of this chapter, are normal Java comments that begin with an extra asterisk. They are easy to insert into your Java programs, and they add implementation-specific information to your documentation. To show how they are used, I've added doc comments to the MyMenu.java source code. These comments can be easily identified in the new program listing for MyMenu (see Listing D.1). If you want to duplicate what I have done, you have to copy and paste the doc comments into the MyMenu.java file and then regenerate its documentation using javadoc.
package ju.ch09; import java.awt.*; import java.awt.event.*; /** * The MyMenu class is used to facilitate * the creation of menus. */ public class MyMenu extends Menu { /** * A MyMenu object is constructed from an * array of labels, an ActionListener, * and an ItemListener. */ public MyMenu(Object labels[],ActionListener al,ItemListener il) { super((String)labels[0]); String menuName = (String) labels[0]; char firstMenuChar = menuName.charAt(0); if(firstMenuChar == `~' || firstMenuChar =='!'){ setLabel(menuName.substring(1)); if(firstMenuChar == `~') setEnabled(false); } for(int i=1;i<labels.length;++i) { if(labels[i] instanceof String){ if("-".equals(labels[i])) addSeparator(); else{ String label = (String)labels[i]; char firstChar = label.charAt(0); switch(firstChar){ case `+': CheckboxMenuItem checkboxItem = new CheckboxMenuItem(label.substring(1)); checkboxItem.setState(true); add(checkboxItem); checkboxItem.addItemListener(il); break; case `#': checkboxItem = new CheckboxMenuItem(label.substring(1)); checkboxItem.setState(true); checkboxItem.setEnabled(false); add(checkboxItem); checkboxItem.addItemListener(il); break; case `-': checkboxItem = new CheckboxMenuItem(label.substring(1)); checkboxItem.setState(false); add(checkboxItem); checkboxItem.addItemListener(il); break; case `=': checkboxItem = new CheckboxMenuItem(label.substring(1)); checkboxItem.setState(false); checkboxItem.setEnabled(false); add(checkboxItem); checkboxItem.addItemListener(il); break; case `~': MenuItem menuItem = new MenuItem(label.substring(1)); menuItem.setEnabled(false); add(menuItem); menuItem.addActionListener(al); break; case `!': menuItem = new MenuItem(label.substring(1)); add(menuItem); menuItem.addActionListener(al); break; default: menuItem = new MenuItem(label); add(menuItem); menuItem.addActionListener(al); } } }else{ add(new MyMenu((Object[])labels[i],al,il)); } } } /** * The getItem() method returns the MenuItem * object identified by a String. */ public MenuItem getItem(String menuItem) { int numItems = getItemCount(); for(int i=0;i<numItems;++i) if(menuItem.equals(getItem(i).getLabel())) return getItem(i); return null; } }
You can see how these doc comments were integrated into the appropriate class, variable, and constructor descriptions by looking for them in my browser's display (see Figure D.6).
FIGURE D.6. Doc comments as displayed by a browser.
javadoc tags are special tags that are inserted into doc comments. They are used to identify specific references in your code. Special javadoc tags are provided for documenting classes, variables, and methods.
javadoc tags consist of an at sign (@) followed by a tag type and then a specific comment reference. Their syntax is as follows:
@tagType commentReference
Java classes and interfaces are allowed to use the see, version, author, since, and deprecated tag types. Variables can only use the see, since, and deprecated tag types. Methods are allowed to use the see, param, return, exception, since, and deprecated tag types.
The see tag type has the following syntax:
@see HTMLlink @see className @see fullClassName @see fullClassName#methodName
The see tag is used to reference other classes and methods that are related to the class, interface, variable, or method being documented.
The version and author tag types are used like this:
@version versionID @author authorNames
The version tag is used to associate a software version identifier with a class or interface. The author tag is used to identify the author of the class or interface.
The param, return, and exception tags are used as follows:
@param parameterName description @return description @exception fullClassName description
The param tag is used to document a method parameter. The return tag is used to describe the value returned by a method. The exception tag is used to document the exceptions that are thrown by a method.
The deprecated tag is a new tag introduced with the JDK 1.1. It is used to mark old API classes, interfaces, variables, and methods as superseded and about to be phased out. It is used as follows:
@deprecated comment
The optional comment is used to provide instructions on how to replace the superseded API element. For a good example of the deprecated tag, check out the JDK 1.2 API's description of the readLine() method of the java.io.DataInputStream class. If you used the JDK 1.0, you probably used readLine() to read console input. This method has been replaced by the readLine() method of the java.io.BufferedReader class.
The since tag is used to identify the JDK version in which a language feature was added. It is used as follows:
@since version
In order to demonstrate the use of these tags, I have modified the ju.ch09.MyMenuBar.java file to include param tags (see Listing D.2).
package ju.ch09; import java.awt.*; import java.awt.event.*; public class MyMenuBar extends MenuBar { /** * @param labels[] Menu labels * @param al ActionListener for menu selections * @param il ItemListener for menu checkboxes */ public MyMenuBar(Object labels[][],ActionListener al, ItemListener il) { super(); for(int i=0;i<labels.length;++i) add(new MyMenu(labels[i],al,il)); } /** * @param menuName Name of menu item */ public MyMenu getMenu(String menuName) { int numMenus = getMenuCount(); for(int i=0;i<numMenus;++i) if(menuName.equals(getMenu(i).getLabel())) return((MyMenu)getMenu(i)); return null; } }
Figure D.7 shows how the javadoc tags are integrated by javadoc and displayed by my browser.
FIGURE D.7. The browser's display of the javadoc tags.
If the doc comments and javadoc tags still aren't enough to meet your documentation requirements, you can always insert your own HTML markup into a doc comment. However, using HTML is a little bit dangerous because your HTML tags might conflict with the HTML tags inserted by javadoc. If you're going to use HTML in your documentation, try to keep it as simple as possible.
I've modified the source code in MessageDialog.java to include HTML address tags so that I can put my email address in the doc comment. See Listing D.3.
package ju.ch09; import java.awt.*; import java.awt.event.*; /** * Send your bug reports to: * <ADDRESS>[email protected]</ADDRESS> */ public class MessageDialog extends Dialog { public MessageDialog(Frame parent,String title,boolean modal,String text[], String buttons[], WindowListener wh, ActionListener bh) { super(parent,title,modal); int textLines = text.length; int numButtons = buttons.length; Panel textPanel = new Panel(); Panel buttonPanel = new Panel(); textPanel.setLayout(new GridLayout(textLines,1)); for(int i=0;i<textLines;++i) textPanel.add(new Label(text[i])); for(int i=0;i<numButtons;++i){ Button b = new Button(buttons[i]); b.addActionListener(bh); buttonPanel.add(b); } add("North",textPanel); add("South",buttonPanel); setBackground(Color.lightGray); setForeground(Color.black); pack(); addWindowListener(wh); } }
Figure D.8 shows how the HTML tags are integrated by javadoc and displayed by my browser.
FIGURE D.8 How a browser displays javadoc tags.
javadoc generates its documentation using doclets, which are Java programs that specify the content and format of the output of javadoc. In this appendix, you've been using javadoc's default doclet. However, you can create your own doclets to customize javadoc's output. Doclets can also be used to perform analyses of Java source and compiled code.
Doclets are written using the Doclet API, which consists of the sun.tools.javadoc package. This package is included with the classes.zip file that is located in the lib directory of the JDK 1.2 files. The sun.tools.javadoc package contains 1 interface and 16 classes. Figure D.9 shows the class hierarchy and describes the classes and interfaces.
Doclets are executed by the javadoc tool and are different from both applets and applications. The execution entry point for a doclet is a start() method of the following form:
public static boolean start(Root root) { . . . }
FIGURE D.9. The sun.tools.javadoc package.
The Root object provides the doclet with methods for gaining access to the information generated by javadoc.
Listing D.4 provides an example doclet that displays all packages, interfaces, classes, and class/interface members that have been processed by javadoc. Compile the doclet using javac, and then run it using the following command:
javadoc -J-mx20m -doclet MyDoclet ju.ch09
The -doclet option tells javadoc to use the MyDoclet class for generating its output. This output is as follows:
Loading source files for ju.ch09 Constructing Javadoc information. Package: ju.ch09 Class: MyMenu Constructor: MyMenu Method: getItem Class: MessageDialog Constructor: MessageDialog Class: MyMenuBar Constructor: MyMenuBar Method: getMenu
The MyDoclet class contains three static methods: start(), displayClasses(), and displayMembers(). The start() method is the doclet's entry point. It is passed an object of the Root class, which contains the information gathered by javadoc. The packages array is used to access the PackageDoc objects for each of the packages that were processed. These objects are returned by the specifiedPackages() method of Root. The indent string is used to format the doclet's output. A for statement is used to iterate through packages, and to display the package name and its interfaces and classes. The interfaces() and ordinaryClasses() methods of the PackageDoc class provide access to information about the interfaces and classes of a package.
The displayClasses() method is used to display information about a class or interface. It takes the following arguments:
The method iterates through the classes array and displays the name of the interface or class. It then uses the fields(), constructors(), and methods() methods of ClassDoc to retrieve the members of the interface or class. The displayMembers() method is invoked to display these members.
The displayMembers() method uses the outputType and indent arguments in the same manner as displayClasses(). Its other argument is an array of MemberDoc objects. It iterates through this array and displays the type and name of each member.
import sun.tools.javadoc.*; public class MyDoclet { public static boolean start(Root root) { PackageDoc[] packages = root.specifiedPackages(); String indent=""; for (int i = 0; i < packages.length; ++i) { System.out.println(indent+"Package: "+packages[i].name()); ClassDoc[] interfaces = packages[i].interfaces(); displayClasses("Interface: ",indent+" ",interfaces); ClassDoc[] classes = packages[i].ordinaryClasses(); displayClasses("Class: ",indent+" ",classes); } return true; } public static void displayClasses(String outputType, String indent,ClassDoc[] classes) { for(int i=0;i<classes.length;++i) { System.out.println(indent+outputType+classes[i].name()); FieldDoc[] fields = classes[i].fields(); displayMembers("Field: ",indent+" ",fields); ConstructorDoc[] constructors = classes[i].constructors(); displayMembers("Constructor: ",indent+" ",constructors); MethodDoc[] methods = classes[i].methods(); displayMembers("Method: ",indent+" ",methods); } } public static void displayMembers(String outputType, String indent, MemberDoc[] members) { for(int i=0;i<members.length;++i) { System.out.println(indent+outputType+members[i].name()); } } }
In addition to the excellent documentation capabilities provided by javadoc, JavaSoft is in the process of developing a separate JavaHelp API that will allow software developers to incorporate online help for applets, applications, JavaBeans, and other Java software. The JavaHelp API will support the development of Help applications that run in the context of other software components or that run separately. These Help applications will contain sophisticated methods for searching and navigating through help information.
At the time of this writing, the JavaHelp specification was still in development. This specification calls for a Help Viewer that displays help information using HTML 3.2. The Help Viewer also supports Java applets. The JavaHelp specification also identifies Help Navigators that provide tables of contents, indices, and full-text search capabilities. The JavaHelp files will be distributed as compressed archives in the Java Archive (JAR) file format. JavaHelp will also support the merging of help information about multiple components and the dynamic online update of help information.
For more information about JavaHelp, check out its Web page at http://java.sun.com/products/javahelp/index.html.
© Copyright, Macmillan Computer Publishing. All rights reserved.