New to Java Developer
By Xueming Shen

It's well known that creating a Jar file can be a "little" slow. How slow? On my aged SunBlad1000, it takes about 1 minute and 40 seconds to jar the whole rt.jar in cf0M mode (no compress, no manifest) -- and it costs you a little more if done in compress mode.

But then we figured we were talking about creating jars for ten of thousands of classes with a total size of over 50M. Given the number of files and the total size, it seemed a reasonable amount of time. So, until now, we assumed it really needed that time — until someone accidentally noticed that "the CPU went to 100% busy for quite some time, perhaps a minute or more on my laptop, before starting to hit the disk to create the Jar archive."

That sounds strange, as the main job the Jar is supposed to do is to copy and compress the files (into the Jar). Thus it should hit the disk from the very beginning to the end.

So I peeked into the Jar source code (after many years), and it turned out we had a very embarassing bug in the jar code: We were doing a O(n) look-up on a Hashtable (via the contains() method) for each and every file we were jarring, where it really should be a O(1) look-up operation with a HashSet. Given the number of files the command is working on, this simple mistake caused us to spend the majority of the time (that 1 min 40+ seconds) in collecting the list of files that need to jar, instead of the real "jarring" work. Sigh:-(

With that fixed (in JDK 7 build44 and later), the Jar is now much faster.

Following are the quick time-measure numbers of 10 runs of jarring/zipping the rt.jar/zip, in Store Only mode and Zip Compression mode.

  • b43: the JDK 7/build43, which does not have the fix.
  • b47: the JDK 7/build47, which does have the fix.
  • zip: the default zip installed on my Solaris, which is zip2.3/1999

jar cf0M / zip -r0q (store, no zip compression)
Build 43 Build 471 Zip
1:43.7 20.6 10.2
1:40.3 20.2 9.2
1:40.1 21.0 9.0
1:40.5 19.6 10.4
1:40.9 19.6 8.7
1:40.2 19.6 9.1
1:40.0 18.6 10.0
1:39.1 20.0 8.6
1:41.3 18.5 9.0
1:42.1 19.6 9.6
jar cfM/zip -rq (with zip compression)
Build 43 Build 471
Zip
1:47.0 25.3 15.7
1:45.9 23.4 14.2
1:44.7 23.3 14.9
1:45.4 23.7 14.3
1:45.6 23.3 14.3
1:44.9 23.6 14.0
1:45.9 23.2 14.6
1:44.0 23.0 14.2
1:44.9 23.3 14.8
1:45.8 23.5 14.2
1 The fix is in JDK 7 only, for now.

This page contains details of the fix.

We are making much progress on the Jar tool, and it is performing much better, though it is still slower compared to the Zip command. So we will continue our efforts going forward. I have to admit I do have some code that make Jar processing time much closer to Zip, but it will take time to make it into the product. Stay tuned!

Xueming Shen is an engineer at Sun Microsystems, working in the Java core technologies group.

By Xueming Shen

The UTF-8 charset implementation, which is available in all JDK/JRE releases from Sun, has been updated recently to reject non-shortest-form UTF-8 byte sequences. This is because the old implementation might be leveraged in security attacks. Since then I have been asked many times about what this "non-shortest-form" issue is and what the possible impact might be, so here are some answers.

The first question usually goes: "What is the non-shortest-form issue"?

The detailed and official answer is at Unicode Corrigendum #1: UTF-8 Shortest Form. Simply put, the problem is that Unicode characters can be represented in more than one way (form) in the "UTF-8 encoding" than many people think or believe. When asked what UTF-8 encoding looks like, the simplest explanation would be the following bit pattern:

# Bits Bit pattern
1 7 0xxxxxxx      
2 11 110xxxxx 10xxxxxx    
3 16 1110xxxx 10xxxxxx 10xxxxxx  
4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

The pattern is close, but it's actually wrong, based on the latest definition of UTF-8. The preceding pattern has a loophole in that you can actually have more than one form represent a Unicode character.

For ASCII characters from u+0000 to u+007f, for example, the UTF-8 encoding form maintains transparency for all of them, so they keep their ASCII code values of 0x00..0x7f (in one-byte form) in UTF-8. Based on the preceding pattern, however, these characters can also be represented in 2-bytes form as [c0, 80]..[c1, bf], the "non-shortest-form".

The following code shows all of the non-shortest-2-bytes-form for these ASCII characters, if you run code against the "old" version of the JDK and JRE (Java Runtime Environment).


    byte[] bb = new byte[2];
    for (int b1 = 0xc0; b1 < 0xc2; b1++) {
        for (int b2 = 0x80; b2 < 0xc0; b2++) {
            bb[0] = (byte)b1;
            bb[1] = (byte)b2; 
            String cstr = new String(bb, "UTF8");
            char c = cstr.toCharArray()[0];
            System.out.printf("[%02x, %02x] -> U+%04x [%s]%n",
                              b1, b2, c & 0xffff, (c>=0x20)?cstr:"ctrl");
        }
    }

The output would be as follows:


...
[c0, a0] -> U+0020 [ ]
[c0, a1] -> U+0021 [!]
...
[c0, b6] -> U+0036 [6]
[c0, b7] -> U+0037 [7]
[c0, b8] -> U+0038 [8]
[c0, b9] -> U+0039 [9]
...
[c1, 80] -> U+0040 [@]
[c1, 81] -> U+0041 [A]
[c1, 82] -> U+0042 [B]
[c1, 83] -> U+0043 [C]
[c1, 84] -> U+0044 [D]
...

So, for a string like "ABC", you would have two forms of UTF-8 sequences:


"0x41 0x42 0x43" and "0xc1 0x81 0xc1 0x82 0xc1 0x83"

The Unicode Corrigendum #1: UTF-8 Shortest Form specifies explicitly that "The definition of each UTF specifies the illegal code unit sequences in that UTF. For example, the definition of UTF-8 (D36) specifies that code unit sequences such as [C0, AF] are illegal."

Our old implementation accepts those non-shortest-form (while it never generates them when encoding). The new UTF_8 charset now rejects the non-shortest-form byte sequences for all BMP characters. Only the "legal byte sequences" listed below are accepted.


    /*  Legal UTF-8 Byte Sequences
     *
     * #    Code Points      Bits   Bit/Byte pattern
     * 1                     7      0xxxxxxx
     *      U+0000..U+007F          00..7F
     * 2                     11     110xxxxx    10xxxxxx
     *      U+0080..U+07FF          C2..DF      80..BF
     * 3                     16     1110xxxx    10xxxxxx    10xxxxxx
     *      U+0800..U+0FFF          E0          A0..BF      80..BF
     *      U+1000..U+FFFF          E1..EF      80..BF      80..BF
     * 4                     21     11110xxx    10xxxxxx    10xxxxxx    10xxxxxx
     *     U+10000..U+3FFFF         F0          90..BF      80..BF      80..BF
     *     U+40000..U+FFFFF         F1..F3      80..BF      80..BF      80..BF
     *    U+100000..U10FFFF         F4          80..8F      80..BF      80..BF
     */

The next question usually is: "What would be the issue/problem if we keep using the old version of JDK/JRE?"

First, I'm not a lawyer — oops, I meant I'm not a security expert:-) — so my word does not count. We consulted with our security experts instead. Their conclusion is that while "it is not a security vulnerability in Java SE per se, it may be leveraged to attack systems running software that relies on the UTF-8 charset to reject these non-shortest form of UTF-8 sequences".

A simple scenario that might give you an idea about what the above "may be leveraged to attack..." really means:

  1. A Java application would like to filter the incoming UTF-8 input stream to reject certain key words, for example "ABC".
  2. Instead of decoding the input UTF-8 byte sequences into Java char representation and then filter out the keyword string "ABC" at Java "char" level, for example:
    
           String utfStr = new String(bytes, "UTF-8");
           if ("ABC".equals(strUTF)) { ... }
    
    The application might choose to filter the raw UTF-8 byte sequences "0x41 0x42 0x43" (only) directly against the UTF-8 byte input stream and then rely on (assume) the Java UTF-8 charset to reject any other non-shortest-form of the target keyword, if there is any.
  3. The consequence is the non-shortest form input "0xc1 0x81 0xc1 0x82 0xc1 0x83" will penetrate the filter and trigger a possible security vulnerability, if the underlying JDK/JRE runtime is an OLD version.

So the recommendation is: Update to the latest JDK/JRE releases to avoid the potential risk.

Wait, there is another big bonus for updating: performance.

The UTF-8 charset implementation has not been updated or touched for years. UTF-8 encoding is very widely used as the default encoding for XML, and more and more websites use UTF-8 as their page encoding. Given that fact, we have taken the defensive position of "don't change it if it works" during the past years.

So Martin and I decided to take this opportunity to give it a speed boost as well. The following data is from one of my benchmark's run data, which compares the decoding/encoding operations of new implementation and old implementation under -server vm. (This is not an official benchmark: it is provided only to give a rough idea of the performance boost.)

The new implementation is much faster, especially when decoding or encoding single bytes (those ASCIIs). The new decoding and encoding are faster under -client vm as well, but the gap is not as big as in -server vm. I wanted to show you the best:-)


    Method Millis Millis(OLD)
    Decoding 1b UTF-8         :  1786  12689
    Decoding 2b UTF-8         : 21061  30769
    Decoding 3b UTF-8         : 23412  44256
    Decoding 4b UTF-8         : 30732  35909
    Decoding 1b (direct)UTF-8 : 16015  22352
    Decoding 2b (direct)UTF-8 : 63813  82686
    Decoding 3b (direct)UTF-8 : 89999 111579
    Decoding 4b (direct)UTF-8 : 73126  60366
    Encoding 1b UTF-8         :  2528  12713
    Encoding 2b UTF-8         : 14372  33246
    Encoding 3b UTF-8         : 25734  26000
    Encoding 4b UTF-8         : 23293  31629
    Encoding 1b (direct)UTF-8 : 18776  19883
    Encoding 2b (direct)UTF-8 : 50309  59327
    Encoding 3b (direct)UTF-8 : 77006  74286
    Encoding 4b (direct)UTF-8 : 61626  66517

The new UTF-8 charset implementation has been integrated in JDK7, Open JDK 6, JDK 6 update 11 and later, JDK5.0u17, and 1.4.2_19.

If you are interested in what the change looks like, you can take a peek at the webrev of the new UTF_8.java for OpenJDK7.

Xueming Shen is an engineer at Sun Microsystems, working in the Java core technologies group.

By Michael McMahon

Complex Java programs, such as application servers, sometimes create their own class loaders using the URLClassLoader type. With URLClassLoader, applications can load classes and resources from a search path of URLs. The following URL types are supported:

  • file: (loads from file-system directories)
  • jar: (loads from JAR files)
  • http: (loads from http servers)

A frequent problem has been how to support updated implementations of the classes and resources loaded from a particular codebase, and in particular from JAR files. In principle, once the application clears all references to a loader object, the garbage collector and finalization mechanisms will eventually ensure that all resources (such as the JarFile objects) are released and closed.

The application can then replace the JAR file, and create a new URLClassLoader instance to load from the same location, but this time using the new implementation of the classes/resources.

However, since it can't be predicted exactly when finalization and garbage collection will occur, this causes problems for applications which need to be able to do this in a predictable and timely fashion. It is a particular problem on Windows, because open files cannot be deleted or replaced.

To alleviate this problem, URLClassLoader has acquired a new method called close(). It has been implemented since Build 48 of JDK7.

The close() method effectively invalidates the loader, so that no new classes can be loaded from it. It also closes any JAR files that were opened by the loader. This allows the application to delete or replace these files and, if necessary, create new loaders using new implementations.

The new method follows the familiar "Closeable" pattern, and URLClassLoader now implements the Closeable interface, which defines URLClassLoader.close(). The following sample code shows how one might use the method.

       //
       // create a class loader loading from "foo.jar"
       //
       URL url = new URL("file:foo.jar");
       URLClassLoader loader = new URLClassLoader (new URL[] {url});
       Class cl = Class.forName ("Foo", true, loader);
       Runnable foo = (Runnable) cl.newInstance();
       foo.run();
       loader.close ();

       // foo.jar gets updated somehow

       loader = new URLClassLoader (new URL[] {url});
       cl = Class.forName ("Foo", true, loader);
       foo = (Runnable) cl.newInstance();
       // run the new implementation of Foo
       foo.run();

Michael McMahon is an engineer at Sun Microsystems. He works in the Java Security, Networking, and Libraries group.

Introduction to GUI Building

This tutorial teaches you how to create a simple graphical user interface and add simple back-end functionality. 

Working with numbers can be a large part of application programming. Follow this tutorial to get familiar with the Numbers classes, and how to work with numbers in your applications.

When working with numbers, most of the time you use the primitive types in your code. For example:
int i = 500;
float gpa = 3.65f;
byte mask = 0xff;
There are, however, reasons to use objects in place of primitives, and the Java platform provides wrapper classes for each of the primitive data types. These classes "wrap" the primitive in an object. Often, the wrapping is done by the compiler—if you use a primitive where an object is expected, the compiler boxes the primitive in its wrapper class for you. Similarly, if you use a number object when a primitive is expected, the compiler unboxes the object for you.

Here is an example of boxing and unboxing:

Integer x, y;
x = 12;
y = 15;
System.out.println(x+y);
When x and y are assigned integer values, the compiler boxes the integers because x and y are integer objects. In the println() statement, x and y are unboxed so that they can be added as integers.

All of the numeric wrapper classes are subclasses of the abstract class Number:

The class hierarchy of Number.

Note: There are four other subclasses of Number that are not discussed here. BigDecimal and BigInteger are used for high-precision calculations. AtomicInteger and AtomicLong are used for multi-threaded applications.
There are three reasons that you might use a Number object rather than a primitive:
  1. As an argument of a method that expects an object (often used when manipulating collections of numbers).

  2. To use constants defined by the class, such as MIN_VALUE and MAX_VALUE, that provide the upper and lower bounds of the data type.

  3. To use class methods for converting values to and from other primitive types, for converting to and from strings, and for converting between number systems (decimal, octal, hexadecimal, binary).

The following table lists the instance methods that all the subclasses of the Number class implement.

Methods Implemented by all Subclasses of Number
Method Description
byte byteValue()
short shortValue()
int intValue()
long longValue()
float floatValue()
double doubleValue()
Converts the value of this Number object to the primitive data type returned.
int compareTo(Byte anotherByte)
int compareTo(Double anotherDouble)
int compareTo(Float anotherFloat)
int compareTo(Integer anotherInteger)
int compareTo(Long anotherLong)
int compareTo(Short anotherShort)
Compares this Number object to the argument.
boolean equals(Object obj) Determines whether this number object is equal to the argument.
The methods return true if the argument is not null and is an object of the same type and with the same numeric value.
There are some extra requirements for Double and Float objects that are described in the Java API documentation.

Each Number class contains other methods that are useful for converting numbers to and from strings and for converting between number systems. The following table lists these methods in the Integer class. Methods for the other Number subclasses are similar:

Conversion Methods, Integer Class
Method Description
static Integer decode(String s) Decodes a string into an integer. Can accept string representations of decimal, octal, or hexadecimal numbers as input.
static int parseInt(String s) Returns an integer (decimal only).
static int parseInt(String s, int radix) Returns an integer, given a string representation of decimal, binary, octal, or hexadecimal (radix equals 10, 2, 8, or 16 respectively) numbers as input.
String toString() Returns a String object representing the value of this Integer.
static String toString(int i) Returns a String object representing the specified integer.
static Integer valueOf(int i) Returns an Integer object holding the value of the specified primitive.
static Integer valueOf(String s) Returns an Integer object holding the value of the specified string representation.
static Integer valueOf(String s, int radix) Returns an Integer object holding the integer value of the specified string representation, parsed with the value of radix. For example, if s = "333" and radix = 8, the method returns the base-ten integer equivalent of the octal number 333.

by Jennie Hall
Updated Jan. 23, 2009

In this tip, you'll learn how to use Swing's progress indicator support to monitor and report on the progress of long-running operations. It is a good practice to keep users informed as they interact with an application; one way to do this is with a progress bar. A progress bar is an animated image that indicates the degree of completion of a given task. The animation typically looks like a rectangular bar that fills in as the task becomes more complete.

Swing's Progress Monitoring API consists of three classes that enable the use of progress bars. JProgressBar subclasses JComponent and is a graphical component that illustrates the progress of an operation. It can be embedded within other graphical components. ProgressMonitor subclasses Object and is not itself a graphical component. It monitors a task and pops a dialog box with a progress bar in it. ProgressMonitorInputStream is a stream filter with an associated progress monitor. As the stream is read, the progress monitor automatically receives updates on the number of bytes read and displays the percentage of work completed in its dialog box.

The Java Tutorial provides some good rules of thumb that help to determine the appropriate class to use in a given situation. For example, use JProgressBar when you need more than one progress bar or you would like more control over the configuration of the progress bar. If you need a convenient way to cancel the monitored task or to allow the user to dismiss the dialog box while continuing to run the task in the background, ProgressMonitor provides for this. ProgressMonitor also features a modifiable status note in its dialog box that can be updated periodically by your application. The sample application for this tip uses ProgressMonitor.

The Sample Application

The sample application copies files located in a source directory (in) to a destination directory (out). It has a Swing GUI that allows the user to launch the copy operation by clicking the Copy Files button as shown in Figure 1.

Figure 1: Sample Application

Upon the launch of the copy operation, the application creates a progress monitor that keeps track of the amount of work completed and displays this information in a dialog containing a progress bar. The application also writes output regarding the progress of the operation to the console as shown in Figure 2.

