Prepare yourself for what's new and different in the forthcoming JDK 1.2 release

Core Java continues to grow and grow, but you'll be ready for the new release -- with JavaWorld's detailed analysis of all the additions

1 2 3 4 Page 3
Page 3 of 4

JDK 1.2 adds the concept of reference objects to the set of tools developers can use to better manage memory. A reference object, or weak reference, is a reference to an object in memory. It has one catch though. The automatic garbage collector doesn't count this reference as a reference to the object. Thus, that object can be garbage-collected if no non-weak objects refer to it. The WeakHashMap collections class, introduced in beta 4, represents a hashtable where the keys are weak references. When the system needs more memory, the map size may shrink at will, with no notification to you. With phantom references, one type of weak reference, you can even perform post-finalization cleanup, after an object has been garbage collected. All this provides you with more direct control over storage reclamation strategies.

CORBA

New in JDK 1.2 is an object request broker (ORB) to support interoperability between the Common Object Request Broker Architecture (CORBA) and a JRE, through Java IDL (Interface Definition Language). CORBA is similar to RMI for distributed object applications. But while RMI requires Java technology at both ends and a wire in the middle, CORBA has no such restriction and works between disparate computing languages and platforms. The CORBA support in JDK 1.2 makes future developments with Enterprise JavaBeans much easier, as CORBA is the most likely candidate for communication between Java environments and existing application services.

To use CORBA within a Java program, you create an IDL file that defines the interfaces to use for communication, similar to RMI. Then, after running this file through the idltojava command (available separately from the JDK), you get a set of classes that provide the stub and skeleton for communication. After defining your specific implementation, you're off and running. It really is very easy to use. And if you include CORBA services within an applet, you can take advantage of the ORB that comes with Netscape Communicator. One added command available to run your CORBA applications is the tnameserv program, which acts as a naming service, looking up service locations upon request.

Read more on Java 1.2's distributed object technologies in Bryan Morgan's "Java 1.2 extends Java's distributed object capabilities."

Thread local variables

JDK 1.2 adds support for static variables with different values based on which thread a class (or set of classes) is running in. These thread local variables work great for storing session identifiers and sharing them within a ThreadGroup. These types of variables are supported by the two classes ThreadLocal and InheritableThreadLocal, and are found in the java.lang package.

Version identification

With the package versioning support added to JDK 1.2, sometimes you can find out the name and version of packages. I say sometimes because a package isn't known to the system until a class is loaded from that package. So this doesn't look at all the packages in the CLASSPATH variable, just the loaded packages. For instance, the following three lines list all the packages known to a program:

Package p[] = Package.getPackages();
for (int i=0, n=p.length;i < n;i++)
  System.out.println (p[i]);

If you added a line like JButton jb = new JButton("Ack"); as the first line, the number of packages returned would expand significantly.

Versioning properties are set through the manifest file of the jar containing the classes. Currently, the Java Core packages do not provide version numbers, only names.

Floating point extension proposal

Two new keywords were added to JDK 1.2 with the beta 4 release: strictfp and widefp. These keywords let you specify the IEEE 754-standard strictness that a method or class uses when calculating intermediate results. Currently, these options are not used by the JVM, but you can place them in your code. The strictfp keyword acts like the current float behavior, while widefp is an extended-precision format, which may be faster. Here's how to flag a method to use the wide format:

widefp void doCalc (float x, float y) {...}

These keywords will not be added officially until the Proposal for Extension of Java Floating Point in JDK 1.2 is approved through Sun's Java standardization process. If rejected, the keywords will disappear, going the way of the private protected access modifier, which briefly appeared in a Java 1.0 release.

Java Foundation Classes

The Java Foundation Classes (JFC) encompass a large set of changes in JDK 1.2. JFC also includes the existing JDK 1.1.x Abstract Windowing Toolkit (AWT) capabilities. The 1.2 features of JFC are Swing, Drag and Drop, Accessibility, Java 2D, and the Input Method framework.

Swing

