.
.
developers.sun.com java.sun.com
.
    April 7, 2005    

In this Issue

 

Welcome to the Java Technology Fundamentals Newsletter.

This monthly newsletter provides a way for you to learn the basics of the Java programming language, discover new resources, and keep up-to-date on the latest additions to Sun Developer Network's New to Java Programming Center.

You can receive future issues of this newsletter in HTML or text: http://developer.java.sun.com/subscription/

Note: For the code to compile in this issue of Fundamentals, you need to use the JDK 5.0 software.

- Java Programming Language Basics: Learning the Preferences API
- Making Sense of the Java Classes & Tools: jvmstat 3.0
- Java Bits: How to Write Doc Comments for the Javadoc Tool
- Technical Blog from Sun Engineer
- Program Challenge
- What's New on java.net: How to Create Custom Popup Menus -- Kirill Grouchnikov's Blog
- Sun's Online Java Courses: Understanding Servlets (WJ-3050)
- Sun's Instructor-Led Courses: Java Programming Language Workshop (SL-285)
- For More Information

.

Java Programming Language Basics

Learning the Preferences API

The Java platform provides the Preferences API in the java.util.prefs packages for the storage and retrieval of system and user preferences. These preferences are then saved in an implementation-specific way, like the Microsoft Windows Registry, so you, as the developer, don't have to worry about where to store settings. While there are many different tasks you can do with preferences, essentially, working with the Preferences API consists of two primary tasks: finding the root node to work with and then reading or writing a value from it. There are two node hierarchies, one at the user level and another for system level preferences, where node values can be strings, boolean values, byte arrays, or numbers (float, long, int, or double).

The Preference class is a series of static and abstract methods. Once you get the root node to manipulate with a static method, you are given a concrete implementation from which you can call the concrete implementations of the abstract methods. Then, you can get or set different node values.

There are four different ways to get a node, two for each working with system and user nodes. If you are working in a non-static method, you can pass an instance of an object whose package you want preferences saved for to the userNodeForPackage and systemNodeForPackage methods:

Preferences userPrefs = Preferences.userNodeForPackage(this);
Preferences sysPrefs = Preferences.systemNodeForPackage(this);

If instead you are working within a static method like the main method, you need to get the root node first, then pass in the package as a string to move to the appropriate node:

Preferences userPrefs = Preferences.userRoot().node("/net/java");
Preferences sysPrefs = Preferences.systemRoot().node("/net/java");

Assuming your class was in the net.java package, the user node calls would return one node to work with while the system node calls would return a different one. You would use the system version for settings you wanted to set for all users of the application on that single client machine. Node names are limited to a maximum length of Preferences.MAX_NAME_LENGTH (80 characters).

Once you have a node, you can store preferences in it with the put method. There are also specialized versions of the method that convert different data types to a String for storage. These are listed below. The key for the preference is limited to a length of Preferences.MAX_KEY_LENGTH (80) characters, while values are limited to Preferences.MAX_VALUE_LENGTH (8192) characters.

  • put(String key, String value)
  • putBoolean(String key, boolean value)
  • putByteArray(String key, byte value[])
  • putDouble(String key, double value)
  • putFloat(String key, float value)
  • putInt(String key, int value)
  • putLong(String key, long value)

Retrieval of preferences works with the get method, where again there are specialized methods for the different supported data types. These methods retrieve the value for the key from the Preferences node. Notice that a default value is made available for when the node is not found or is unavailable. This is the one difference between the get and put calls.

  • get(String key, String default)
  • getBoolean(String key, boolean default)
  • getByteArray(String key, byte default[])
  • getDouble(String key, double default)
  • getFloat(String key, float default)
  • getInt(String key, int default)
  • getLong(String key, long default)

In addition to just setting and getting property values, the Preferences API also provides support for listening for changes to preferences by attaching a pair of listeners, either addNodeChangeListener or addPreferenceChangeListener. You can also find a list of keys under a node with keys, or remove nodes and values with calls to clear, remove, removeNode.

The following program demonstrates the Preferences API by saving some characters of Berkeley Breathed's comic strips Bloom County and Outland.