Figure 2: Dialog containing progress bar

As shown above, the GUI displays the number of kilobytes copied and the file name of the file currently being copied. The user may cancel the operation at any time by clicking the Cancel button. After the copy operation completes, the GUI appears as shown in Figure 3:

Stepping Through the Sample Application

The sample application consists of a class, ProgressMonitorExample, that extends javax.swing.JPanel and implements java.awt.event.ActionListener and java.beans.PropertyChangeListener. ProgressMonitorExample's main() method tells the event dispatch thread to schedule the execution of a Runnable that creates the application GUI:

	public static void main(String[] args) {
		// tell the event dispatch thread to schedule the execution
		// of this Runnable (which will create the example app GUI) for a later time
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				// create example app window
				JFrame frame = new JFrame("Progress Monitor Example");
				// application will exit on close
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
				
				// create example app content pane
				// ProgressMonitorExample constructor does additional GUI setup
				JComponent contentPane = new ProgressMonitorExample();
				contentPane.setOpaque(true);
				frame.setContentPane(contentPane);					
				...

ProgressMonitorExample contains an inner class, CopyFiles, that extends javax.swing.SwingWorker. When the user clicks the Copy Files button, ProgressMonitorExample's actionPerformed() method receives the event, creates a new ProgressMonitor, and starts the file-copying operation on a background thread. Here's the code that creates the ProgressMonitor:

    public void actionPerformed(ActionEvent event) {
        // make sure there are files to copy
        File srcDir = new File("in");
        if (srcDir.exists() && (srcDir.listFiles() != null && srcDir.listFiles().length > 0)) {
            // set up the destination directory
            File destDir = new File("out");            
            // create the progress monitor
            progressMonitor = new ProgressMonitor(ProgressMonitorExample.this,
                                                  "Operation in progress...",
                                                  "", 0, 100);
            progressMonitor.setProgress(0);
			...

ProgressMonitor has a single constructor. The first argument is the parent component to the progress monitor's dialog box. The second argument, of type Object, is displayed on the dialog box. It should be a string, icon, or component. This example supplies the constructor with a string that lets the user know that the requested operation is underway. The third argument is an optional status note that also appears on the dialog box. This status note can be updated periodically as the monitored task runs. Set this value to null if no status note is necessary. The fourth and fifth arguments are the minimum and maximum values for the progress bar in the progress monitor dialog box.

The code below, also excerpted from actionPerformed(), creates a new instance of CopyFiles, adds ProgressMonitorExample as a property change listener on the instance, and executes the instance:

    // schedule the copy files operation for execution on a background thread
    operation = new CopyFiles(srcDir, destDir);
    // add ProgressMonitorExample as a listener on CopyFiles;
    // of specific interest is the bound property progress
    operation.addPropertyChangeListener(this);
    operation.execute();
    // we're running our operation; disable copy button
    copyButton.setEnabled(false);

CopyFiles subclasses SwingWorker, so the call to inherited method execute() schedules CopyFiles for execution on a background thread and returns immediately. Time-consuming activities should always run on a background thread rather than the event dispatch thread. This way, the GUI remains responsive.

Although the file-copying operation has begun, the progress monitor dialog box doesn't pop up right away. By default, ProgressMonitor waits for 500 ms before making a decision on whether or not to show the dialog box at all. After this time period has elapsed, if ProgressMonitor determines that the monitored operation has already completed or is likely to complete before the dialog box can be displayed, ProgressMonitor does not pop the dialog box. ProgressMonitor's method setMillisToDecideToPopup() controls this setting. setMillisToPopup() sets the estimated amount of time it will take the dialog box to appear; the default value for this property is 2 seconds.

The real work of copying the files occurs in doInBackground(), an abstract method on SwingWorker that CopyFiles overrides. Here's a partial listing:

	// perform time-consuming copy task in the worker thread
	@Override
	public Void doInBackground() {
		int progress = 0;
		// initialize bound property progress (inherited from SwingWorker)
		setProgress(0);
		// get the files to be copied from the source directory
		File[] files = srcDir.listFiles();
		// determine the scope of the task
		long totalBytes = calcTotalBytes(files);
		long bytesCopied = 0;
		
		while (progress < 100 && !isCancelled()) {                 
			// copy the files to the destination directory
			for (File f : files) {
				File destFile = new File(destDir, f.getName());
				long previousLen = 0;
				
				try {
					InputStream in = new FileInputStream(f);
					OutputStream out = new FileOutputStream(destFile);                    
					byte[] buf = new byte[1024];
					int counter = 0;
					int len;
					
					while ((len = in.read(buf)) > 0) {
						out.write(buf, 0, len);
						counter += len;
						bytesCopied += (destFile.length() - previousLen);
						previousLen = destFile.length();
						if (counter > PROGRESS_CHECKPOINT || bytesCopied == totalBytes) {
							// get % complete for the task
							progress = (int)((100 * bytesCopied) / totalBytes);
							counter = 0;
							CopyData current = new CopyData(progress, f.getName(), getTotalKiloBytes(totalBytes), getKiloBytesCopied(bytesCopied));

							// set new value on bound property
							// progress and fire property change event
							setProgress(progress);
							
							// publish current progress data for copy task
							publish(current);
						}
					}
					in.close();
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			...

doInBackground() gets any files located in the in directory and copies them one by one to the out directory. Each time a specified number of bytes have been copied, the application calculates what percentage of the total number of bytes has been copied so far, then creates an instance of the inner class CopyData to hold this information along with the total number of kilobytes, the number of kilobytes copied so far, and the filename of the file currently being copied. The application then updates the bound property progress with the calculated percentage, firing a property change event in the process. The call to publish() makes the copy task's current progress data available for processing in the event dispatch thread.

ProgressMonitorExample's propertyChange() method extracts the progress value from the property change event. It then updates the progress monitor animation by calling its setProgress() and passing the progress value. Here's the code:

    // executes in event dispatch thread
    public void propertyChange(PropertyChangeEvent event) {
        // if the operation is finished or has been canceled by
        // the user, take appropriate action
        if (progressMonitor.isCanceled()) {
            operation.cancel(true);
        } else if (event.getPropertyName().equals("progress")) {            
            // get the % complete from the progress event
            // and set it on the progress monitor
            int progress = ((Integer)event.getNewValue()).intValue();
            progressMonitor.setProgress(progress);            
        }        
    }

Notice that ProgressMonitor provides a convenient way to determine if the dialog has been canceled by the user. The sample application responds to a user cancellation by terminating the monitored activity, but in other situations it might be appropriate to allow the user to dismiss the dialog box while the activity continues to run in the background.

By overriding the SwingWorker method process(), CopyFiles can use the progress data made available by the call to publish() to update the GUI. process() executes in the event dispatch thread, so it is safe to update Swing components in this method. Here's the code:

	// process copy task progress data in the event dispatch thread
	@Override
	public void process(List data) {
		if(isCancelled()) { return; }
		CopyData update  = new CopyData(0, "", 0, 0);
		for (CopyData d : data) {
		    // progress updates may be batched, so get the most recent
			if (d.getKiloBytesCopied() > update.getKiloBytesCopied()) {
				update = d;
			}
		}
		
		// update the progress monitor's status note with the
		// latest progress data from the copy operation, and
		// additionally append the note to the console
		String progressNote = update.getKiloBytesCopied() + " of " 
							  + update.getTotalKiloBytes() + " kb copied.";
		String fileNameNote = "Now copying " + update.getFileName();
		
		if (update.getProgress() < 100) {
			progressMonitor.setNote(progressNote + " " + fileNameNote);
			console.append(progressNote + "\n" + fileNameNote + "\n");
		} else {
			progressMonitor.setNote(progressNote);
			console.append(progressNote + "\n");
		}           
	}

As shown above, process() updates the progress monitor's status note with the number of kilobytes copied so far and the filename of the file currently being copied, then appends this information to the console.

When its background operation is finished, CopyFiles sets its own state to done and invokes the done() method in the event dispatch thread. done() invokes the SwingWorker method get(), which returns the final result of the background task. In the case of the sample application, however, there is no final result to be processed. The sample application calls get() to determine whether or not the background task was canceled before completion and responds appropriately:

	// perform final updates in the event dispatch thread
	@Override
	public void done() {
		try {
			// call get() to tell us whether the operation completed or 
			// was canceled; we don't do anything with this result
			Void result = get();
			console.append("Copy operation completed.\n");                
		} catch (InterruptedException e) {
			
		} catch (CancellationException e) {
		    // get() throws CancellationException if background task was canceled
			console.append("Copy operation canceled.\n");
		} catch (ExecutionException e) {
			console.append("Exception occurred: " + e.getCause());
		}
		// reset the example app
		copyButton.setEnabled(true);
		progressMonitor.setProgress(0);
	}


Running the Sample Application

To run the sample application, download the sample code and unzip it. The sample application assumes that there are files to copy in the in directory located under the project root, so add some (preferably large) files of your choice to this directory. Launch NetBeans and select File -> Open Project. In the Open Project dialog box, navigate to the directory where you unzipped the sample code and select the folder progressMonitorExample. Select the Open as Main Project check box. Click Open Project Folder. Right-click the progressMonitorExample project and select Build, then right-click the project again and select Run.

References and Resources

Sample code for this tip
The Java Tutorial

About the Author

Jennie Hall is a lead developer working in the financial sector.

Application Basics With Ants (Young Developer Series, Part 3)
uses the Ants scenario in Greenfoot to describe Java packages, variables, and ways that objects interact with each other through methods.
By Dana Nourie, December 2008

Learn about Java packages, variables, and ways that objects interact with each other through methods.

In the articles Wombat Object Basics and Wombat Classes Basics, you learned about objects, classes, methods, and language syntax. Now, in Part 3 of the Young Developer series, you'll learn what is involved in writing a Java application that relies on other Java classes (or Java API), what variables are, how to use variables, and how objects interact through methods.

As in the last article, to follow along, you will need these installed on your computer:

This article is aimed at anyone interested in Java programming who is from the age of 10 to 100 and who has no programming experience. We recommend that you have read and followed the instructions in Wombat Object Basics and Wombat Classes Basics before you move on to this article.

Looking at Packages and Variables in Ants

For this tutorial, open the Ants scenario by going to the Scenario menu, and selecting Open. The scenarios folder should automatically be visible. Choose ants, and then click Open as shown in Figure 1.

Opening the Ants Scenario
Figure 1. Opening the Ants Scenario

A new window opens and displays the Ants scenario. If you do not see the sand-colored world on the screen, click the Compile All button at the bottom of the scenario main screen.

Read the rest of this article . . .

Trail: Security Features in Java SE

In this trail you'll learn how the built-in Java™ security features protect you from malevolent programs. You'll see how to use tools to control access to resources, to generate and to check digital signatures, and to create and to manage keys needed for signature generation and checking. You'll also see how to incorporate cryptography services, such as digital signature generation and checking, into your programs.

The security features provided by the Java Development Kit (JDK™) are intended for a variety of audiences:

  • Users running programs:

    Built-in security functionality protects you from malevolent programs (including viruses), maintains the privacy of your files and information about you, and authenticates the identity of each code provider. You can subject applications and applets to security controls when you need to.

  • Developers:

    You can use API methods to incorporate security functionality into your programs, including cryptography services and security checks. The API framework enables you to define and integrate your own permissions (controlling access to specific resources), cryptography service implementations, security manager implementations, and policy implementations. In addition, classes are provided for management of your public/private key pairs and public key certificates from people you trust.

  • Systems administrators, developers, and users:
    JDK tools manage your keystore (database of keys and certificates); generate digital signatures for JAR files, and verify the authenticity of such signatures and the integrity of the signed contents; and create and modify the policy files that define your installation's security policy.

Trail Lessons

Quick Tour of Controlling Applets shows how resource accesses, such as reading or writing a file, are not permitted for unsigned applets unless explicitly allowed by a permission in a policy file.

Quick Tour of Controlling Applications builds on the previous lesson, showing that when applications are run under a security manager, resource accesses may be controlled in exactly the same way as for unsigned applets.

API and Tools Use for Secure Code and File Exchanges defines digital signatures, certificates, and keystores and discusses why they are needed. It also reviews information applicable to the next three lessons regarding the steps commonly needed for using the tools or the API to generate signatures, export/import certificates, and so on.

Signing Code and Granting It Permissions illustrates the use of all the security-related tools. It shows the steps that a developer would take to sign and to distribute code for others to run. The lesson also shows how someone who will run the code (or a system administrator) could add an entry in a policy file to grant the code permission for the resource accesses it needs.

Exchanging Files shows use of the tools by one person to sign an important document, such as a contract, and to export the public key certificate for the public key corresponding to the private key used to sign the contract. Then the lesson shows how another person, who receives the contract, the signature, and the public key certificate, can import the certificate and verify the signature.

Generating and Verifying Signatures walks you step by step through an example of writing a Java program using the JDK Security API to generate keys, to generate a digital signature for data using the private key, and to export the public key and the signature to files. Then the example shows writing a second program, which may be expected to run on a different person's computer, that imports the public key and verifies the authenticity of the signature. Finally, the example discusses potential weaknesses of the approach used by the basic programs and demonstrates possible alternative approaches and methods of supplying and importing keys, including in certificates.

Implementing Your Own Permission demonstrates how to write a class that defines its own special permission.

 *******************

Test Your Java Knowledge - Chance to Win 1 of 100 books!

Take the SDN Quiz to see how much you know about Java. Join or log into the Sun Developer Network and answer the questions correctly for a chance to win one of 100 Hello World(s) -- From Code to Culture: A 10 Year Celebration of Java Technology (Hardcover). Register to take the Quiz and a chance to Win Today!

No purchase necessary. Void where prohibited. Open to legal residents of U.S. (excluding Puerto Rico) and Canada (excluding Quebec) 18 years or older. Entrants are responsible for complying with their employers' policies regarding acceptance of promotional items. Entries accepted from 11/04/08 to 12/01/08. 100 winners will receive one copy of the book Hello World(s) -- From Code to Culture: A 10 Year Celebration of Java Technology (Hardcover) (US $24.99). For complete Official Rules, visit here.

In this tutorial, you learn how to use the UML features of the IDE to create a simple UML class diagram. You then use the code generation and reverse engineering features to develop a simple banking application, which you can test by executing a test class. This banking application is greatly simplified; a real model for an application of this type would require more detail. The purpose of this tutorial is to introduce some of the IDE's UML features, not to teach you about UML concepts or the Java programming language.

Expected duration: 25 minutes

Content on this page applies to NetBeans IDE 6.0

    Tutorial Requirements

    Before you proceed, make sure you review the requirements in this section.

    Prerequisites

    To use this tutorial, the IDE must be installed on your system and you should be familiar with the basic parts of the IDE. You should also have a basic familiarity with the Java programming language and UML. For a basic understanding of the IDE, see the IDE Basics topics in the online help. A good resource for UML techniques and theory is the official UML resource page at http://www.uml.org/.

    System Requirements

    This tutorial assumes that your system meets the requirements specified in the Systems Requirements section of the NetBeans 6.1 Release Notes.

    Software Needed for This Tutorial

    To follow this tutorial, you need the software and resources listed in the following table.

    Software or Resource Version Required
    NetBeans IDE version 6.1 or
    version 6.0
    Java Development Kit (JDK)

    version 6 or
    version 5

    Creating the Java Project for the Application

    In this section , you create a new Java project for the Java application you are going to develop in this tutorial.

    1. From the main menu, choose File > New Project and then do the following in the New Project wizard:
      1. Under Categories, select Java.
      2. Under Projects, select Java Application
      3. Click Next.
    2. In the Project Name field, type JavaPrj.
    3. For the Project Location field, click Browse, navigate to any directory on your computer. Click Open and type MyPrj.
    4. Clear the Set as Main Project and the Create Main Class checkboxes.
    5. Click Finish.
      A progress dialog box appears.
      When the new JavaPrj project is created, it appears in the Projects window.

     View Demo

    top


    Creating the UML Project and the Class Diagram

    In this section, you create the UML project (or UML project) and class diagram for the application. A UML project is the mechanism by which you store and manage a collection of files for a UML model. A UML model contains all of the model's diagrams, their associated elements, and metadata related to the UML model.

    1. To create the UML project, choose File > New Project and then do the following:
      1. Under Categories, select UML.
      2. Under Projects, select Java-Platform Model.
      3. Click Next.
      The New Java-Platform Model dialog box opens.
    2. In the Project Name field, type UMLPrj.
      Notice that when you type the Project Name, the IDE automatically suggests this name for the name of the Project Folder.
    3. Verify that the Project Location is MyPrj.
    4. Click Finish.
      The IDE creates the UML project and the Create New Diagram dialog box appears.
    5. In the Diagram Type list, select Class Diagram.
    6. In the Diagram Name field, type BankClassDiagram.
    7. Leave UMLPrj in the Namespace field and click Finish.
      The IDE does the following:
      • Adds the UMLPrj project node in the Projects window.
      • Creates a BankClassDiagram node under the Model node
      • Displays the new diagram in the Diagram editor (the diagram is empty at this point)
      • Opens the Modeling Palette

     View Demo

    top

    Adding and Defining Class Elements

    Now, add and define the class elements that will make up your Java application. You use the Class icon from the Modeling Palette to create the class elements.

    1. From the Basic section of the Modeling Palette, select the Class icon image of Class icon is displayed. and click in the Diagram editor.
      This action places a class element on the Diagram editor.
    2. Deselect the Class icon by right-clicking anywhere in the Diagram editor.
    3. Select the newly added class element, type BankAccount and press Enter.
      The IDE does the following:
      • Labels the element BankAccount
      • Creates a public operation, BankAccount()
      • Displays the properties of the BankAccount class in the Properties window
    4. With the BankAccount class element selected in the Diagram editor, right-click the word Attributes and choose Insert Attribute from the pop-up menu.
      A one-line editor opens and displays the following information:
      visibility type name[ranges]=initialValue{name=value}
    5. Type balance and press Enter.
      A private attribute named balance of type int appears on the BankAccount class. The following operations are created on the class:
      • public int getBalance()
      • public void setBalance(int val)
    6. With the BankAccount class element still selected in the Diagram editor, right-click the word Operations and choose Insert Operation from the pop-up menu.
      A one-line editor opens and displays the following information:
      visibility returnType name(parameter) {properties...}
    7. Type withdraw, move your cursor (use the forward arrow on your keyboard) into the parentheses, type int amount and press Enter.
      The IDE adds the new operation in the class element as follows:
      public void withdraw(int amount)

     View Demo

    top

    Adding More Elements to the Diagram

    In this section, you use more UML icons from the Modeling Palette to add interfaces, packages, attributes, and operations to your application.

    1. From the Basic section of the Modeling Palette, select the Package icon image of Package icon.

      Note: If necessary, scroll down to see the additional Modeling icons.
    2. Click in the Diagram editor to add a package element to the class diagram.
    3. Right-click anywhere in the Diagram editor to deselect the Package icon.

      Note: As you add modeling elements to the diagram, you can select them and drag them to new locations in the Diagram editor to improve the appearance of the diagram. Be careful when you right-click, as in some positions, this action opens a pop-up menu for the Diagram editor. If this happens, just click again in the white space of the Diagram editor.
    4. With the package element selected, type bankpack and press Enter.
    5. From the Basic section of the Modeling Palette, select the Interface icon image of Interface icon and click in the Diagram editor.
    6. Right-click anywhere in the Diagram editor to deselect the Interface icon.
    7. With the interface element selected, type Bank and press Enter.
    8. Add a deposit operation to the Bank interface.
      You add operations to interfaces the same way you add them to classes (Step 6 in the preceding section). Define the operation as follows:
      public void deposit(int amount)
    9. From the Modeling Palette, select the Class icon image of Class icon and click in the Diagram editor two times.
    10. Right-click anywhere in the Diagram editor to deselect the Class icon.

      Note: If you draw too many class elements, deselect the Class icon, then right-click the class element you want to delete and select Edit > Delete.
    11. Name the class elements Checking and AccountTest and resize the elements if necessary.

     View Demo

    top


    Identifying Associations Between Elements

    In this section, you use the UML icons from the Modeling Palette to identify the association between class elements.

    1. From the Basic section of the Modeling Palette, select the Implementation icon image of Implementation icon and click inside the BankAccount class element.
    2. Click inside the Bank interface element and right-click anywhere in the Diagram editor to deselect the Implementation icon.
      An implementation link appears between the class and the interface element. An implementation link denotes a relationship between a class and an interface.
    3. From the Basic section of the Modeling Palette, select the Generalization icon image of Generalization icon.
    4. Click inside the Checking class element (the subclass), then click inside the BankAccount class element (the superclass).
      The Select Methods to Redefine dialog box appears.
    5. Select the withdraw method and click OK.
      The IDE does the following:
      • Closes the dialog box
      • Adds the withdraw method to the Checking class
      • Adds the Generalization link between the two related Class elements
      A generalization link shows the relationship between a subclass and its superclass. Subclasses are refinements of the superclass, meaning they can inherit features (attributes and operations) from the superclass.
    6. Right-click in any white space in the Diagram editor to deselect the Generalization icon.
    7. From the Basic section of the Modeling Palette, select the Nested Link icon image of Nested Link icon and click inside the BankAccount element and then inside the bankpack package element.
    8. Use the Nested Link icon as described in the prior step and connect the Checking, AccountTest, and Bank elements with the bankpack package.
    9. Deselect the Nested Link icon.
      A nested link denotes how elements are organized into groups. In this case, you organized all the class elements into a group in the bankpack package.
    10. Press Ctrl-S anywhere in the Diagram editor to save the changes made to the model.

     View Demo

    top


    Generating Java Source Code

    In this section, using the Generate Code feature of UML you generate the Java source code for the UML model that you created in the previous sections.

    1. In the Projects window, right-click the UMLPrj node and choose Generate Code from the pop-up menu.
      The Generate Code dialog box appears. and specifies the Target Project.
    2. Accept the default checkboxes in the Generate Code dialog box.
    3. Click OK.
      The IDE generates the code and the output window displays the progress of the code generation process.

     View Demo

    top

    Continuing Development Using Reverse Engineering

    In this section, you continue with your application development by modifying the generated source code in the Source editor and using the Reverse Engineer feature to update your UML model of your application.

    1. In the Projects window, expand the UMLPrj > Model > bankpack node.
    2. Right-click the BankAccount node and choose Navigate To Source from the pop-up menu.
    3. Add the following code to the deposit method in the Source Editor:
      setBalance(getBalance() + amount);
    4. Under the UMLPrj > Model > bankpack node in the Projects window, right-click the AccountTest node and choose Navigate To Source from the pop-up menu.
    5. Type (or copy and paste) the following code in the Source Editor:
      public static void main(String[] args) {
      Checking myChecking = new Checking();
      myChecking.deposit(100);
      System.out.println("Checking Balance is: " +
      myChecking.getBalance() );
      }
      This code creates a new Checking object and specifies a deposit of $100, then prints the results.
    6. Right-click in the Source Editor and choose Format Code.
    7. Press Ctrl-S anywhere in the Source Editor to save the changes made to the AccountTest.java source file.
    8. Right-click in the Source Editor again and choose Reverse Engineer from the pop-up menu. The Reverse Engineer dialog box appears.
    9. Select Use Existing UML Project in the Reverse Engineer dialog box and choose UMLPrj as the target project.
    10. Click OK to invoke the reverse engineering process.
    11. The popup Model Element Overwrite Authorization dialog appears, requesting that you confirm your overwriting the AccountTest model element. Click Yes/ Yes to All.
    12. Click the BankClassDiagram tab. Notice that the newly entered main method now appears in the AccountTest class element in the class diagram. By using the Reverse Engineer feature, the changes made to the Java source project can be reflected in the corresponding UML model project.

     View Demo

    top

    Testing Your Work

    Now build and run your project.

    1. In the Projects window, right-click the JavaPrj node and choose Build from the pop-up menu.
    2. In the Projects window, right-click the JavaPrj node and choose Run from the pop-up menu. The Run Project dialog box appears.
    3. In the Run Project dialog box, click OK to select the bankpack.AccountTest as the main class. The IDE executes the application and displays the following output in the Output window:
      Checking Balance is: 100

    You have now completed the application.

     View Demo

    top

    Summary

    In this tutorial, you designed a class diagram for a simple banking application. You learned how to perform the following tasks:

    • Create a UML project
    • Use the UML icons from the Modeling Palette to create classes, interfaces, packages, attributes, and operations
    • Link the classes together with UML associations
    • View the elements that you created in the Diagram editor in the UML project as represented in the Projects window
    • Generate the source code for the elements created in the Diagram editor in the UML project and view the generated source in the Source Editor.
    • Use the Code Generation and reverse engineering features to go back and forth between modeling and developing code in the Source Editor
    • Compile and execute classes from the Source Editor

    top

    Next Steps

    • To learn more about the UML feature, complete the Reverse Engineering tutorial.

    By Dana Nourie

    BlueJ is an integrated development environment (IDE) specifically designed for teaching students object-oriented programming using the Java programming language. Although BlueJ covers the introductory phase of learning to program, the NetBeans IDE offers powerful tools for professional developers. Taking the inevitable step from one into the other has been a difficult barrier for students -- until now.

    The collaboration of the NetBeans IDE and BlueJ teams has resulted in the NetBeans BlueJ plugin. This tool creates a smooth migration path for students learning the Java programming language from beginner's stage through to the use of professional development tools. In addition, this IDE provides a seamless path for students to switch from educational tools into a full-featured, professional IDE. The BlueJ plugin makes the transition between these two environments easier for students and teachers. Even if you are not familiar with BlueJ, the NetBeans BlueJ plugin is a great way to learn to use an IDE.

    This article gets you started using the NetBeans BlueJ plugin. First, you'll discover how easy it is to load existing projects and edit them, and then you'll learn to create a new project and use drag-and-drop features to create a graphical user interface (GUI).

    Developers unfamiliar with the BlueJ software will also learn everything they need to get started with this IDE and will benefit by following along with the examples.

    To follow the descriptions and code examples, download the NetBeans IDE version 6.1 or later. In addition, download the BlueJ project Calculator.zip, which the first part of this article uses as an example. In the second part of the article, you create a small application called Address Book to learn various other IDE features.

    Read the article . . .

    *************

    Learn about Sun Microsystems events in Second Life

    *************

    Discover resources for Student Developers

    *************

    Join developers and students in virtual learning

    *************

    Learning in Second Life

    Getting Started With the NetBeans BlueJ Plugin

    This article gets you started using the NetBeans BlueJ plugin by loading an existing project, and then creating a new project that uses drag-and-drop features to create a graphical user interface (GUI).

    This community is for all things Macintosh and Java related. That may mean developing Java code on the Mac, with the various tools available to Mac developers... or it may mean running your Java code on the Mac, using available technologies to deliver a great experience to your Mac-based users... or even tying into technologies like Cocoa. If you have Mac-specific projects, weblogs, questions, or advice, this is the place to be.

    Here are some of the items you'll find on this Mac Java  Community page:


    Fabrizio Giudici Bye bye, Mac OS X?
    If you follow my blog, you know that I've a bad attitude towards Apple's gear, even though (or just because?) I've been an Apple user for three years now. I've been frustrated by a) lack of support for Java updates, b) Mac OS X not performing as I need (Linux on the same hardware box is faster) and c) the scarce quality of my MacBook Pro (first generation). So, this week I can officially say that - at the moment - Mac OS X is no more my primary operating system.   Fabrizio Giudici

    OpenJDK 7 for Mac OS X
    Landon Fuller has announced that OpenJDK7 is now runnable on Mac OS X (and the BSDs) as part of the OpenJDK BSD Port project, culminating the efforts of his SoyLatte project to bring the latest open-source JDK to the Mac. "The move to OpenJDK -- and Sun's re-licensing of the code under the GPL license -- opens the project to any interested contributor." He suggests there's more work to do with JCK conformance testing, enabling dtrace support, PowerPC and ARM support via the Zero project, Core Audio-based sound support, and more. To facilitate user testing, Landon has also posted OpenJDK 7 binaries for Darwin (and, by extension, for Mac OS X). 

    Running VisualVM on MacOS X
    The Aquarium points out a tip for Running VisualVM on MacOS X: "I wrote about VisualVM yesterday (entry) but I had missed Octavian's Introduction where he gives instructions on how to use VisualVM on MacOS X. As a reminder, to run the VisualVM client you need a recent JVM, so you will need to use the latest JVM from Apple, but the app can run in a variety of JVMs, remote or local to VisualVM. VisualVM can even save the data into a snapshot and process it offline."

    Java SE 6 for Mac OS X 10.5.2
    Available via Software Update, Java for Mac OS X 10.5 Update 1 adds Java SE 6 version 1.6.0_05 to your Mac. This version of Java is only for Mac OS X v10.5.2 and later, and only runs on 64-bit Intel machines. Developers may want to check out the release notes, which detail major new features including an API to work with the Dock icon (getting and setting the image, adding a badge, setting a dock menu, etc.), the ability to provide document-modal dialog sheets, support for Java DTrace probes, AppleScript as a supported language to the javax.script API, and more. 

    And there is a whole lot more. Visit Mac Java Community today!

    ****************************

    Virtual Classrooms in Geeksville

    Over the last few years I've been spending a lot of time online learning a whole lot of stuff. There is no better tool to teach us about computing, programming languages, and software than the computer itself. Of course, I realize it's not the computer but the site or the program, but virtual learning is hugely successful and for good reasons. And it's not limited to computer topics, thank goodness.[Read More]

    Learning in Second Life

    Second Life (SL) is easy to misunderstand, and many people have the wrong idea that it is some kind of game environment, or a place where people just chat and act silly. On the contrary, Second Life has many places of learning from Science Friday, to Buddhist meditations, to technical seminars[Read More]


    by Jennie Hall

    In Exchanging Data With XML and JAXB, Part 1, we saw how the Java Architecture for XML Binding (JAXB) expedites the exchange of data between systems. With JAXB 2.0's annotation support, generating XML data for a business partner is as easy as annotating your existing object model. 

    In this tip, you'll learn how JAXB's binding customization features can facilitate XML processing for the recipient of data as well as for the sender. Binding customization offers a level of control over the characteristics of the Java classes generated by the JAXB schema compiler. This allows you to work with an object model that makes sense for your business domain even when processing XML instance documents based on a schema that is not of your own design.

    For a brief overview of the Java Architecture for XML Binding (JAXB), see the "What's JAXB?" section of Exchanging Data With XML and JAXB, Part 1.

    The Sample Application

    Let's continue with our scenario from Part 1.A veterinary office, NiceVet, wants to send upcoming appointment reminders and pet birthday cards to its clients. NiceVet contracts with a service provider, WePrintStuff, to do the printing and mailing. In Part 1, we assembled some data for WePrintStuff by annotating NiceVet's existing object model and then using JAXB to marshal application data from Java objects to an XML instance document. We also used JAXB's schema generator to produce a corresponding schema from the annotated Java classes.

    On the receiving end, WePrintStuff will run the JAXB schema compiler against the source schema to generate the schema-derived classes. JAXB will create instances of these classes as it unmarshals NiceVet's data from the XML instance document and binds it into a Java content tree. In some cases, however, the default manner in which JAXB generates the schema-derived classes and binds the data is not exactly what is needed. JAXB's binding customization features provide us with some nice ways to handle many of these cases. We'll take a look at some of them in the next section.

    Customizing the Source Schema

    We can make some customizations right away to make life easier at WePrintStuff. For example, we would like to work with meaningful package and class names and avoid any naming collisions. To accomplish this, we can add custom binding declarations to the source schema itself -- this is known as inline customization.

    Here are the first few lines of the annotated schema:

    	<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    	<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    				 <!-- JAXB namespace declaration required for inline customization -->
    	                         xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    	                         xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    	                         jxb:extensionBindingPrefixes="xjc"
    				 <!-- JAXB version number required for inline customization -->
    	                         jxb:version="2.0">
    	    <xs:annotation>
    	        <xs:appinfo>
                        <!-- All collections in this schema will use implementation class java.util.ArrayList. -->
    	            <jxb:globalBindings collectionType="java.util.ArrayList"/>
    	            <jxb:schemaBindings>
                            <!-- Specify the package for the generated classes; avoid naming collisions. -->
    	                <jxb:package name="weprintstuff.generated">
                                <!-- Specify some Javadoc that describes our package and its uses. -->
    	                    <jxb:javadoc><![CDATA[<body> The package weprintstuff.generated contains the
                                     schema-derived classes that make up the object model used to process
                                     print client orders.</body>]]>
    	                    </jxb:javadoc>
    	                </jxb:package>
    	            </jxb:schemaBindings>
    	        </xs:appinfo>
    	    </xs:annotation>
    

    To enable inline customization, we must include a JAXB namespace declaration and the JAXB version number. The JAXB namespace prefix we'll use in our sample application is jxb:. We can override the default JAXB bindings at different scopes. Lower-level, more fine-grained scopes inherit declarations made at higher-level scopes, but binding declarations made at lower-level scopes can override these inherited declarations. The scopes in order from highest to lowest level are global, schema, definition, and component.

    In the preceding example, we've made a declaration at global scope that specifies that all collections in this schema will use the implementation class java.util.ArrayList. If our source schema imported another schema, this declaration would apply to the second schema as well. There can be only one <globalBindings> declaration per schema. This declaration is valid in the top-level schema only.

    At schema scope, we've specified the package into which the JAXB schema compiler will generate the schema-derived classes. We've also included some package-level Javadoc that describes our package and its uses. Note that we've wrapped our custom binding declarations in <annotation><appinfo> tags.

    Now that we have the package we want, let's see if we can get some class names that better reflect Java naming conventions and WePrintStuff's business domain. The default bindings for the original schema would generate classes with names like ClassAType, ClassBType, and so on.This is not how we typically name classes in the Java programming language, so let's fix it:

        <xs:element name="printOrder" type="PrintOrderType"/>
        <xs:complexType name="PrintOrderType">
            <xs:annotation>
                <xs:appinfo>
                    <!-- Name the generated class PrintOrder rather than PrintOrderType. -->
                    <jxb:class name="PrintOrder">
                        <!-- Provide some Javadoc for PrintOrder. -->
                        <jxb:javadoc><![CDATA[<code>PrintOrder</code> javadoc goes here]]>
                        </jxb:javadoc>
                    </jxb:class>
                </xs:appinfo>
            </xs:annotation>
            <xs:sequence>
                <xs:element name="notifications" type="notificationsType" minOccurs="0">
                    <xs:annotation>
                        <xs:appinfo>
                            <!-- PrintOrder's notifications property becomes printItems. -->
                            <jxb:property name="printItems"/>
                        </xs:appinfo>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
    		...
        </xs:complexType>
        <xs:complexType name="notificationsType">
            <xs:annotation>
                <xs:appinfo>
                    <!-- Name the generated class PrintItems rather than NotificationsType. -->
                    <jxb:class name="printItems" />
                </xs:appinfo>
            </xs:annotation>
    			...
        </xs:complexType>
    		
    

    PrintOrderType becomes PrintOrder, NotificationsType becomes PrintItems, and so on. Dealing with class names is straightforward, but unfortunately we're stuck with a class structure that is less than ideal. There are too many wrappers around the data, which results in a long chain of method calls. Here's what the calls would have looked like with classes derived from the original schema. As you can see, methods with singular method names return collections, which is misleading.

    	List<AppointmentType> appointments = printOrder.getNotifications().getAppointments().getAppointment();
    	List<BirthdayType> birthdays = printOrder.getNotifications().getBirthdays().getBirthday();
    

    The following improved calls show the new names, which say what they mean and are more relevant to WePrintStuff's business domain.

    	List<Appointment> appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
    	List<Birthday> birthdays = printOrder.getPrintItem().getBirthdayHolder().getBirthdays();
    

    I tried to solve some of the class structure issues by using the enhanced <jxb:javaType> customization (<xjc:javaType>) and an adapter class derived from XmlAdapter, but JAXB currently does not support this customization for XML complex types. This issue is documented in the JAXB issue tracker as issue number 209. Meanwhile, we'll look at an example of the enhanced <jxb:javaType> customization used with an XML simple type in the upcoming paragraphs.

    Moving down the source schema, we see that each print order received will have an ID of type long. We know, however, that WePrintStuff employs a natural key strategy in its persistent store. For print-order records, the key consists of a client name and an order ID. WePrintStuff uses the class PrintOrderKey to encapsulate this key information. We'll apply a binding customization that causes the JAXB schema compiler to use an adapter class, IdAdapter, to replace the original print-order ID with WePrintStuff's PrintOrderKey class. Take a look:

       <xs:element name="printOrder" type="PrintOrderType"/>
        <xs:complexType name="PrintOrderType">
            <xs:sequence>
                <xs:element name="notifications" type="notificationsType" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="id" type="xs:long" use="required">
                <xs:annotation>
                    <xs:appinfo>
                        <!-- Use an XmlAdapter-based adapter to create WePrintStuff's PrintOrderKey class. -->
                        <!-- Specify the name orderKey for this property. -->
                        <jxb:property name="orderKey">
                            <jxb:baseType>
                                <!-- Specify weprintstuff.print.PrintOrderKey as the type of the orderKey property. -->
                                <!-- Specify the adapter class that will map the schema type to the Java type. -->
                                <xjc:javaType name="weprintstuff.print.PrintOrderKey"
                                  adapter="weprintstuff.print.IdAdapter"/>
                            </jxb:baseType>
                        </jxb:property>
                    </xs:appinfo>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    

    We've changed the name of the print-order property to orderKey and specified the types of the adapter and the order key. During the unmarshalling process, JAXB calls IdAdapter's unmarshal() method, which receives the value of id and incorporates it into a new PrintOrderKey containing the order ID and client name. Here's the code for IdAdapter:

    	public class IdAdapter extends XmlAdapter<String, PrintOrderKey> {
    
    	    // When marshalling a Java content tree to an XML instance document,
    	    // move from the type that we work with in Java (PrintOrderKey)
    	    // to the type that JAXB understands.
    	    public String marshal(PrintOrderKey key) throws Exception {
    	        return key.getOrderId().toString();
    	    }
    
    	    // When unmarshalling an XML instance document to a Java content tree,
    	    // move from the type that JAXB understands (String) to the type
    	    // we want to work with in Java technology.
    	    public PrintOrderKey unmarshal(String id) throws Exception {
    	        // WePrintStuff uses natural keys. Add client name and
    	        // convert String ID to required Long.
    	        return new PrintOrderKey("NICEVET", new Long(id));
    	    }
    	}
    

    The <xjc:javaType> customization we've just discussed is an example of a vendor extension. The JAXB reference implementation (RI) offers additional customizations that are not part of the JAXB specification. To use these extensions, we must include a declaration for the JAXB RI vendor extension namespace and specify a namespace prefix:

    	<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	                         xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
                                     <!-- JAXB RI vendor extension namespace declaration is required. -->
    	                         xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                                     <!-- JAXB RI vendor extension namespace prefix is required. -->
                                     jxb:extensionBindingPrefixes="xjc"
    	                         jxb:version="2.0">
    

    Finally, vendor extensions require that we run the schema compiler with the -extension switch. For an example of the standard <jxb:javaType> customization, which is not a vendor extension, check out niceVet.xsd and weprintstuff.print.CustomDataTypeConverter. These files are included with the sample code that comes with this tech tip. In our example, we've used the <jxb:javaType> customization to convert XML dateTime types to nicely formatted String dates ready for output.

    Things are looking better, but we'd also like to handle the printing of appointment reminders and birthday cards as polymorphically as we can. Take a look at the following:

       <xs:complexType name="AppointmentType">
            <xs:annotation>
                <xs:appinfo>
                    <!-- Name has generated class Appointment rather than AppointmentType. -->
                    <jxb:class name="Appointment">
                        <jxb:javadoc><![CDATA[<code>Appointment</code> javadoc goes here]]>
                        </jxb:javadoc>
                    </jxb:class>
                </xs:appinfo>
            </xs:annotation>
            <xs:complexContent>
                <!-- XML Schema extension element causes AppointmentType to derive from printItemType, a type we've added to the schema. -->
                <xs:extension base="printItemType">
                    <xs:sequence>
                       ...
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
            ...
        <!-- Add this complex type to the schema so that Appointment class now derives from PrintItem, a base class that we've implemented. -->
        <xs:complexType name="printItemType">
            <xs:annotation>
                <xs:appinfo>
                    <!-- Due to this customization, JAXB will not generate a class for printItemType; it will use the PrintItem class that we've written. -->
                    <jxb:class ref="weprintstuff.print.PrintItem"/>
                </xs:appinfo>
            </xs:annotation>
        </xs:complexType>
    

    Fortunately for us, we can modify the structure of the source schema somewhat while retaining the schema's ability to validate the same set of XML instance documents. In this case, we have added a totally new complex type, printItemType, to the schema. Then we modified the complex type AppointmentType with the XML Schema extension element, causing AppointmentType to derive from printItemType.

    At this point, we applied a JAXB customization to printItemType that directs the schema compiler to use the specified class that we've written rather than generating one. Because we've implemented PrintItem ourselves, we can include behavior: specifically, a print() method that allows us to handle subclasses, such as Appointment and Birthday, in a more polymorphic manner. Here's the code for PrintItem:

    	package weprintstuff.print;
    
    	import java.util.*;
    
    	public abstract class PrintItem {
    
    	    private static final Map<String,Printer> printers;
    
    	    static {
    	        printers = new HashMap<String,Printer>();
    	        printers.put("weprintstuff.generated.Birthday", new BirthdayPrinter());
    	        printers.put("weprintstuff.generated.Appointment", new AppointmentPrinter());
    	    }
    
    	    public void print() {
    	        Printer p = this.getPrinter();
    	        p.print(this);
    	    }
    
    	    private Printer getPrinter() {
    	        return printers.get(this.getClass().getName());
    	    }
    	}
    

    The Printer interface has a single method:

        public void print(PrintItem item);
    

    Although we're still hampered by the structure of the schema-derived classes as discussed earlier, the code to print the items in the print order is now pretty clean. Here's an excerpt from our main() method:

    	// Unmarshal the data in the XML instance document to a Java content tree
    	// made up of instances of the schema-derived classes.
    	JAXBElement printOrderElement = (JAXBElement)unmarshaller.unmarshal(new FileInputStream(input));
    	PrintOrder printOrder = (PrintOrder)printOrderElement.getValue();
    
    	List<Appointment> appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
    	for (Appointment a : appointments) {
    		a.print();
    	}
    
    	List<Birthday> birthdays = printOrder.getPrintItems().getBirthdayHolder().getBirthdays();
    	for (Birthday b : birthdays) {
    		b.print();
    	}
    

    Another nice customization feature that JAXB provides is the ability to map XML simple types to typesafe enumerations. This is convenient because WePrintStuff currently has printing templates for certain types of appointments only. We'll modify the schema to include the supported appointment types and add a customization that causes the schema compiler to map the elements of ApptType to a Java typesafe enum class. XML instance documents with appointment types that WePrintStuff does not support will be rejected:

        <xs:simpleType name="ApptType">
            <xs:annotation>
                <xs:appinfo>
                    <!-- Map the elements of this simple type to a Java typesafe enum class. -->
                    <jxb:typesafeEnumClass/>
                </xs:appinfo>
            </xs:annotation>
            <!-- Use XML Schema elements restriction and enumeration to define the supported appointment types. -->
            <xs:restriction base="xs:string">
                <xs:enumeration value="Yearly Checkup"/>
                <xs:enumeration value="Well Mom Exam"/>
                <xs:enumeration value="Teeth Cleaning"/>
                <xs:enumeration value="Vaccination"/>
                <xs:enumeration value="Senior Pet Checkup"/>
            </xs:restriction>
        </xs:simpleType>
    

    Here is the resultant typesafe enum class, ApptType:

    	package weprintstuff.generated;
    
    	import javax.xml.bind.annotation.XmlEnum;
    	import javax.xml.bind.annotation.XmlEnumValue;
    	import javax.xml.bind.annotation.XmlType;
    
    	@XmlType(name = "ApptType")
    	@XmlEnum
    	public enum ApptType {
    
    	    @XmlEnumValue("Yearly Checkup")
    	    YEARLY_CHECKUP("Yearly Checkup"),
    	    @XmlEnumValue("Well Mom Exam")
    	    WELL_MOM_EXAM("Well Mom Exam"),
    	    @XmlEnumValue("Teeth Cleaning")
    	    TEETH_CLEANING("Teeth Cleaning"),
    	    @XmlEnumValue("Vaccination")
    	    VACCINATION("Vaccination"),
    	    @XmlEnumValue("Senior Pet Checkup")
    	    SENIOR_PET_CHECKUP("Senior Pet Checkup");
    	    private final String value;
    
    	    ApptType(String v) {
    	        value = v;
    	    }
    
    	    public String value() {
    	        return value;
    	    }
    
    	    public static ApptType fromValue(String v) {
    	        for (ApptType c: ApptType.values()) {
    	            if (c.value.equals(v)) {
    	                return c;
    	            }
    	        }
    	        throw new IllegalArgumentException(v);
    	    }
    
    	}
    

    So far we've made what are known as inline binding customizations, but JAXB also accepts customizations in the form of one or more external binding customization files. Inline and external customizations can be used in combination, but they cannot be used together on the same element. External binding files are useful when you cannot modify a given schema or when you want to reuse customizations across schemas. For example, WePrintStuff has its own class for U.S. addresses, DomesticAddress, and WePrintStuff would like to use this class to represent the concept of an address throughout the system.

    Here's the external binding file, binding.xjb:

    	<!-- XML Schema namespace is required, as are the JAXB namespace and version. -->
    	<jxb:bindings version="2.0"
    	               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    	               xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    	  <!-- Specify the schema name and root schema node. -->
    	  <jxb:bindings schemaLocation="niceVet.xsd" node="/xs:schema">
    
    	    <!-- Specify the schema node to which this customization should apply with an XPath expression. -->
    	    <jxb:bindings node="//xs:complexType[@name='AddressType']">
                    <!-- Direct the schema compiler to use the DomesticAddress class rather than generating a class for complex type AddressType. -->
    	        <jxb:class ref="weprintstuff.print.DomesticAddress"/>
    	    </jxb:bindings> <!-- node="//xs:complexType[@name='AddressType']" -->
    
    	  </jxb:bindings> <!-- schemaLocation="niceVet.xsd" node="/xs:schema" -->
    	</jxb:bindings>
    

    The binding customization file is just an ASCII text file. A valid binding file must specify the schema name and node. We identify nodes using XPath expressions. In the previous listing, we've applied a customization that directs the schema compiler to use WePrintStuff's DomesticAddress class rather than generating a class for the complex type AddressType. This is the same customization illustrated earlier in our PrintItem base class example, although in that situation, we declared the customization inline. The syntax for supplying a binding customization file to the schema compiler is the following:

    	xjc -b bindings schema
    

    We can apply multiple binding files to one schema, one binding file to multiple schemas, or multiple binding files to multiple schemas. Each binding file must have its own -b switch.

    Generating the Schema-Derived Classes

    We generate our schema-derived classes at the command line with the following command to the schema compiler, xjc:

    	xjc -d ./src -b binding.xjb -extension niceVet.xsd
    

    The schema compiler informs us that it has generated our classes with the following output:

    	parsing a schema...
    	compiling a schema...
    	weprintstuff\generated\Adapter1.java
    	weprintstuff\generated\Adapter2.java
    	weprintstuff\generated\Appointment.java
    	weprintstuff\generated\ApptType.java
    	weprintstuff\generated\Birthday.java
    	weprintstuff\generated\ObjectFactory.java
    	weprintstuff\generated\Owner.java
    	weprintstuff\generated\Pet.java
    	weprintstuff\generated\PrintItems.java
    	weprintstuff\generated\PrintOrder.java
    	weprintstuff\generated\package.html
    

    The JAXB schema compiler has a number of options. For example, it will mark generated classes as read only in response to the -readOnly switch. Invoke xjc with no options or with the -help switch for more information.

    The Payoff

    We've modified our source schema, made our customizations, and generated our schema-derived classes. All that's left to do is run our printing program, let JAXB bind the XML data supplied by NiceVet, and print out the appointment reminders and birthday cards. We'll take a look at our XML instance document:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <printOrder id="1219271208522">
        <notifications>
            <appointments>
                <appointment>
                    <apptType>Yearly Checkup</apptType>
                    <apptDate>2008-09-15T00:00:00-07:00</apptDate>
                    <owner>
                        <firstName>Joe</firstName>
                        <lastName>Outdoors</lastName>
                        <address>
                            <addressLine1>123 Whitewater Street</addressLine1>
                            <city>OurTown</city>
                            <state>CA</state>
                            <zip>90347</zip>
                            <zipExt>1234</zipExt>
                        </address>
                    </owner>
                    <pet>
                        <name>Honcho</name>
                        <species>Dog</species>
                    </pet>
                </appointment>
                <appointment>
                    <apptType>Well Mom Exam</apptType>
                    <apptDate>2008-09-12T00:00:00-07:00</apptDate>
                    <owner>
                        <firstName>Missy</firstName>
                        <lastName>Fairchild</lastName>
                        <address>
                            <addressLine1>456 Scenic Drive</addressLine1>
                            <city>West OurTown</city>
                            <state>CA</state>
                            <zip>90349</zip>
                            <zipExt>6789</zipExt>
                        </address>
                    </owner>
                    <pet>
                        <name>Miss Kitty</name>
                        <species>Cat</species>
                    </pet>
                </appointment>
            </appointments>
            <birthdays>
                <birthday>
                    <age>7</age>
                    <birthday>2000-09-07T00:00:00-07:00</birthday>
                    <owner>
                        <firstName>Violet</firstName>
                        <lastName>Flowers</lastName>
                        <address>
                            <addressLine1>22375 Willow Court</addressLine1>
                            <city>West OurTown</city>
                            <state>CA</state>
                            <zip>90349</zip>
                            <zipExt>6789</zipExt>
                        </address>
                    </owner>
                    <pet>
                        <name>Tom</name>
                        <species>Cat</species>
                    </pet>
                </birthday>
            </birthdays>
        </notifications>
    </printOrder>
    

    And here's another look at the main() method:

    	// The XML instance document received from NiceVet contains NiceVet's print order.
    	File input = new File("niceVet.xml");
    
    	// Create a JAXBContext for the weprintstuff.generated package.
    	JAXBContext ctx = JAXBContext.newInstance("weprintstuff.generated");
    
    	// Create an unmarshaller.
    	Unmarshaller unmarshaller = ctx.createUnmarshaller();
    
    	// Unmarshal the data in the XML instance document to a Java content tree made up of instances of the schema-derived classes.
    
    	JAXBElement printOrderElement = (JAXBElement)unmarshaller.unmarshal(new FileInputStream(input));
    	PrintOrder printOrder = (PrintOrder)printOrderElement.getValue();
    
    	// Print out the print items.	
            List<Appointment> appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
    	for (Appointment a : appointments) {
    		a.print();
    	}
    
    	List<Birthday> birthdays = printOrder.getPrintItems().getBirthdayHolder().getBirthdays();
    	for (Birthday b : birthdays) {
    		b.print();
    	}
    

    Check out our results: No one will ever miss an appointment or a birthday again.

    	Hi Joe!
    	Our records show that your dog Honcho has a Yearly Checkup appointment scheduled on 09/15/2008.
    	Please call us 24 hours prior to your appointment if you need to reschedule.
    	Sincerely, NiceVet
    
    	Hi Missy! Our records show that your cat Miss Kitty has a Well Mom Exam appointment scheduled on 09/12/2008.
    	Please call us 24 hours prior to your appointment if you need to reschedule.
    	Sincerely, NiceVet
    
    	Hi Violet!
    	Our records show that your cat Tom will turn 7 years old on 09/07.
    	Happy Birthday, Tom, from all of us at NiceVet!
    

    Running the Sample Application

    To run the sample application, download the sample code and unzip it. Navigate to the directory <sample-install-dir>/schema-to-java and generate the schema-derived classes as described in the section "Generating the Schema-Derived Classes."

    Launch the NetBeans IDE and select File > Open Project. In the Open Project dialog box, navigate to the directory where you unzipped the sample code and select the folder schema-to-java. Select the Open as Main Project check box. Click Open Project Folder. Right-click the schema-to-java project and select Run Project.

    Conclusion

    In Exchanging Data With XML and JAXB, Parts 1 and 2, we've learned how JAXB can facilitate the flow of data between business partners. With features that expedite XML processing on both ends of the exchange, JAXB can enable simpler, more productive integration between systems.

    References and Resources

    Sample code for this tip
    Java EE 5 Tutorial
    Kohsuke Kawaguchi's Blog - Kohsuke Kawaguchi is a staff engineer at Sun Microsystems, where he works on JAXB, among other projects.
    JSR 222: JAXB Specification

    About the Author

    Jennie Hall is a lead developer working in the financial sector.

    Creating an Ajax Autocompletion Textfield with Dynamic Faces

    This tutorial demonstrates the usage of the Woodstock JSF 1.2 Text Field component with Ajax functionality provided by the Project Dynamic Faces component library.

    by Patrick Keegan

    Most of the tutorials I've run across talk about creating applications that connect with a database that is managed from a server. This is appropriate for most business applications. However, sometimes you might want to create a more portable application that carries its own data with it, such as an application in which a user manages personal data.

    In this application, we will use NetBeans to create a simple desktop application to store info on your personal music collection. We will use Java DB, which has an embedded mode so that it can be packaged within the application. The application will also make use of the Beans Binding library and the Java Persistence API.

    Setting Up the Database

    First we will create a "connection". This isn't a connection to a real database but it gives us a place to create a database structure, which we can then use to generate application code.

    1. In NetBeans, open the Services window and expand the Drivers node.
    2. Right-click Java DB (Embedded) and choose Connect Using.
    3. embedded-connectusing.png
    4. For Database URL, enter jdbc:derby:Recordings;create=true.
    5. For User Name, enter APP.
    6. Enter whatever you wish the password and click OK. embedded-dbconnwiz.png

    Now we need to generate the database structure. We will do so by executing an SQL script that defines a single table and its columns.

    To generate the database structure:

    1. In the Services window, scroll down to the jdbc:derby:Recordings;create=true node, right-click, and choose Execute Command. embedded-executecommand.png
    2. Paste the following code into the editor.
      create table "APP".RECORD
      (
      	ARTIST VARCHAR(30) NOT NULL,
      	TITLE VARCHAR(30) NOT NULL PRIMARY KEY,
      	FORMAT VARCHAR(30) NOT NULL,
      	RATING INTEGER,
      	CONDITION VARCHAR(10),
      	COMMENTS VARCHAR(30)
      )
      
      
      
    3. Click the Run SQL button to execute the command.
    4. embedded-executescript.png
    5. Right-click the jdbc:derby:Recordings;create=true node and choose Refresh.
    6. Expand the node and then expand the Tables node.

    Creating the Application

    With the database structure set up, we can now use the Java Desktop Application project template to create a basic CRUD application based on that structure.

    1. Choose File | New Project.
    2. In the wizard select the Java | Java Desktop Application template. embedded-javadesktop.png
    3. In the Name and Location page of the wizard, select the Database Application skeleton. embedded-wiznamelocation.png
    4. In the Master Table page of the wizard, select the connection for the Recordings database. embedded-wizmastertable.png
    5. In the Detail Options page, click Finish.

    Once you complete the wizard, you have a basic CRUD application that should be ready to build and run. Here is how the application looks in the Design view of the GUI Builder:

    embedded-designview.png

    Building, Testing, and Distributing the Application

    Before building and running, make sure that you have all of the necessary libraries by expanding the project's Libraries node.

    embedded-libraries.png

    You should see libraries for the Swing Application Framework, Beans Binding, TopLink (which contains classes from the Java Persistence API), and Derby (Java DB). Depending on your setup, it might happen that TopLink and Derby are not added. If those libraries are not listed, you need to add the libraries manually. The TopLink library is available within the IDE's list of libraries. You can get the Derby JAR file from an installation of JDK 6, Glassfish, or from a Java DB or Derby standalone installation.

    To add the TopLink library:

    1. Right-click the Libraries node and choose Add Library.
    2. From the Available Libraries list, add TopLink Essentials.
    embedded-addlibrary.png

    To add derby.jar:

    1. Right-click the Libraries node and choose Add JAR/Folder.
    2. Navigate to your Derby/Java DB installation and select derby.jar. (I used the copy I found in C:\Program Files\glassfish-v2ur2\javadb\lib, but you might have it as part of your JDK.)

    To build and test run the project:

    1. Press F11 to build the project. (If this project is not your main project, right-click the project's node in the Projects window and choose Build.)
    2. Press F6 to run the project in the IDE. (If this project is not your main project, right-click the project's node in the Projects window and choose Run.)
    3. In the running application, add a few records and save them.
    embedded-runningapp.png

    The database is created and saved in your project directory. You can glimpse the database files that were created in the test run by opening the Files window and expanding the node for your project.

    embedded-fileswindow.png

    You'll notice that there is a sub-folder called Recordings (based on the database name) which contains the database files.

    Note: If you run the application directly from dist/Recordings.jar, the database once again will be empty. When you add records, the database files will be created in a location that depends conventions of your operating system. I run on Vista, and so my database files are created in the VirtualStore folder of my Windows user directory.

    You can distribute the application by zipping up the project's dist folder and giving it to the user. The dist folder contains the application's main JAR file, Recordings.jar, and the lib folder. The lib folder contains various libraries essential for the project, including derby.jar, which contains pretty much all of Java DB (which is just 2.2 MB).

    embedded-dist.png

    Once they unzip the file, they can run the Recordings.jar file, either by double-clicking it (if they have the .jar file extension associated with Java on their system) or by running it from the command line with the command java -jar Recordings.jar.

    So there you have it - a portable database application with no hand coding.

    Bonus Note on the Database Structure

    For purposes of quickly showing how to use Java DB as an embedded db, I used and over-simplified database structure, especially regarding the primary key. So that you can you can have multiple entries for the same artist, you might want to create an auto-generated identity field and make that the primary key instead. For example:

    create table "APP".RECORD
    (
        ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
        ARTIST VARCHAR(30) NOT NULL,
        TITLE VARCHAR(30) NOT NULL PRIMARY KEY,
        FORMAT VARCHAR(30) NOT NULL,
        RATING INTEGER,
        CONDITION VARCHAR(10),
        COMMENTS VARCHAR(30)
    );
    
    ALTER TABLE "APP".RECORD
        ADD CONSTRAINT CONTACTS2008_PK Primary Key (ID);
    

    Then after creating the project, you would need to modify the Recordings entity class by inserting the line @GeneratedValue(strategy=GenerationType.IDENTITY)@Id.

    ***********************

    Learning in Second Life

    Second Life (SL) is easy to misunderstand, and many people have the wrong idea that it is some kind of game environment, or a place where people just chat and act silly. On the contrary, Second Life has many places of learning from Science Friday, to Buddhist meditations, to technical seminars[Read More]

    ******************

    Virtual Classrooms in Geeksville

    Over the last few years I've been spending a lot of time online learning a whole lot of stuff. There is no better tool to teach us about computing, programming languages, and software than the computer itself. Of course, I realize it's not the computer but the site or the program, but virtual learning is hugely successful and for good reasons. And it's not limited to computer topics, thank goodness.[Read More]

    ********************

    Participate in MySQL-GlassFish Student Contest and Win $500

    Use MySQL database and GlassFish application server to develop a web application and write a review for...

    • A chance to win a grand prize of $500 in Visa debit card, and
    • Five chances to win a prize of $250 in Visa debit card


    By Robert Eckstein

    Contents

    - What Is Model-View-Controller (MVC)?
    - Interaction Between MVC Components
    - Modifying the MVC Design
    - Using the Modified MVC
    - Issues With Application Design
    - Common Swing Component Listeners
    - Conclusion
    - For More Information

    What Is Model-View-Controller (MVC)?

    If you've programmed with graphical user interface (GUI) libraries in the past 10 years or so, you have likely come across the model-view-controller (MVC) design. MVC was first introduced by Trygve Reenskaug, a Smalltalk developer at the Xerox Palo Alto Research Center in 1979, and helps to decouple data access and business logic from the manner in which it is displayed to the user. More precisely, MVC can be broken down into three elements:

    • Model - The model represents data and the rules that govern access to and updates of this data. In enterprise software, a model often serves as a software approximation of a real-world process.
    • View - The view renders the contents of a model. It specifies exactly how the model data should be presented. If the model data changes, the view must update its presentation as needed. This can be achieved by using a push model, in which the view registers itself with the model for change notifications, or a pull model, in which the view is responsible for calling the model when it needs to retrieve the most current data.
    • Controller - The controller translates the user's interactions with the view into actions that the model will perform. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in an enterprise web application, they appear as GET and POST HTTP requests. Depending on the context, a controller may also select a new view -- for example, a web page of results -- to present back to the user.
    Although different architectures allow the three components to interact in different ways, Figure 1 shows a common implementation of the MVC design pattern, as shown in the Sun BluePrints Catalog.

    Figure1: A Common MVC Implementation
    Figure1. A Common MVC Implementation

    Interaction Between MVC Components

    This section will take a closer look at one way to implement Figure 1 in the context of an application in the Java Platform, Standard Edition 6 (Java SE 6). Once the model, view, and controller objects are instantiated, the following occurs:

    1. The view registers as a listener on the model. Any changes to the underlying data of the model immediately result in a broadcast change notification, which the view receives. This is an example of the push model described earlier. Note that the model is not aware of the view or the controller -- it simply broadcasts change notifications to all interested listeners.
    2. The controller is bound to the view. This typically means that any user actions that are performed on the view will invoke a registered listener method in the controller class.
    3. The controller is given a reference to the underlying model.

    Once a user interacts with the view, the following actions occur:

    1. The view recognizes that a GUI action -- for example, pushing a button or dragging a scroll bar -- has occurred, using a listener method that is registered to be called when such an action occurs.
    2. The view calls the appropriate method on the controller.
    3. The controller accesses the model, possibly updating it in a way appropriate to the user's action.
    4. If the model has been altered, it notifies interested listeners, such as the view, of the change. In some architectures, the controller may also be responsible for updating the view. This is common in Java technology-based enterprise applications.

    Figure 2 shows this interaction in more detail.

    Figure 2: A Java SE Application Using MVC
    Figure 2. A Java SE Application Using MVC

    As this article mentioned earlier, the model does not carry a reference to the view but instead uses an event-notification model to notify interested parties of a change. One of the consequences of this powerful design is that the many views can have the same underlying model. When a change in the data model occurs, each view is notified by a property change event and can update itself accordingly. For example, Figure 3 shows two views that use the same data model.


    Figure 3: Multiple Views Using the Same Model
    Figure 3. Multiple Views Using the Same Model

    Modifying the MVC Design

    A more recent implementation of the MVC design places the controller between the model and the view. This design, which is common in the Apple Cocoa framework, is shown in Figure 4.


    Figure 4: An MVC Design Placing the Controller Between the Model and the View
    Figure 4. An MVC Design Placing the Controller Between the Model and the View

    The primary difference between this design and the more traditional version of MVC is that the notifications of state changes in model objects are communicated to the view through the controller. Hence, the controller mediates the flow of data between model and view objects in both directions. View objects, as always, use the controller to translate user actions into property updates on the model. In addition, changes in model state are communicated to view objects through an application's controller objects.

    Thus, when all three components are instantiated, the view and the model will both register with the controller. Once a user interacts with the view, the events are nearly identical:

    1. The view recognizes that a GUI action -- for example, pushing a button or dragging a scroll bar -- has occurred, using a listener method that is registered to be called when such an action occurs.
    2. The view calls the appropriate method on the controller.
    3. The controller accesses the model, possibly updating it in a way appropriate to the user's action.
    4. If the model has been altered, it notifies interested listeners of the change. However, in this case, the change is sent to the controller.

    Why adopt this design? Using this modified MVC helps to more completely decouple the model from the view. In this case, the controller can dictate the model properties that it expects to find in one or more models registered with the controller. In addition, it can also provide the methods that effect the model's property changes for one or more views that are registered with it.

    Using the Modified MVC

    This section of the article shows you how to put this design into practice, starting with the model. Suppose that you want to paint some text using a simple display model with five properties. Code Sample 1 shows a simple component that you can use to create such a model.

    Code Sample 1

    public class TextElementModel extends AbstractModel
    {
    
        private String text;
        private Font font;
        private Integer x;
        private Integer y;
        private Integer opacity;
        private Integer rotation;
    
    
        /**
         * Provides the means to set or reset the model to
         * a default state
         */
        public void initDefault() {
    
            setOpacity(89);
            setRotation(0);
            setText("Sample Text");
            setFont(new Font("Arial", Font.BOLD, 24));
            setX(50);
            setY(50);
    
        }
    
        //  Accessors
    
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
    
            String oldText = this.text;
            this.text = text;
    
            firePropertyChange(
                DefaultController.ELEMENT_TEXT_PROPERTY,
                oldText, text);
        }
    
        public Font getFont() {
            return font;
        }
    
        public void setFont(Font font) {
    
            Font oldFont = this.font;
            this.font = font;
    
            firePropertyChange(
                DefaultController.ELEMENT_FONT_PROPERTY,
                oldFont, font);
        }
    
        //  The remaining accessors for properties are omitted.
    
    }
    

    Note that the rest of the accessors follow the standard JavaBeans model, although they are omitted in Code Sample 1. For reference, Code Sample 2 shows the underlying AbstractModel class, which simply uses the javax.beans.PropertyChangeSupport class to register, deregister, and notify interested listeners of changes to the model.

    Code Sample 2

    public abstract class AbstractModel
    {
    
        protected PropertyChangeSupport propertyChangeSupport;
    
        public AbstractModel()
        {
            propertyChangeSupport = new PropertyChangeSupport(this);
        }
    
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }
    
        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }
    
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
            propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
        }
    
    
    }
    

    The Controller

    Between the model and view lies the controller. First, take a look at the code for the abstract controller superclass, as shown in Code Sample 3.

    Code Sample 3

    public abstract class AbstractController implements PropertyChangeListener {
    
        private ArrayList registeredViews;
        private ArrayList registeredModels;
    
        public AbstractController() {
            registeredViews = new ArrayList();
            registeredModels = new ArrayList();
        }
    
    
        public void addModel(AbstractModel model) {
            registeredModels.add(model);
            model.addPropertyChangeListener(this);
        }
    
        public void removeModel(AbstractModel model) {
            registeredModels.remove(model);
            model.removePropertyChangeListener(this);
        }
    
        public void addView(AbstractViewPanel view) {
            registeredViews.add(view);
        }
    
        public void removeView(AbstractViewPanel view) {
            registeredViews.remove(view);
        }
    
    
        //  Use this to observe property changes from registered models
        //  and propagate them on to all the views.
    
    
        public void propertyChange(PropertyChangeEvent evt) {
    
            for (AbstractViewPanel view: registeredViews) {
                view.modelPropertyChange(evt);
            }
        }
    
    
        /**
         * This is a convenience method that subclasses can call upon
         * to fire property changes back to the models. This method
         * uses reflection to inspect each of the model classes
         * to determine whether it is the owner of the property
         * in question. If it isn't, a NoSuchMethodException is thrown,
         * which the method ignores.
         *
         * @param propertyName = The name of the property.
         * @param newValue = An object that represents the new value
         * of the property.
         */
        protected void setModelProperty(String propertyName, Object newValue) {
    
            for (AbstractModel model: registeredModels) {
                try {
    
                    Method method = model.getClass().
                        getMethod("set"+propertyName, new Class[] {
                                                          newValue.getClass()
                                                      }
    
    
                                 );
                    method.invoke(model, newValue);
    
                } catch (Exception ex) {
                    //  Handle exception.
                }
            }
        }
    
    
    }
    

    The AbstractController class contains two ArrayList objects, which are used to keep track of the models and views that are registered. Note that whenever a model is registered, the controller also registers itself as a property change listener on the model. This way, whenever a model changes its state, the propertyChange() method is called and the controller will pass this event on to the appropriate views.

    The final method, setModelProperty(), employs some magic to get its work done. In order to keep the models completely decoupled from the controller, the code samples in this article have employed the Java Reflection API. In this case, when this method is called with the desired property name, you hunt through the registered models to determine which one contains the appropriate method. Once you find it, you invoke the method using the new value. If the method is not called, the getMethod() will throw a NoSuchMethodException, which the exception handler ignores, allowing the for- loop to continue.

    Code Sample 4 shows the source code for the default controller class. This class consists of only property constants and methods called by the GUI event listeners of the view.

    Code Sample 4

    public class DefaultController extends AbstractController
    {
    
        public static final String ELEMENT_TEXT_PROPERTY = "Text";
        public static final String ELEMENT_FONT_PROPERTY = "Font";
        public static final String ELEMENT_X_PROPERTY = "X";
        public static final String ELEMENT_Y_PROPERTY = "Y";
        public static final String ELEMENT_OPACITY_PROPERTY = "Opacity";
        public static final String ELEMENT_ROTATION_PROPERTY = "Rotation";
    
        //  Code omitted
    
        public void changeElementText(String newText) {
            setModelProperty(ELEMENT_TEXT_PROPERTY, newText);
        }
    
        public void changeElementFont(Font newFont) {
            setModelProperty(ELEMENT_FONT_PROPERTY, newFont);
        }
    
        public void changeElementXPosition(int newX) {
            setModelProperty(ELEMENT_X_PROPERTY, newX);
        }
    
        public void changeElementYPosition(int newY) {
            setModelProperty(ELEMENT_Y_PROPERTY, newY);
        }
    
        public void changeElementOpacity(int newOpacity) {
            setModelProperty(ELEMENT_OPACITY_PROPERTY, newOpacity);
        }
    
        public void changeElementRotation(int newRotation) {
            setModelProperty(ELEMENT_ROTATION_PROPERTY, newRotation);
        }
    
    }
    

    The View

    This example will have two views displaying the data from the model: a property-editor view and a graphical page view. Both of these are implementations of a JPanel, inserted into either a JDialog or JFrame. The dialog box allows the user to update the values of the model, and the frame panel simply reflects the changes as the final textual display. The author of this article built this example using the NetBeans Swing GUI Builder, formerly referred to as Project Matisse, to design the GUI forms.

    Code Sample 5 shows the source code for the property-editor view, the more interesting of the two. The first section is simply devoted to initialization of the components, which for the most part was automatically generated by the NetBeans integrated development environment (IDE) in the initComponents() method. All of this section is omitted but is present in the downloadable code. Any other initialization that you need to perform -- in this case, creating custom models for JSpinner and JSlider objects or adding DocumentListeners to the JTextField components -- is handled in the localInitialization() method.

    Code Sample 5

    public PropertiesViewPanel(DefaultController controller) {
    
            this.controller = controller;
    
            initComponents();
            localInitialization();
    
        }
    
        // ‹editor-fold defaultstate="collapsed" desc=" Local Initialization "›
    
        /**
         * Used to provide local initialization of Swing components
         * outside of the NetBeans automatic code generator
         */
        public void localInitialization() {
    
            opacitySpinner.setModel(new SpinnerNumberModel(100, 0, 100, 1));
            opacitySlider.setModel(new DefaultBoundedRangeModel(100, 0, 0, 100));
    
            rotationSpinner.setModel(new SpinnerNumberModel(0, -180, 180, 1));
            rotationSlider.setModel(new DefaultBoundedRangeModel(0, 0, -180, 180));
    
            text.getDocument().addDocumentListener(new DocumentListener() {
    
                public void insertUpdate(DocumentEvent e) {
                    textDocumentChanged(e);
                }
    
                public void removeUpdate(DocumentEvent e) {
                    textDocumentChanged(e);
                }
    
                public void changedUpdate(DocumentEvent e) {
                    textDocumentChanged(e);
                }
    
            });
    
        }
    
        // ‹/editor-fold›
    

    Note that the automatically generated NetBeans IDE code folds in the source code so that the developer can collapse each of these sections when it is not needed:

    // ‹editor-fold defaultstate="collapsed" desc=" Local Initialization "›
    // ‹/editor-fold›
    

    If you're using the NetBeans IDE, this practice is highly recommended.

    The second section of the PropertiesViewPanel class deals exclusively with the model. In Code Sample 6, a modelPropertyChange() method is called by the controller whenever the model reports a state change.

    Code Sample 6

    // ‹editor-fold defaultstate="collapsed" desc=" Model Event Handling Code "›
    
        public void modelPropertyChange(final PropertyChangeEvent evt) {
    
            if (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_X_PROPERTY)) {
                String newStringValue = evt.getNewValue().toString();
                xPositionTextField.setText(newStringValue);
            } else if
               (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_Y_PROPERTY)) {
                String newStringValue = evt.getNewValue().toString();
                yPositionTextField.setText(newStringValue);
            } else if
               (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_OPACITY_PROPERTY)) {
                int newIntegerValue = (Integer)evt.getNewValue();
                opacitySpinner.setValue(newIntegerValue);
                opacitySlider.setValue(newIntegerValue);
            } else if
                (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_ROTATION_PROPERTY)) {
                int newIntegerValue = (Integer)evt.getNewValue();
                rotationSpinner.setValue(newIntegerValue);
                rotationSlider.setValue(newIntegerValue);
            } else if
               (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_TEXT_PROPERTY)) {
                String newStringValue = evt.getNewValue().toString();
                text.setText(newStringValue);
            } else if
               (evt.getPropertyName().equals(
                       DefaultController.ELEMENT_FONT_PROPERTY)) {
                Font f = (Font)evt.getNewValue();
                String fontString = f.getFontName() + " " + f.getSize();
                font.setText(fontString);
                currentFont = f;
            }
    
            //  Remainder of the code omitted
    
        }
    
        // ‹/editor-fold›
    

    Again, this code sample omits portions of the code that are similar to the sections shown.

    The final portion consists of the GUI event listeners. Code Sample 7 contains listeners that are called whenever GUI events occur, such as pushing the Change Font button or the Opacity spinner buttons, or resetting the text in any of the text fields. These are largely event listeners that most Swing developers are already familiar with. If you're using the NetBeans IDE, you'll see that the IDE can automatically generate many of these using the GUI developer.

    Code Sample 7

     // ‹editor-fold defaultstate="collapsed" desc=" GUI Event Handling Code "›
    
        //  Code omitted
    
        private void yPositionTextFieldFocusLost(java.awt.event.FocusEvent evt) {
            try {
                controller.changeElementYPosition(
                    Integer.parseInt(yPositionTextField.getText()));
            } catch (Exception e) {
                //  Handle exception.
            }
        }
    
        private void yPositionTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
            try {
                controller.changeElementYPosition(
                    Integer.parseInt(yPositionTextField.getText()));
            } catch (Exception e) {
                //  Handle exception.
            }
        }
    
        //  Code omitted -- code for xPosition
        //  is nearly the same as for yPosition.
    
        private void changeFontButtonActionPerformed(java.awt.event.ActionEvent evt) {
    
            JFontChooserDialog fontChooser = new
                JFontChooserDialog((Dialog)this.getTopLevelAncestor());
            fontChooser.setSelectedFont(currentFont);
            fontChooser.setVisible(true);
    
            Font returnedFont = fontChooser.getSelectedFont();
            if (returnedFont != null) {
                controller.changeElementFont(returnedFont);
            }
        }
    
        private void opacitySliderStateChanged(javax.swing.event.ChangeEvent evt) {
            controller.changeElementOpacity((int)opacitySlider.getValue());
        }
    
        private void rotationSliderStateChanged(javax.swing.event.ChangeEvent evt) {
            controller.changeElementRotation((int)rotationSlider.getValue());
        }
    
        private void opacitySpinnerStateChanged(javax.swing.event.ChangeEvent evt) {
            controller.changeElementOpacity((Integer)opacitySpinner.getValue());
        }
    
        private void rotationSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {
            controller.changeElementRotation((Integer)rotationSpinner.getValue());
        }
    
        private void textDocumentChanged(DocumentEvent evt) {
    
            Document document = evt.getDocument();
            try {
                controller.changeElementText(document.getText(0,
                document.getLength()));
            } catch (BadLocationException ex) {
                //  Handle exception.
            }
        }
    
        // ‹/editor-fold›
    

    Issues With Application Design

    Once the application is up and running, you immediately run into a problem. Consider the following chain of events:

    1. One of the Swing components in the view receives a change, presumably from the user action.
    2. The appropriate controller method is called.
    3. The model is updated. It notifies the controller of its property change.
    4. The view receives a change event from the controller and attempts to reset the value of the appropriate Swing components.
    5. The appropriate controller method is called, and the model is updated again.

    At this point, any of three different scenarios can occur, depending on what Swing component you use and how robust your model is.

    • The Swing component that prompted the initial change refuses to update itself the second time, noting that its property state cannot be updated again while it is in the process of notifying listeners of the initial state change. This primarily occurs when you use Swing text components.
    • The model notes that the value of the second update matches that of the first, its current value, and refuses to send a change notification. This is always a safe programming practice, and it automatically occurs if you use the PropertyChangeSupport class provided in the java.beans package. However, it does not keep the model from receiving a redundant update.
    • No safeguards are in place on either the model or the Swing component, and the program enters an infinite loop.

    This issue occurs because the Swing components are autonomous. For example, what happens if the user presses the up arrow of the JSpinner component in PropertiesViewPanel, incrementing the spinner's value by one? After the value is updated, a GUI event listener method that is listening for value changes is called, opacitySpinnerStateChanged(), which in turn calls the controller and then updates the appropriate property in the model.

    With a traditional MVC design, the view would still contain the previous value, and the change in the model would update the view to the current value. However, there is no need to update the Swing component because it has already reset itself to the correct value -- it did so before it even passed an event to the controller.

    How do you get around this? One way is to write a mechanism that tells the model or the controller not to propagate a change notification under these circumstances, but this is not a good idea. Remember that more than one view may be listening for changes on the model. If you shut down the change notification for the model, no other listeners, including other views, will be notified of the change. In addition, other components in the same view may rely on the property change notification, with a slider and spinner combination, for example.

    Ideally, each Swing component would be aware of its current value and the value that the view is trying to set it to. If they match, no change notifications will be sent. However, some Swing components include this logic, and others do not. One possible solution is to check the incoming changed value of the model against the current value stored in the Swing component. If they are identical, there is no need to reset the value of the Swing component.

    Code Sample 8 shows an update of the modelPropertyChange() method to demonstrate this approach.

    Code Sample 8

    public void modelPropertyChange(final PropertyChangeEvent evt) {
    
            if (evt.getPropertyName().equals(DefaultController.ELEMENT_X_PROPERTY)) {
    
                String newStringValue = evt.getNewValue().toString();
                if (!xPositionTextField.getText().equals(newStringValue))
                    xPositionTextField.setText(newStringValue);
    
            }
    
            //  Remaining code omitted
    
        }
    

    The final example, which uses two delegate views, is shown in Figure 5. The second delegate makes use of the Java 2D libraries to display the text, which is beyond the scope of this article. However, the source code is relatively easy to follow and is included in the downloadable source code.

    Figure 5. Both Views Attached to a Single Model
    Figure 5. Both Views Attached to a Single Model

    Common Swing Component Listeners

    As this article has shown throughout, part of the initialization of each delegate or controller requires you to subscribe to various Swing component events. However, individual Swing components can often generate multiple event types. Table 1 presents some common listener methods.

    Table 1. Common Swing Event Listener Methods
    Event to Monitor
    Swing Event Listener Method
    JButton pressed; JCheckBox pressed; JRadioButton pressed; JToggleButton toggled.
    JButton.addActionListener(java.awt.event.ActionListener)
    JSpinner value changed.
    JSpinner.addChangeListener(javax.swing.event.ChangeListener)
    JTextField, JFormattedTextField, JPasswordField or JTextArea character(s) are added, changed, or deleted.
    JTextField.getDocument().addDocumentListener(javax.swing.event.DocumentListener)
    JTextField return button is pressed, or focus switches to another component.
    JTextField.addActionListener(java.awt.event.ActionListener)
    JComboBox new entry is selected. from list.
    JComboBox.addActionListener(java.awt.event.ActionListener)
    JComboBox editor (typically a text field) characters are added, changed, or deleted.
    JTextField editor = ((JTextField)comboBox.getEditor().getEditorComponent());
    editor.getDocument().addDocumentListener(javax.swing.event.DocumentListener)
    JComboBox return button is pressed.
    JComboBox.addActionListener(java.awt.event.ActionListener)
    JComboBox pop-up menu is about to become visible, invisible, or be cancelled without a selection.
    JComboBox.addPopupMenuListener(javax.swing.event.PopupMenuListener)
    JList new entry is selected.
    JList.addListSelectionListener(javax.swing.event.ListSelectionListener)
    JTabbedPane new tab is selected.
    JTabbedPane.addChangeListener(javax.swing.event.ChangeListener)
    JScrollBar adjustment is made.
    JScrollBar.addAdjustmentListener(java.awt.event.AdjustmentListener)
    JScrollPane adjustment is made.
    JScrollPane.getHorizontalScrollBar().addAdjustmentListener(java.awt.event.AdjustmentListener)
    JScrollPane.getVerticalScrollBar().addAdjustmentListener(java.awt.event.AdjustmentListener)
    JPopupMenu is about to become visible, invisible, or be cancelled without a selection.
    JPopupMenu.addPopupMenuListener(javax.swing.event.PopupMenuListener)
    JMenu is about to be become visible or invisible, or be cancelled without a selection.
    JMenu.addMenuListener(javax.swing.event.MenuListener)
    JMenuItem (in standard or pop-up menu) is selected.
    JMenuItem.addActionListener(java.awt.event.ActionListener)
    JSlider value is changed.
    JSlider.addChangeListener(javax.swing.event.ChangeListener)


    Conclusion

    MVC is one of the staples of any GUI programmer's toolkit. This article has shown how to implement a variation of the MVC design using Java SE and the Swing libraries. In addition, it has demonstrated some common issues that programmers may face when using MVC, as well as listed common Swing component events that any Java platform programmer can use when creating a view.


    For More Information
    Java Web Start provides the power to launch full-featured applications with a single click. Users can download and launch applications, such as a complete spreadsheet program or an Internet chat client, without going through complicated installation procedures.

    With Java Web Start, the user can launch a Java application by clicking a link in a Web page. The link points to a JNLP file, which instructs Java Web Start to download, cache and run the application.

    Java Web Start provides Java developers and users with many deployment advantages:

    • With Java Web Start, you can place a single Java application on a Web server for deployment to a wide variety of platforms, including Windows 2003/Vista/2000/XP, Linux, and SolarisTM
    • Java Web Start supports multiple, simultaneous versions of the Java Standard Edition platform. Specific applications can request specific Java versions without conflicting with the different needs of other applications. Java Web Start automatically downloads and installs the correct version of the Java platform as necessary based on the application's needs and the user's environment.
    • Users can launch a Java Web Start application independently of a Web browser. The user can be off-line, or unable to access the browser. Desktop shortcuts can also launch the application, providing the user with the same experience as a native application.
    • Java Web Start takes advantage of the inherent security of the Java platform. By default, applications have restricted access to local disk and network resources. Users can safely run applications from sources that are not trusted.
    • Applications launched with Java Web Start are cached locally, for improved performance.
    • Java Web Start provides limited support for applets through its built-in applet viewer. However, this is not intended to be a full- scale applet environment, such as the one provided by Java Plug-in. Java Web Start's applet viewer has certain limitations; for example, you cannot specify class files as resources, and it does not accept policy files.

    In Java Version 1.4.2 and beyond, Java Web Start is installed as part of the JRE. Users do not have to install it separately or perform additional tasks to use Java Web Start applications.

    Read the rest of this lesson . . .

    Also see:

    New to Java Programming Center

    Young Developers

    The Java Tutorial

    Get Started with Java Programming in Facebook

     ******

     

    Introducing NetBeans IDE 6.5 Beta! Development Simplified. 
    Rapidly create web, enterprise, desktop, and mobile applications with 
    Java, C/C++ , JavaScript, Ruby, Groovy, and now PHP.
    

    ******

    Wombat Classes Basics (Young Developers Series, Part 2)

    Learn where Java code is written and saved, how classes relate to one another, and how to use the Greenfoot code editor.

    by Jennie Hall

    In this tip, you'll learn how to to use the Java Architecture for XML Binding (JAXB) in Java SE 6 to exchange XML data between systems without having to delve into the specifics of XML processing. Among other key improvements, JAXB 2.0 offers support for binding Java objects to XML via the use of annotations. This feature allows you to generate XML data from your application simply by annotating your existing object model.

    What's JAXB?

    JAXB simplifies the use of XML data in Java applications by shielding you and your code from the low-level details of working with XML. Essentially, JAXB allows you to move easily back-and-forth between XML and Java. A JAXB implementation supplies a schema compiler, which takes in an XML schema and generates Java classes which map to that schema. Data from XML documents which are instances of the schema can be bound automatically to the generated classes by JAXB's binding runtime framework. This is called unmarshalling. Once unmarshalled, content can be manipulated or modified in Java as needed. JAXB can also write (marshal) data from Java objects to an XML instance document. JAXB optionally performs validation of content as part of these operations.

    In addition to the schema compiler, a JAXB implementation also provides a schema generator, which looks at annotations on Java classes and generates a corresponding XML schema. This feature is new to JAXB 2.0.

    The Sample Application

    A veterinary office wants to send notices to its clients reminding them of their pets' upcoming appointments. Because they are nice folks, they also like to send a birthday card to an owner on the pet's birthday. The veterinary office, NiceVet, contracts with a service provider, WePrintStuff, to do their printing and mailing for them.

    NiceVet already has an application which maintains information about the animals under NiceVet's care and their owners. Here's a diagram of NiceVet's existing object model:


    NiceVet needs a way to get the necessary notification data to WePrintStuff for processing without spending a lot of time and money modifying their current application.

    Generating the XML

    It's time to annotate our object model so we can generate some XML data for the printing and mailing service. Looking at NiceVet's object model, we see that the PrintOrder class holds the information about upcoming events, and thus makes sense as the root element of the data we want to send. Let's add the @XmlRootElement annotation to the PrintOrder class. This will establish printOrder as the root element of our generated XML.

    	import javax.xml.bind.annotation.XmlRootElement;
    
    	// the root element of our generated XML
    	@XmlRootElement(name = "printOrder")
    	public class PrintOrder {
    
    	    private long id;
    	    private List<Event> events;

    Let's add some more annotations:

    	import javax.xml.bind.annotation.XmlRootElement;
    	import javax.xml.bind.annotation.XmlType;
    	import javax.xml.bind.annotation.XmlAccessorType;
    	import javax.xml.bind.annotation.XmlAccessType;
    	import javax.xml.bind.annotation.XmlAttribute;
    	import javax.xml.bind.annotation.XmlElement;
    	import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    	// the root element of our generated XML
    	@XmlRootElement(name = "printOrder")
    	// maps this class to a generated schema type
    	@XmlType(name = "PrintOrderType", propOrder = {"events"})
    	// bind all non-static, non-transient fields
    	// to XML unless annotated with @XmlTransient
    	@XmlAccessorType(XmlAccessType.FIELD)
    	public class PrintOrder {
    
    	    // maps this field to an XML attribute
    	    @XmlAttribute(required = true)
    	    private long id;
    	    // custom adapter maps this field to a type,
    
    	    // NotificationsType, which makes it easy to
    	    // generate the desired XML
    	    @XmlJavaTypeAdapter(value=EventAdapter.class)   
    	    @XmlElement(name = "notifications")
    	    private List<Event> events;

    @XmlType maps the PrintOrder class to a generated schema type named PrintOrderType. The @XmlAccessorType(XmlAccessType.FIELD) annotation tells JAXB to bind all non-static, non-transient fields to XML unless annotated with @XmlTransient, which prevents the mapping of a field or property. With the XmlAccessType.FIELD setting, getter/setter pairs are not bound to XML unless explicitly annotated. The default setting is XmlAccessType.PUBLIC_MEMBER (all public fields and getter/setter pairs are bound unless otherwise annotated); other settings are XmlAccessType.PROPERTY and XmlAccessType.NONE.

    Moving down the code listing, we see that the field id maps to an XML attribute on the PrintOrderType element. Some kind of identifier on the print order is required, and we've annotated the id field accordingly.

    The PrintOrder class has a list of events which contains both appointments and birthdays. The annotation @XmlJavaTypeAdapter tells JAXB that we are going to use a custom adapter, EventAdapter, to help us map this Java construct to XML. To support this annotation, we need to write an adapter class which extends XmlAdapter and overrides its abstract marshal and unmarshal methods.

    	public class EventAdapter extends XmlAdapter<NotificationsType, List<Event>> {
    
    	    // adapt original Java construct to a type, NotificationsType,
    	    // which we can easily map to the XML output we want
    	    public NotificationsType marshal(List<Event> events) throws Exception {
    	        List<Appointment> appointments = new ArrayList<Appointment>();
    	        List<Birthday> birthdays = new ArrayList<Birthday>();
    	        
    	        for (Event e : events) {
    	            if (e instanceof Appointment) {
    	                appointments.add((Appointment)e);
    	            } else {
    	                birthdays.add((Birthday)e);              
    	            }
    	        }        
    	        return new NotificationsType(appointments, birthdays);
    	    }
    
    	    // reverse operation: map XML type to Java
    	    public List<Event> unmarshal(NotificationsType notifications) throws Exception { ... }
            

    EventAdapter's marshal method takes the original Java construct, List<Event> events, and converts it to a type which maps more easily to the XML output we want. Let's take a look at NotificationsType:

    	import javax.xml.bind.annotation.XmlElementWrapper;
    	import javax.xml.bind.annotation.XmlElement;
    	import java.util.List;
    
    	public class NotificationsType {
    	    
    	    // produce a wrapper XML element around this collection
    	    @XmlElementWrapper(name = "appointments")
    	    // maps each member of this list to an XML element named appointment
    	    @XmlElement(name = "appointment")
    	    //private List<Appointment> appointments;
    	    private List<Appointment> appointments;
    	    // produce a wrapper XML element around this collection
    	    @XmlElementWrapper(name = "birthdays")
    	    // maps each member of this list to an XML element named birthday
    	    @XmlElement(name = "birthday")
    	    //private List<Birthday> birthdays;
    	    private List<Birthday> birthdays;
    	    
    	    public NotificationsType() {}
    	    
    	    public NotificationsType(List<Appointment> appointments, List<Birthday> birthdays) {
    	        this.appointments = appointments;
    	        this.birthdays = birthdays;
    	    }		
    

    The @XmlElementWrapper annotation creates a wrapper XML element around each collection, and the @XmlElement annotation maps each member of the collection to an XML element of the appropriate type. Combined with the @XmlElement(name = "notifications") annotation on PrintOrder.events, what we end up with will look something like this:

    	<printOrder>
    		<notifications>
    			<appointments>
    				<appointment>
    					...
    				</appointment>
    			</appointments>
    			<birthdays>
    				<birthday>
    					...
    				</birthday>
    			</birthdays>
    		</notifications>
    	</printOrder>
    

    Another annotation worth mentioning lies in the abstract base class Event (listing below), from which subclasses Appointment and Birthday inherit. This inheritance hierarchy won't hold much meaning for our service provider, WePrintStuff, so we'll eliminate it with the @XmlTransient annotation on Event. We still need fields owner and pet, however, so we annotate them with @XmlElement(required = true).

    	import javax.xml.bind.annotation.XmlElement;
    	import javax.xml.bind.annotation.XmlTransient;
    
    	// no need to capture this inheritance hierarchy in XML
    	@XmlTransient
    	public abstract class Event {
    
    	    @XmlElement(required = true)
    	    private Owner owner;
    	    @XmlElement(required = true)
    	    private Pet pet;
    
    	    public Event() {}
    	            
    	    public Event(Owner owner, Pet pet) {
    	       this.owner = owner;
    	       this.pet = pet;
    	    }
    

    When objects of type Birthday and Appointment are marshalled to XML, they will include all the relevant data from their supertype, Event. Take a look at the listing below for the Birthday class:

    	@XmlType(name = "BirthdayType", propOrder = {"age", "birthday", "owner", "pet"})
    	@XmlAccessorType(XmlAccessType.FIELD)
    	public class Birthday extends Event {
    
    	    @XmlElement(required = true)
    	    private int age;
    	    
    	    public Birthday() {}
    	    
    	    public Birthday(Owner owner, Pet pet) {
    	        super(owner, pet);
    	        this.age = this.calculateAge();
    	    }
    
    	    @XmlElement(name = "birthday", required = true)
    	    public Date getBirthday() {
    	        return this.getPet().getDateOfBirth();
    	    }
    

    @XmlType.propOrder specifies the order in which content is marshalled and unmarshalled. This order would otherwise be unspecified due to the nature of Java reflection. Alternatively, you can impose an order with the @XmlAccessorOrder annotation. As mentioned in the Java Tutorial, imposing an order improves application portability across JAXB implementations.

    Although the field dateOfBirth is actually on the Pet class, it makes more sense in terms of our XML representation if this data is organized as an element under the birthday element. We can achieve this without a dateOfBirth field on the Birthday class by annotating the getBirthday() method, which delegates to Pet.

    On a related note, WePrintStuff doesn't need to do any additional processing with the dates NiceVet sends them; they just need to locate the correct notification template and print the information out. As we saw earlier with the events list on the PrintOrder class, we can supply a custom adapter to get the desired XML output. This time, however, we'll specify the adapter through a package-level annotation. The adapter will take in all java.util.Date instances and output nicely formatted Strings. The package-level annotation goes in the package-info.java file (located in the vet package):

    	// every java.util.Date class in the vet package should be
    	// processed by DateAdapter
    	@XmlJavaTypeAdapter(value=DateAdapter.class, type=Date.class)
    	package vet;
    
    	import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    	import java.util.Date;
        

    Although JAXB can handle marshalling java.util.Date to XML in a default manner on its own, we're telling JAXB to use an alternative, customized mapping which better suits our purposes. We implement the adapter in much the same way as above:

    	import java.util.Date;
    	import java.text.SimpleDateFormat;
    	import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    	public class DateAdapter extends XmlAdapter<String, Date> {
    
    		// the desired format
    	    private String pattern = "MM/dd/yyyy";
    	    
    	    public String marshal(Date date) throws Exception {
    	        return new SimpleDateFormat(pattern).format(date);
    	    }
    	    
    	    public Date unmarshal(String dateString) throws Exception {
    	        return new SimpleDateFormat(pattern).parse(dateString);
    	    }	
    	
      

    The annotations on the other classes in the object model are similar to what we've seen so far; take a peek at the sample code included with this tip to see exactly what's going on in the other classes.

    We've finished annotating NiceVet's object model and we're ready to generate some XML. If we run the sample application, we should see an XML instance document something like the following listing. The document, niceVet.xml, is located in the root directory of the java-to-schema project.

    	<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    	<printOrder id="1218226109781">
    	    <notifications>
    	        <appointments>
    	            <appointment>
    	                <apptType>Yearly Checkup</apptType>
    	                <apptDate>09/15/2008</apptDate>
    	                <owner>
    	                    <firstName>Joe</firstName>
    	                    <lastName>Outdoors</lastName>
    	                    <address>
    	                        <addressLine1>123 Whitewater Street</addressLine1>
    	                        <city>OurTown</city>
    	                        <state>CA</state>
    	                        <zip>90347</zip>
    	                        <zipExt>1234</zipExt>
    	                    </address>
    	                </owner>
    	                <pet>
    	                    <name>Honcho</name>
    	                    <species>Dog</species>
    	                </pet>
    	            </appointment>
    	            <appointment>
    	                <apptType>Well Mom Exam</apptType>
    	                <apptDate>09/12/2008</apptDate>
    	                <owner>
    	                    <firstName>Missy</firstName>
    	                    <lastName>Fairchild</lastName>
    	                    <address>
    	                        <addressLine1>456 Scenic Drive</addressLine1>
    	                        <city>West OurTown</city>
    	                        <state>CA</state>
    	                        <zip>90349</zip>
    	                        <zipExt>6789</zipExt>
    	                    </address>
    	                </owner>
    	                <pet>
    	                    <name>Miss Kitty</name>
    	                    <species>Cat</species>
    	                </pet>
    	            </appointment>
    	        </appointments>
    	        <birthdays>
    	            <birthday>
    	                <age>7</age>
    	                <birthday>09/07/2000</birthday>
    	                <owner>
    	                    <firstName>Violet</firstName>
    	                    <lastName>Flowers</lastName>
    	                    <address>
    	                        <addressLine1>22375 Willow Court</addressLine1>
    	                        <city>West OurTown</city>
    	                        <state>CA</state>
    	                        <zip>90349</zip>
    	                        <zipExt>6789</zipExt>
    	                    </address>
    	                </owner>
    	                <pet>
    	                    <name>Tom</name>
    	                    <species>Cat</species>
    	                </pet>
    	            </birthday>
    	        </birthdays>
    	    </notifications>
    	</printOrder>
    
    

    The generated schema for the XML instance document above is named schema1.xsd, and it lives in /generated/schema under the root directory of the java-to-schema project. It looks like this:

    	<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    	<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    	  <xs:element name="printOrder" type="PrintOrderType"/>
    
    	  <xs:complexType name="PrintOrderType">
    	    <xs:sequence>
    	      <xs:element name="notifications" type="notificationsType" minOccurs="0"/>
    	    </xs:sequence>
    	    <xs:attribute name="id" type="xs:long" use="required"/>
    	  </xs:complexType>
    
    	  <xs:complexType name="notificationsType">
    	    <xs:sequence>
    	      <xs:element name="appointments" minOccurs="0">
    	        <xs:complexType>
    	          <xs:sequence>
    	            <xs:element name="appointment" type="AppointmentType" minOccurs="0" maxOccurs="unbounded"/>
    	          </xs:sequence>
    	        </xs:complexType>
    	      </xs:element>
    	      <xs:element name="birthdays" minOccurs="0">
    	        <xs:complexType>
    	          <xs:sequence>
    	            <xs:element name="birthday" type="BirthdayType" minOccurs="0" maxOccurs="unbounded"/>
    	          </xs:sequence>
    	        </xs:complexType>
    	      </xs:element>
    	    </xs:sequence>
    	  </xs:complexType>
    
    	  <xs:complexType name="AppointmentType">
    	    <xs:sequence>
    	      <xs:element name="apptType" type="xs:string"/>
    	      <xs:element name="apptDate" type="xs:string"/>
    	      <xs:element name="owner" type="OwnerType"/>
    	      <xs:element name="pet" type="PetType"/>
    	    </xs:sequence>
    	  </xs:complexType>
    
    	  <xs:complexType name="OwnerType">
    	    <xs:sequence>
    	      <xs:element name="firstName" type="xs:string"/>
    	      <xs:element name="lastName" type="xs:string"/>
    	      <xs:element name="address" type="AddressType"/>
    	    </xs:sequence>
    	  </xs:complexType>
    
    	  <xs:complexType name="AddressType">
    	    <xs:sequence>
    	      <xs:element name="addressLine1" type="xs:string"/>
    	      <xs:element name="addressLine2" type="xs:string" minOccurs="0"/>
    	      <xs:element name="city" type="xs:string"/>
    	      <xs:element name="state" type="xs:string"/>
    	      <xs:element name="zip" type="xs:string"/>
    	      <xs:element name="zipExt" type="xs:string" minOccurs="0"/>
    	    </xs:sequence>
    	  </xs:complexType>
    
    	  <xs:complexType name="PetType">
    	    <xs:sequence>
    	      <xs:element name="name" type="xs:string"/>
    	      <xs:element name="species" type="xs:string" minOccurs="0"/>
    	    </xs:sequence>
    	  </xs:complexType>
    
    	  <xs:complexType name="BirthdayType">
    	    <xs:sequence>
    	      <xs:element name="age" type="xs:int"/>
    	      <xs:element name="birthday" type="xs:string"/>
    	      <xs:element name="owner" type="OwnerType"/>
    	      <xs:element name="pet" type="PetType"/>
    	    </xs:sequence>
    	  </xs:complexType>
    	</xs:schema>
    
      

    If we take a quick peek at the main() method, we can see that we are generating the schema as follows:

    	// specify where the generated XML schema will be created
    	final File dir = new File("generated" + File.separator + "schema");
    	// specify a name for the generated XML instance document
    	OutputStream os = new FileOutputStream("niceVet.xml");
    
    	// create a JAXBContext for the PrintOrder class
    	JAXBContext ctx = JAXBContext.newInstance(PrintOrder.class);
    	// generate an XML schema from the annotated object model; create it
    	// in the dir specified earlier under the default name, schema1.xsd
    	ctx.generateSchema(new SchemaOutputResolver() {
    		   @Override
    		   public Result createOutput(String namespaceUri, String schemaName) throws IOException {
    				return new StreamResult(new File(dir, schemaName));
    		   }
    	   });
    

    To get the XML instance document, we first create some data, then we obtain a Marshaller from the JAXBContext and marshal the Java content tree to XML:

    	// create some data
    	PrintOrder order = new PrintOrder(EventUtil.getEvents());
    
    		...
    		
    	// create a marshaller   
    	Marshaller marshaller = ctx.createMarshaller();
    	// the property JAXB_FORMATTED_OUTPUT specifies whether or not the
    	// marshalled XML data is formatted with linefeeds and indentation
    	marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    	// marshal the data in the Java content tree 
    	// to the XML instance document niceVet.xml
    	marshaller.marshal(order, os);		
    

    Running the Sample Application


    To run the sample application, download the sample code and unzip it. Launch NetBeans and select File -> Open Project. In the Open Project dialog box, navigate to the directory where you unzipped the sample code and select the folder java-to-schema. Select the Open as Main Project check box. Click Open Project Folder. Right-click the java-to-schema project and select Run Project.

    Conclusion

    In this tip, you've seen how JAXB makes it easy to generate XML data to exchange with a business partner. The XML data your partner receives, however, may need a little tweaking in order to mesh with their system. In a future tip, you'll learn how to apply customizations to a supplied schema to get the Java object model - and content tree - you want.

    References and Resources

  • Sample code for this tip
  • The Java Tutorial.
  • Kohsuke Kawaguchi's Blog. Kohsuke Kawaguchi is a staff engineer at Sun Microsystems, where among other projects he works on JAXB.
  • Jennie Hall is a lead developer working in the financial sector.

    By Dana Nourie, August 2008

    Learn where Java code is written and saved, how classes relate to one another, and how to use the Greenfoot code editor.

    In the Wombat Object Basics article, you learned what an object is, what methods are for, and a bit about the syntax that is used in code. In this article, you will learn where that code is written and saved, how classes relate to one another, and you'll learn to use the Greenfoot code editor. In addition, certain words in this article are linked, so you can learn more than is being taught here.

    As in the last article, to follow along you will need:

    • The Java SE software installed on your computer
    • Greenfoot installed on your computer

    This article is aimed at anyone interested in Java programming who is between the ages of 10-100 and has no programming experience. It is recommended that you have read and followed Wombat Object Basics before moving on in this article.

    Where Is the Code?

    Now that you understand that Java programs are made up of a lot of Java objects, and they interact through methods that provide the instructions for doing things, you are ready to learn about the code. Let's not waste any time.

    Open Greenfoot. If the Wombats scenario is not already open, Click Scenario in the top menu, choose Open, select wombats, and then click Open.

    At the top of the world area, right-click wombatWorld and select void populate(). By invoking that void populate() method, you should now see a few wombats and lots of leaves in your wombat world as shown in Figure 1.

    Figure 1. Wombat World

    Read the rest of this article . . .

    Also see:

    New to Java Programming Center

    Young Developers

    The Java Tutorial

    Get Started with Java Programming in Facebook


     from Tim Boudreau's Blog

     Where's the state? This is a small but useful question when deciding how a problem domain gets carved up into objects: What things have state? What things have values that can change? When and how can they change? Can the changes be observed? Who needs to observe changes in state?

    These questions make a good start for figuring out how to carve up a problem domain into objects, if you observe the principle keep all related state in one place. I would go so far as to say that the majority of the appeal of Model-View-Controller (MVC) architecture is that it encourages you to keep state in one place.

    One big reason why statefulness matters is threading. In practice, it is common to see designs where threading was an afterthought. This is to be expected. Concurrency is a not natural way for human beings to think. So commonly a library is designed with no thought about threading; then a problem shows up which multi-threading can solve. Threading ends up being introduced into a codebase that was never designed for it. Retrofitting a threading model on something designed without one is very painful and sometimes impossible.

    Some threading models can be simple. For example, any time you are writing a Swing application, and you have a method that can do long running I/O, the first line of that method should be

    assert !EventQueue.isDispatchThread();
    under all circumstances.

    But keeping I/O off the event thread is the trivial case. Managing mutations to a model inside an application is a more complicated, less obvious problem.

    IMG_2949.png

    Any time you find yourself writing a setter (or more generally, mutator) method, it is worth asking yourself Who does this piece of state really belong to? Am I putting state in the right place? Blindly following the beans pattern (add a getter/setter to whatever type you happen to be editing) can result in state being distributed all over objects in an application. The result will be harder to maintain, and if it has any lifespan, less and less maintainable over time. Like entropy, or the no broken windows theory, the more state is distributed all over the place, the more that will masquerade as design and make it okay for a programmer to further diffuse state throughout objects in the application. Human beings can only hold so many things in their minds at a time. The more state is diffused, the more things someone must pay attention to simultaneously to solve a problem in that code.

    Read the rest of this blog . . .


    By Dana Nourie, August 2008

    Java programming is easy to learn. All Java programs are made up of objects just like the world around you. And Java objects do things with each other like you do things with objects wherever you are.

    This article explains what Java objects are and how they interact with each other. You will get familiar with some basic programming terminology as well. This article is aimed at anyone interested in Java programming who is between the ages of 10-100, and has no programming experience.

    The best way to learn object basics is to look at a Java program. So, to follow along with this article, you will need the following:

    • The Java SE software must be installed on your computer
    • Greenfoot must be installed on your computer

    Open Greenfoot and let's get started!

    Getting to Know Wombats

    Next, click on Scenario in the top menu, choose Open, select wombats, then click Open. You should see something like Figure 1 below:

    Figure 1. Wombat Scenario

    This program will be made up of several Java objects: World, wombatWorld, Actor, Wombat, Leaf.

    Compare the Wombat World to the real world: We live on the object planet Earth. On the Earth object are Continent objects and Ocean objects. On the Continent objects, there are City objects, House objects, and People objects. And many more objects.

    Read the rest of this article . . .

    Wombat Object Basics (Young Developer Series)
    This article is aimed at anyone age 10+, and explains what Java objects are and how they interact with each other, using examples from the Greenfoot Wombat scenario.

    By John O'Conner, August 2007; revised and updated by Ed Ort, July 2008

    JavaFX Script is a new scripting language that developers can use to create dynamic graphical content. On the desktop, the language provides libraries to help you use the Swing user interface (UI) toolkit and Java 2D APIs conveniently. It doesn't replace either Swing or Java 2D; the goal is to make those APIs more accessible to rich content developers. In other environments, such as mobile systems, JavaFX Script makes use of user interface technologies other than Swing. JavaFX Script enables you to write visually rich applications that run across platforms and operating environments.

    The language provides both declarative and procedural syntax. You can declaratively create a rich user interface, and then you can add event-handling routines and operations.

    However, most of us have to start more modestly, and that's the purpose of this article. Its goal is to show you how to get started with JavaFX Script. First, you'll need the following:

    Setting Up the Java Platform

    As a developer, you no doubt have a JDK on your system. However, if you haven't updated your system in a while, make sure you have Java SE 6. The Learning Curve Journal focuses on the compiler-based version of JavaFX Script and its support in NetBeans IDE 6.1. To install and use NetBeans IDE 6.1 with JavaFX technology, it is recommended that you install the latest level of Java SE 6 on your system, which currently is Java SE 6 Update 10 Beta. Download the latest JDK from the Java SE Downloads page of the Sun Developer Network. If you use Mac OS X, you can get Apple's latest release of the Java platform development kit, which currently is Java for Mac OS X 10.5, Update 1, directly from their Java section of the Apple Developer Connection.

    Going to the Source

    When you experiment with a new environment or language, you're going to hit dead ends and difficult places. That's part of the deal we all make when we adopt leading-edge technology. However, to smooth the learning curve, good documentation and examples are absolutely critical. Along with the JavaFX Technology hub of the Sun Developer Network, the javafx.com and Project OpenJFX web sites provide demo resources and the latest documentation you need to get accurate information.

    Some of you will want to start programming immediately, barely reading a word of the language reference. Others of you will read everything you can before actually using JavaFX Script. Even if you're the type that dives in right away, you have to start with some sort of language specification or tutorial. Before you can scribble out the prototypical "Hello, world" example, you need to know some basic language syntax. The documents on the JavaFX Reference page are a good place to start. You can find links there to reference documents such as the The JavaFX Script Programming Language Reference as well as links to many articles and tutorials such as Getting Started With JavaFX Technology and Creating A Simple JavaFX Application Using NetBeans IDE.

    Creating a JavaFX Application

    After you've read at least some of the language reference document, it's time to build a simple JavaFX application. Although you can build and run a JavaFX application manually from a command line, let's do it using NetBeans IDE 6.1, which has many features designed to simplify developing applications. You will need to install the JavaFX plugin for NetBeans.

    Read the rest of this tutorial . . .

    ********************************

    Get Started with Java Programming!

    Now Facebook users have a page to lead them to content that can help them learn Java programming. Log in to your Facebook account and Become a Fan of  Get Started with Java Programming!

    ********************************

    New to Java Programming Center

    The New to Java Programming Center helps developers who are new to the Java platform find what they need to set up their system, understand the various technologies, and create applications for the desktop, web, and devices.


    Creating a Simple JavaFX Application Using NetBeans IDE
    You will learn how to create, preview, run, and deploy a simple JavaFX application using the NetBeans IDE with JavaFX support.
    By Dana Nourie, July 2008

    Learning the Java platform is an adventure. There is so much you can do with Java technologies. Yet, figuring out what you want to do and where to start is the first hurdle you need to clear. This article describes the tools you can use to learn Java programming. You decide which tool to start with based on what you currently know. After reading about the tools, you'll discover resources to learn about the technologies, and the details of the Java programming language.

    Greenfoot Lunarlander
    Figure 1. Greenfoot Lunarlander

    The adventure of learning the Java platform should be fun, clear, and exciting. Start with one of the tools listed below, work your way into the next tool, and include the resources as you feel ready. Before you know it, you'll be creating exciting Java applications.

    Before You Begin

    Before you read about the tools and resources, you need the Java Standard Edition (Java SE) for any of the tools listed below to work.

    Download Java SE

    Once Java SE is installed on your computer, you are ready to consider the various teaching tools.

    Tools Overview

    Which tool you decide to use depends on what you already know about programming, and specifically Java programming. All of the tools listed here are designed to show you programming visually instead of just a bunch of confusing lines of code. The tools demonstrate the relationships between objects (you'll learn about objects within the tools), and how to make those objects interact and do things. Yet, each tool has been designed with a certain audience in mind.

    If you start with no programming experience and move from one tool to the next, the basic learning path is: Greenfoot > BlueJ > the NetBeans IDE BlueJ Edition, as shown in Figure 2:

    Learning Path for new developers
    Figure 2. Tools Learning Path

    Many of you, however, may know some programming, or you may know a little of another programming language, or maybe you've taken a class or two but need greater understanding. The descriptions of each tool below will help you decide which tool is best for you based on where are you are starting on your learning path now.

    The Learning Tools

    Each of the tools helps you visualize what is happening when you create a program. They help you see the objects and interactions so you can better understand the abstract concepts. All are intended to help you learn Java programming in a fun, clear way.

    Greenfoot [Download]

    Greenfoot is aimed at high school level (13+), but that doesn't mean someone younger or older won't benefit from it. Basically, Greenfoot is aimed at school level programming. The emphasis is to get something exciting and fun on screen very quickly. It's an easy entry into programming, for people who want to see what programming is like. It's great for people who have had no prior interest in programming. Greenfoot is fun, it's exciting, and it generates interest because it's specialized for building graphical 2D applications. This makes what you create visually fun. It's intended to draw you in to programming. Once you're hooked, you can graduate on to BlueJ, and then later to the NetBeans IDE BlueJ Edition.

    Download Quick Intro Tutorial

    BlueJ [Download]

    BlueJ is aimed more at intro university level. It assumes that you know that you are interested in learning programming, and you want to do it in an organized way. BlueJ is generic. It can be used to develop any kind of application. BlueJ teaches the fundamentals of objects, methods, and fields, and shows you visually the relationships between everything you create. You learn the nuts and bolts of the Java programming language, and can also see what is happening visually. Special emphasis is placed on visualization and interaction techniques to create a highly interactive environment that encourages experimentation and exploration.

    BlueJ Supports:

    RingsDataListIcon.gif

    Fully Integrated Environment

    RingsDataListIcon.gif

    Graphical Class Structure Display

    RingsDataListIcon.gif

    Graphical and Textual Editing

    RingsDataListIcon.gif

    Built-in Editor, Compiler, Virtual Machine, Debugger, etc.

    RingsDataListIcon.gif

    Easy-to-use Interface, deal for beginners

    RingsDataListIcon.gif

    Interactive Object Creation

    RingsDataListIcon.gif

    Interactive Object Calls

    RingsDataListIcon.gif

    Interactive Testing

    RingsDataListIcon.gif

    Incremental Application Development

    Download The BlueJ Tutorial

    NetBeans IDE BlueJ Edition [Download]

    BlueJ is an environment specifically aimed at beginning programmers. It offers educational tools, such as visualization and interaction facilities that greatly aid the learning of object-oriented concepts. While BlueJ covers the introductory phase of learning to program, and NetBeans offers powerful tools for professional developers, the inevitable step from one into the other has been a difficult barrier for students - until now.

    This tool offers a seamless migration path for students that supports the switch from educational tools into a full-featured, professional IDE. The BlueJ plug-in adds two significant features to the NetBeans IDE:

    • It allows NetBeans to open, work with, and create BlueJ projects in the BlueJ-native format (without converting them to-and-from the NetBeans IDE standard projects), so that you can do some of your work in the NetBeans IDE,and some back in BlueJ, wherever you feel comfortable working.
    • It adds a BlueJ View tab to the NetBeans Project Window, which gives a familiar view of your BlueJ projects.

    Download The Netbeans BlueJ Plug-in Tutorial

    • An extended tutorial by Dana Nourie.
    • A video on NetBeans/BlueJ from the Sun Developer Network.
    • A set of Lab Notes to help in the transition from BlueJ, and show a few of the facilities that the NetBeans IDE offers to programmers.
    • If you really want to see how far you can take the Zuul-for-NetBeans project, check out Brian Leonard's excellent Zuul everywhere tutorial.
    Tutorials for Learning the Java Programming Language

    Once you are using BlueJ or the NetBeans BlueJ Edition, you'll also need to learn the basics of the Java programming language. Your best resource for this is The Java Tutorial. Don't let these online tutorials overwhelm you. Take it little by little as you work through projects in the tool you are using. The Java Tutorial teaches the syntax of the Java programming language as well as how to use the thousands of classes available to you.

    Bookmark the New to Java Programming Center. Articles and tutorials posted in the center are aimed at learning developers, and are updated often. The level of programming covered varies from beginning to intermediate. The Learning Tab in the center also has a list of articles and tutorials to get you started that should be helpful in the beginning of your learning path. Young Developers is designed specifically for people 13 years old and up.

    Additionally, you can subscribe to Java Technology Fundamentals through convenient RSS feeds. Articles aimed at beginners to intermediate programmers go out in the feed several times a month. Some of these are articles that were published on java.sun.com, some are lessons from the Java Tutorial, and some are specifically written for Java Technology Fundamentals and the New to Java Programming Center. All are designed to help you learn the Java platform.

    If you have a Facebook account, be sure to Become a Fan of the Getting Started with Java Programming page and visit it regularly, as new content is added automatically through RSS feeds.

    When your programming skills are more intermediate, then also consider subscribing to Core Tech Tips. Like Java Technology Fundamentals, Core Tech Tips go out several times a month, but these programming tips are aimed at intermediate to advanced Java developers.

    Summary

    Choose your learning tool, use the resources, start programming, and have fun!

    Young Developer Learning Path
    This article describes the tools you can use to learn the Java programming language, and the appropriate path, depending on your experience.

    This tutorial guides you through the creation of a complete desktop database application that enables its user to browse and edit customer records and purchase history. The resulting application includes the following main features:

    • A main view that enables users to browse customer records and customer purchases.
    • A search field for the customer records.
    • Separate dialog boxes for entering new records or modifying existing records.
    • Code to interact with multiple related database tables.

    Contents

    Content on this page applies to NetBeans IDE 6.0 and 6.1

    To follow this tutorial, you need the following software and resources.

    Software or Resource Version Required
    NetBeans IDE Version 6.1
    Java Development Kit (JDK) Version 6 or
    version 5
    SQL script to create the database tables
    zip file of utility classes

    Note: You can download the final working project created in this tutorial at any time and open it in the IDE to view the classes. If you want to run the downloaded project, be sure to clean and build it before running.

    Introduction

    This application takes advantage of the following technologies:

    • The Java Persistence API (JPA), which helps you interact with a database using Java code.
    • Beans Binding, which enables you to keep Swing component properties synchronized.
    • The Swing Application Framework, which simplifies basic application functions such as persisting session information, handling actions, and managing resources.

    The tutorial makes use of IDE wizards and other code generation features to provide much of the boilerplate code. It also shows you how to customize the generated code and hand code other parts of the application.

    This tutorial takes approximately 2 hours to complete. For a shorter tutorial that shows the creation of a less customized user interface, see Building a Java Desktop Database Application.

    Below is a screenshot of the working application that you will have when you complete the tutorial.

    A screenshot of an application with a
          main frame that has a master/detail view of customer and order records.
          There is a search field that has the letters jul entered, and the two
          displayed customer records both have the jul string. In addition,
          an Order Editor dialog is displayed and contains an open combo box
          showing items to select from.

    Setting Up the Database

    Before creating any application code, we will set up the database. We will then be able to take advantage of wizards that generate much of the application code based on the structure of the database.

    The instructions in this tutorial are based using a MySQL database that you create with this SQL script.

    Note: You can use other database management software, but doing so might require making some adjustments to the SQL script. In addition, you will need to create the database from outside of the IDE.

    To set up the IDE to work with MySQL databases, see the Connecting to a MySQL Database page.

    To create the database:

    1. In the Services window, right-click the MySQL Server node and choose Start.
    2. Right-click the MySQL Server node and choose Create Database.

      If the Create Database item isn't enabled, choose Connect. You might then need to enter a password. The Create Database item should then be enabled.

    3. For Database Name, type MyBusinessRecords and click OK.
    4. In the New Database Connection dialog, type nbuser as the password and click OK.
    5. If the Advanced tab of the dialog box opens, click OK to close the dialog box.
    6. Scroll down to the node for connection that you have just created. The node should have the connection node icon.
    7. Right-click the connection node and choose Execute Command.
    8. Copy the contents of the MyBusinessRecords SQL script and paste them into the SQL Command 1 tab of the Source Editor.
    9. Click the Run SQL button (Run SQL button)in the toolbar of the Source Editor to run the script.

      Output of the script should appear in the Output window.

    10. Right-click the connection node again and choose refresh.
    11. Expand the node, and expand its Tables subnode.

      You should see four database tables listed.

    The database structure was designed with normalization and referential integrity in mind. Here are some notes on the structure:

    • The data is split among several tables to reduce duplication and the possibility for inconsistencies. Some tables are connected to each other through foreign keys.
    • All of the tables use MySQL's AUTO_INCREMENT attribute so that there is a unique identifier for each row in those tables. This identifier is created by the database management software, so your application and/or your application's user do not have to create this identifier. (For AUTO_INCREMENT to work properly within the application, you need to add the @GeneratedValue(strategy=GenerationType.IDENTITY annotation for that column in the table's entity class. Otherwise, the application does not try to submit a value for that column when you create a new record.)
    • The foreign key in the ORDERS table is there to link each order record with a customer. In the application's user interface, ORDER records are only displayed for the selected CUSTOMER.
    • The ON CASCADE DELETE attribute for the foreign key to the CUSTOMERS class ensures that a customer's orders are also deleted when a customer is deleted.
    • The foreign key in the CUSTOMERS table points to a COUNTRIES table. We will use this relationship in the application to enable the user to select a customer's country from a combo box.
    • The ORDERS table has a foreign key to the PRODUCTS table. When adding a new order record, the user will be able to choose a product from a combo box.
    • The COUNTRIES and PRODUCTS tables are pre-populated with data so that you can choose from those tables when the user of the application is adding customer and order records.
    • Though this tutorial does not cover it, you might find it useful to create separate applications to populate the COUNTRIES and PRODUCTS tables. Such applications could be created with the Java Desktop Application project template and would not require additional hand-coding.

    Creating the Application Skeleton

    We will use the IDE's Java Desktop Application project template to create much of the base code for the application. This template generates code for the following features:

    • Connection to the database.
    • A main application frame that contains tables for customer details and customer orders.
    • A main application class that handles basic application life-cycle functions, including persisting of window state between sessions and resource injection.
    • Actions (and corresponding buttons) for standard database application commands.

    Read the rest of this tutorial.

    For general tips and tricks on using the GUI Builder in NetBeans IDE, see the GUI Editor FAQ and Patrick Keegan's web log.

    *******************

    Get Started with Java Programming!

    Now Facebook users have a page to lead them to content that can help them learn Java programming. Log in to your Facebook account and Become a Fan of  Get Started with Java Programming!

    What's Your Sign? - Introduction to the JavaServer Faces Framework

    This tutorial, the first in a series, demonstrates the fundamentals of using the JavaServer Faces (JSF) framework to code web applications in the NetBeans IDE. Create a web application called jAstrologer that takes a user's name and birthday and returns information such as the user's zodiac sign, birthstone, and horoscope.