Swing is very likely the single JDK 1.2 addition that has received the most attention, probably because it's usable in JDK 1.1, too. Swing is a new set of Java components, providing a richer set of widgets than the original AWT controls. Instead of a small set of components that follow the lowest common denominator approach (if something isn't available on every Java runtime platform, it isn't available on any of them), the Swing component set is huge. By itself, Swing is larger than the original JDK 1.0. It offers everything from grid controls and labelled sliders to HTML rendering components, and more. The components are so flexible that you can change practically everything without changing anything. For instance, you can change the look and feel of your application without changing your event-handling code. You can even remove all event-handling code and deal with everything through the Model/View/Controller (MVC) architecture of the flexible Swing components.

In my experience, using the Swing components since last August has been a continual struggle. They tend to work best when doing everything by hand. While they were designed as JavaBean components, they were not initially created to be designable within drag and drop GUI environments like JBuilder or Visual Café. As the IDE vendors have improved their tools to be Swing-aware and Sun has improved the components to be more designable, we're now at a stage where Swing components are basically usable within second-generation IDE tools. Within IDE tools, however, you can only use the Swing components as replacement components for the AWT controls. You cannot use them, yet, in their more advanced MVC mode.

With all this flexibility of Swing comes complexity and performance bottlenecks. Performance has improved somewhat since the early days of Swing, but if it's to be a viable option for client-side applications, performance speed has to improve. Otherwise, we'll be forced to look to Microsoft's WFC (and limit our programs to run on only 90 percent of the desktop systems).

By the time JDK 1.2 is released, you'll find the Swing classes in the javax.swing package. This will be the third home for Swing in JDK 1.2; previously it lived in java.awt.swing and in com.sun.java.swing.

Undo/redo framework

The Swing classes (package javax.swing.undo) include a framework for supporting undoable and redoable activities. Whenever an editable activity occurs, you add it to the list of undoable activities an UndoManager is managing. Then, when a user asks to undo the activity, it can be undone. After being undone, it can also be redone, unless something isn't redoable, in which case a CannotRedoException is thrown.

Tomer Meshorer discusses Swing's undo/redo facility in "Add an undo/redo function to your Java apps with Swing" (JavaWorld, June 1998).

Drag and drop

The drag and drop capabilities of JDK 1.2 beta 4 are somewhat crippled. Not only has drag and drop changed significantly between beta 3 and beta 4, but Sun had to disable it completely under Solaris, permitting it to work only in Java programs on Win32 machines. Hopefully, by the time JDK 1.2 hits the street, all the kinks will be worked out, including that annoying three- to five-second delay before dragging is actually initiated.

Assuming everything is working, drag and drop is meant to permit dragging and dropping between Java applications and native platform applications. (See Resources for an example of using the beta 4 Drag and Drop API.)

Accessibility

The Accessibility API lets developers enable their applications for assistive technologies. These technologies include screen readers, voice recognition software, and many other options for users unable to physically see output or respond with input. Assistive technologies may be used to augment users with disabilities or support users whose jobs require them to be away from keyboard and monitor. The Swing component set automates many of the steps necessary to make components accessible. So, if you use them, there is little extra you need to do. However, you should still be aware of the capabilities and set appropriate messages when necessary (assuming an application could run in such an environment). Here's an example of how to set such a descriptive message. How it's used depends upon the assistive device installed.

aButton.getAccessibleContext().setAccessibleDescription(
  "Selecting this button turns off the coffee pot.");

Java 2D