package net.java.BloomCounty;

import java.util.prefs.*;

public class Sample {
  public static void main(String args[]) {
    String stuff[][] = {
        {"Opus", "Penguin"},
        {"Bill", "the Cat"},
        {"Steve", "Dallas"},
        {"Oliver", "Wendell Jones"},
        {"Michael", "Binkley"},
        {"Ronald", "Ann"},
        {"Cutter", "John"},
        {"Milque", "toast"},
        {"Berkeley", "Breathed"}
    };

    Preferences prefs =
      Preferences.userRoot().node("/net/java/BloomCounty");

       prefs.addPreferenceChangeListener(new PreferenceChangeListener() {
      public void preferenceChange(PreferenceChangeEvent evt) {
        System.out.println("Change: " +
          evt.getKey() + "\t" + evt.getNewValue() +
          "\t" + evt.getNode());
      }
    });

    for (int i=0, n=stuff.length; i < n; i++) {
      prefs.put(stuff[i][0], stuff[i][1]);
    }

    try {
      String keys[] = prefs.keys();
      for (int i=0, n=keys.length; i < n; i++) {
        System.out.println(keys[i] + ": " + prefs.get(keys[i], ""));
      }
    } catch (BackingStoreException e) {
      System.err.println("Unable to read backing store: " + e);
    }
  }
} 
.
.

Making Sense of the Java Classes & Tools

jvmstat 3.0

The jvmstat technology adds lightweight performance and configuration instrumentation to the HotSpot JVM and provides a set of monitoring APIs and tools for monitoring the performance of the HotSpot JVM in production environments. The instrumentation is designed such that it is 'always on', yet has negligible performance impact. The monitoring interfaces added to the HotSpot JVM are proprietary and may or may not be supported in future versions of the HotSpot JVM.

The jvmstat tools included with J2SE 5.0, and the visualgc tool included with the jvmstat 3.0 distribution, are capable of monitoring Java applications running on HotSpot 1.4.1 and later JVMs. Only this distribution and a J2SE 5.0 JDK are needed to monitor any version of an instrumented HotSpot JVM. Therefore, jvmstat versions 1.1 and 2.0 will be discontinued.

Some features of the jvmstat tools require the existence of specific counter instances in the HotSpot JVM. Older HotSpot JVMs may not contain these specific counters. When encountering an older JVM, some features of the jvmstat tools may be disabled or warning messages may be issued.

Read more

.
.

Java Bits

How to Write Doc Comments for the Javadoc Tool

Sun Microsytems documentation comments define the official Java Platform API Specification. To this end, our target audience is those who write Java compatibility tests, or conform or re-implement the Java platform, in addition to developers. We spend time and effort focused on specifying boundary conditions, argument ranges and corner cases rather than defining common programming terms, writing conceptual overviews, and including examples for developers.

These two targets are described in the following sections. A staff with generous resources can afford to blend both into the same documentation (properly "chunked"); however, our priorities dictate that we give prime focus to writing API specifications in doc comments. This is why developers often need to turn to other documents, such as the J2SE Documentation, Java Tutorial or the Java Class Libraries (in hardback only) for programming guides.

Writing API Specifications

Ideally, the Java API Specification comprises all assertions required to do a clean-room implementation of the Java Platform for "write once, run anywhere" -- such that any Java applet or application will run the same on any implementation. This may include assertions in the doc comments plus those in any architectural and functional specifications (usually written in FrameMaker) or in any other document. This definition is a lofty goal and there is some practical limitation to how fully we can specify the API. The following are guiding principles we try to follow:

  • The Java Platform API Specification is defined by the documentation comments in the source code and any documents marked as specifications reachable from those comments.

    Notice that the specification does not need to be entirely contained in doc comments. In particular, specifications that are lengthy are sometimes best formatted in a separate file and linked to from a doc comment.

  • The Java Platform API Specification is a contract between callers and implementations.

    The Specification describes all aspects of the behavior of each method on which a caller can rely. It does not describe implementation details, such as whether the method is native or synchronized. The specification should describe (textually) the thread-safety guarantees provided by a given object. In the absence of explicit indication to the contrary, all objects are assumed to be "thread-safe" (that is, it is permissible for multiple threads to access them concurrently). It is recognized that current specifications don't always live up to this ideal.

  • Unless otherwise noted, the Java API Specification assertions need to be implementation-independent. Exceptions must be set apart and prominently marked as such.

    We have guidelines for how to prominently document implementation differences.

  • The Java API Specification should contain assertions sufficient to enable Software Quality Assurance (SQA) to write complete Java Compatibility Kit (JCK) tests.

    This means that the doc comments must satisfy the needs of the conformance testing by SQA. The comments should not document bugs or how an implementation that is currently out of spec happens to work.

Read more

.
.

Technical Blog from Sun Engineer

Threadaches -- Chet Haase's Blog

I find myself trying to multithread my life constantly. I've got so many things to do; surely there's a way I can multiplex the chores to get all of them done faster, right?

For example, I'll be brushing my teeth and realize I also need to comb my hair. I'm only using one hand to hold the toothbrush, so I reach for the comb with the other hand. Then I'll start combing my hair, at which point the other hand with the toothbrush stops moving, or even worse, keeps moving, but in such as way that toothpaste starts running all over the place.

Now I've gone from two actions that would have been simple to perform serially to one interleaved complex action that's resulted in a toothpaste-and-spittle mess and an unruly mop on my head.

The problem here is that, despite the speed of our processors and the simplicity of our actions, some things in life simply cannot be multithreaded.

This is not to say that multithreading itself is unachievable or not worthwhile for some operations. As an example, consider breathing or blinking; if I had to stop any other action to make my eyes blink or to breathe, I'd never get anything done. Consider multiplexing actions while driving; if we couldn't do many things at once in this environment, we'd all be dead.

Of course, many people assume that this multiplexing-while-driving capability is universal and extends to complex conversations on phones while driving at 80 on the highway; I believe these folks will eventually be evolved out of our society, although they may take a few of us with them along the way.

So, there are clearly some operations which are better done on separate threads; the trick is figuring out which ones are which if you don't want to be wiping up toothpaste off your clothes all the time. Or, in the case of your applications, if you don't want to be debugging thread deadlocks or performance problems due to thread abuse.

That reminds me; I was going to write about software in this article, not toothpaste and driving. I knew there was a reason I was posting this to a developer site...

Now, to get Technical

I've spent the better part of the last year thinking about multithreading problems, and I could probably spend the rest of my career doing the same, although it probably wouldn't be a long career since my head would pop off before too long. There are so many issues in this ugly space that to write about all of them would take too long. So for the purposes of a focused blog, although it's probably too late for that goal, I'll focus on one area of trouble for Java client developers: multithreaded graphics.

When developers first discover the joys of multithreaded programming, it's like opening a new present on Christmas; the power of Java thread creation is that it is so easy to create and use new threads, that you can start taking advantage of multithreaded processing in a much easier fashion than you ever could before in previous programming languages. And the knowledge that your application can perform multiple tasks simultaneously, especially on systems with multiple processors or hyper-threaded cores, is huge. You no longer need to block on IO, waiting for the system to open a file. You no longer need to hang in your display code waiting for an image to be downloaded over the network. You no longer need to hang the GUI while calculating a complex set of equations. In all of these cases, it is trivial to spawn a new thread to perform the bottlenecking operation, and use the result of that operation later as appropriate.

In fact, Java builds in much of this functionality for you, so you don't even need to do the work of multithreading some of your operations which may be blocking. For example, the old Toolkit Image loading methods automatically load images on a separate thread. The following code:

Image img = Toolkit.getImage("duke.gif");

would return without having loaded the image. Instead, the method puts the request to load that image on a separate image-loading thread. Later, when you need to use img, you may need to make sure it's loaded first (see my blog on Image APIs for more information on this asynchronous behavior).

Read the rest of this blog.

.
.

Program Challenge

Create a program that will dump out all available user and system preferences. This can either be displayed in a JTree, or dumped out to the system console.

See a possible solution.

.
.