The Java 2D API is an important part of the Java Foundation Classes. So important, in fact, that JavaWorld has columnist Bill Day writing about it in every issue (the JavaWorld Topical Index provides links to all of Bill's Java Media columns). The Java 2D API adds capabilities like adding an alpha (or transparency) channel to colors, drawing with antialiasing to get rid of the jaggies when drawing diagonal lines, filling shapes with arbitrary styles, and defining stroking patterns when drawing lines. I leave the details of the Java 2D API for Bill Day to explain.

Many people I spoke with placed the Java 2D capabilities among their top three enhancements in JDK 1.2, along with Swing and Security. "Component developers will be most interested in the 2D API provided in JDK 1.2, which eliminates the complicated and slow capabilities introduced in JDK 1.0," says Frank Pittelli, PhD, of Pittelli & Associates, co-founder of ChartWorks Inc. (formerly NetFactory), a Java-based charting solution provider. "As the designer of charting components, I only wish that the 2D API was around three years ago, when it all began."

Input Method framework

The Input Method framework supports input of multibyte characters (specifically Japanese, Chinese, and Korean) within text components. Currently, the TextArea and TextField components of AWT cannot support this framework because they use the underlying operating system to create the controls through platform-specific peers. If you need to use this framework, you must use lightweight components, like the Swing controls.

Printing

Printing in JDK 1.2 now supports an optional print dialog. JDK 1.1 printing capabilities required a print dialog, so you couldn't automate print jobs for after hours. Located in the java.awt.print package, the key class for printing is PrinterJob and the key interface is Printable. The print() method of the Printable interface is repeatedly called as long as the method returns Printable.PAGE_EXISTS. The calls cease when the method returns Printable.NO_SUCH_PAGE.

Font support

You can forget about the limited font support in JDK 1.0 and JDK 1.1. With JDK 1.2 you now have access to all the fonts available on your system (or at least those available by the directory specified in the JAVA_FONTS environment variable). Instead of asking a Toolkit for the font list, you ask the GraphicsEnvironment. You then set the font according to the user's choice.

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font fonts[] = ge.getAllFonts();
Font aFont = fonts[1].deriveFont (Font.PLAIN, 12);
// or
String fontList[] = ge.getAvailableFontFamilyNames();
Font bFont = new Font (fontList[1], Font.PLAIN, 12);

Buffered image

With the addition of the java.awt.image.BufferedImage class, double buffering has gotten much easier. No longer do you have to worry about when createImage() will return a valid Image object. And, you can specify the bit-depth when you create a buffered image, or ask for the optimum image format for the current graphics-display configuration.

BufferedImage biOne =
  new BufferedImage (640, 480, BufferedImage.TYPE_INT_RGB);
// or
Graphics2D gwd = (Graphics2D)g; // g is arg to paint()
GraphicsConfiguration gc =
  g2d.getDeviceConfiguration();
BufferedImage biTwo =
  gc.createCompatibleImage (640, 480);

Unfortunate incompatibilities

Sun's Java Development Kit Compatibility with Previous Releases page (see Resources) contains a complete set of version incompatibilities. Unfortunately, there are some. Most of the incompatibilities listed are the result of bug fixes. However, there are some that aren't related to bug fixes. They're caused by the addition of classes, where a new class is given the same name as an old one, but exists in a different package. You may happen to import both into your program, due to importing with asterisks (that is, import java.util.*), in which case you'll have to explicitly import one in the source before it will successfully recompile (or explicitly reference the class name). The most frequently used duplicately named classes are as follows:

  • java.lang.reflect.Array/java.sql.Array
  • java.sql.Date/java.util.Date
  • java.awt.List/java.util.List
  • javax.swing.filechooser.FileFilter/java.io.FileFilter
  • java.security.Permission/java.security.acl.Permission

JPEG encoding

The com.sun.image.codec.jpeg package comes with Sun's JRE and allows you to read and write JPEG files. While reading has long been available with getImage(), writing previously required a third-party package, assuming you wanted to maintain the JPEG encoding when you saved. When first introduced into an early beta version of JDK 1.2, these classes were in a different package, under the java.* hierarchy. After causing quite a bit of controversy, they were moved. They're not considered part of the Core API. However, they are available with the runtime environments provided by Sun.

FileInputStream fis = new FileInputStream ("imagefile.jpg");
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder (fis);
BufferedImage bi = decoder.deco deAsBufferedImage();
1 2 3 4 Page 3
Page 3 of 4