What's New on java.net

How to Create Custom Popup Menus -- Kirill Grouchnikov's Blog

The popup menus in Swing application are rather standard. Put a few JMenuItems, most likely with icons, spice them with an assorted selection of JSeparators, and your plain boring popup is ready for the outside world to see.

The immediate solution to creating custom menu items is, of course, using some lively look'n'feel scheme. However, you don't have to go that far to bring your popup menu alive. There are two things you can do - use HTML text and create custom background images. The following example illustrates both techniques.

menu example

  • The text of the header entry is painted twice (black shadow makes the white text stand out).
  • The text of regular entries is HTML and anti-aliased.
  • The gradient on the header entry and the overlaid squares will be discussed below.

The first and the simpler thing to do - make menu items with HTML text. Simply provide a valid HTML construct to the constructor, or setText method of JMenuItem:

JMenuItem myItem =
           new JMenuItem("<html><b>Increase</b> font size</html>");

The more interesting part is providing custom rendering for your menu items. The obvious approach is to extend the JMenuItem class and override the paintComponent(Graphics g) method:

@Override
protected final void paintComponent(Graphics g) {
   Graphics2D graphics = (Graphics2D) g;
   graphics.setColor(Color.red);
   graphics.fillRect(0,0,this.getWidth(), this.getHeight());
   super.paintComponent(graphics);
}

Of course, the fillRect method can be replaced by drawImage for painting your background image before the super implementation is called. However, this approach fails when the corresponding menu item is selected - the background is filled with grey color, or the color specified in UIDefaults / L&F specific setting. In this case, you may completely override the painting function, using HTMLEditorKit, HTMLDocument and HTML.Attribute classes to correctly display both the background image and the HTML text. Of course, special attention has to be paid to icons and accelerator strings. The code given below goes halfway in this direction - it draws only the background image and simple non-HTML text.

Read the rest of this blog.

.
.

Sun's Online Java Courses

Understanding Servlets (WJ-3050)

The Understanding Servlets course provides students with an introduction to Java technology servlets, a key component of server-side Java technology development, allowing developers to extend and customize the functionality of any Java-enabled server. This course introduces servlet technology, and presents ways to use servlets in extending server-side web functionality.

.
.

Sun's Instructor-Led Java Courses

Java Programming Language Workshop (SL-285)

The Java Programming Language Workshop course provides students with practical experience in designing a vertical solution for a distributed, multitier application. Students use graphical user interface (GUI) design principles and network-communications capabilities to code a functional Java application that interacts with a networked database server. The significant amount of lab time illustrates the workshop nature of this course.

.
.

For More Information

.
.

Downloading the Java 2 Platform

For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the J2SE development kit.

.
.
Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.
.
.

Find archived issues of the following Java technology developer newsletters or manage your current newsletter subscriptions: https://softwarereg.sun.com/registration/developer/en_US/subscriptions

Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:

- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with core Java technologies.
- Mobility Developer Newsletter. Learn about the latest releases, tools, and resources for developers working on wireless and Java Card technologies and applications.
- Core Java Technologies Tech Tips (formerly JDC Tech Tips) Get expert tips, sample code solutions, and techniques for developing in the Java 2 Platform, Standard Edition (J2SE)


You can subscribe to these and other JDC publications on the JDC Newsletters and Publications page

PRIVACY STATEMENT:
Sun respects your online time and privacy. You have received this based on your e-mail preferences. If you would prefer not to receive this information, please follow the steps at the bottom of this message to unsubscribe.


IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html


Copyright 2005 Sun Microsystems, Inc. All rights reserved. Sun Microsystems, Inc. 10 Network Circle, MPK10-209 Menlo Park, CA 94025 US

FEEDBACK
Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: dana.nourie@sun.com


SUBSCRIBE/UNSUBSCRIBE
- To subscribe, go to the subscriptions page, choose the newsletters you want to subscribe to and click Update
- To unsubscribe, go to the subscriptions page, uncheck the appropriate check box, and click Update


Trademark Information: http://www.sun.com/suntrademarks/
Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.


Sun Microsystems, Inc.
image
image