Core Java Technologies Tech Tips Tips, Techniques, and Sample Code Welcome to the Core Java Technologies Tech Tips for April 5, 2005. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE). This issue covers: * Introduction to Autoboxing * Introduction to Tables with JDesktop Network Components (JDNC) These tips were developed using the Java 2 Platform Standard Edition Development Kit 5.0 (JDK 5.0). You can download JDK 5.0 at http://java.sun.com/j2se/1.5.0/download.jsp. This issue of the Core Java Technologies Tech Tips is written by Daniel H. Steinberg, Director of Java Offerings for Dim Sum Thinking, Inc, and editor-in-chief for java.net (http://java.net). You can view this issue of the Tech Tips on the Web at http://java.sun.com/developer/JDCTechTips/2005/tt0405.html. See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms. For more Java technology content, visit these sites: java.sun.com - The Java technology source for developers. Get the latest Java platform releases, tutorials, newsletters and more. java.net - A web forum where enthusiasts of Java technology can collaborate and build solutions together. java.com - The ultimate marketplace promoting Java technology, applications and services. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INTRODUCTION TO AUTOBOXING Although the Java programming language is an object-oriented language, it's often the case that when using the language you need to work with primitive types. Before J2SE 5.0, working with primitive types required the repetitive work of converting between the primitive types and the wrapper classes. In this tip, you will see how the new autoboxing feature in J2SE 5.0 handles conversions -- for example, between values of type int and values of type Integer. The tip also discusses some autoboxing-related considerations in determining when two numerical values are equal. The October 5, 2004 Tech Tip, "Formatting Output with the New Formatter" (http://java.sun.com/developer/JDCTechTips/2004/tt1005.html#2) discussed a new way to format output that is similar to that of the C language's printf. An example in that tip used the printf() method to print an integral value. Here is a simple example that uses the printf() method: public class FormatPrint { public static void main(String[] args) { System.out.printf("There is only %d thing.", 1); } } The signature of the printf() method in the FormatPrint example is: printf(String format, Object... args) The number 1 is a primitive and not an object, so you might think that the line: System.out.printf("There is only %d thing.", 1); should not compile. However autoboxing takes care of the situation by automatically wrapping the integer value in the appropriate wrapper object. In J2SE 1.4 you would have needed to manually wrap the primitive value using something like new Integer(1). Another example of where automatically converting from a primitive might be useful is when you use the Collections APIs. The collections classes are designed to store objects. Consider the following simple example of storing int values from 0 to 9 in an ArrayList: import java.util.ArrayList; public class Autoboxing { public static void main(String[] args) { ArrayList list = new ArrayList(); for(int i = 0; i < 10; i++){ list.add(i); } } } The comparable program for J2SE 1.4.2 would be the following: import java.util.ArrayList; public class ManualBoxing { public static void main(String[] args) { ArrayList list = new ArrayList(); for(int i = 0; i < 10; i++){ list.add(new Integer(i)); } } } With ManualBoxing you need to explicitly create the Integer object using list.add(new Integer(i)). Contrast that with Autoboxing, where the int i is autoboxed to an Integer object in the line list.add(i). Autoboxing works well with other new J2SE 5.0 features. For example, the autoboxing feature allows seamless integration between generic types and primitive types. In the ManualBoxing example, the elements of the ArrayList are of type Object. By comparison, in the Autoboxing example, the elements of list are of type Integer. (For more information about generics, see the Tech Tip "Generics" (http://java.sun.com/developer/JDCTechTips/2005/tt0315.html#1).) Let's extend the Autoboxing example to iterate through the elements in the ArrayList and calculate their sum. Notice that this new version also uses the new J2SE 5.0 enhanced for loop to iterate through the elements. import java.util.ArrayList; public class Autoboxing { public static void main(String[] args) { ArrayList list = new ArrayList(); for(int i = 0; i < 10; i++){ list.add(i); } int sum = 0; for ( Integer j : list){ sum += j; } System.out.printf("The sum is %d.", sum ); } } Autoboxing is used in a number of places in the updated Autoboxing example. First, ints are boxed to Integers as they are added to the ArrayList. Then Integers are unboxed to ints to be used in calculating the sum. Finally, the int representing the sum is boxed for use in the printf() statement. The transparency of the boxing and unboxing makes autoboxing easy to use. However using the autoboxing feature requires some care. In particular, testing for the equality of objects created by autoboxing is not the same as testing for the equality of objects that are not created by autoboxing. To see this, look at the following BoxingEquality class: import java.util.ArrayList; public class BoxingEquality { public static void main(String[] args) { int i = 2; int j = 2; ArrayList list = new ArrayList(); list.add(i); list.add(j); System.out.printf("It is %b that i ==j.\n", (i==j)); //(1) System.out.printf("It is %b that " + "list.get(0) == list.get(1).\n", list.get(0)==list.get(1)); //(2) System.out.printf("It is %b that " + "list.get(0).equals(list.get(1)).", list.get(0).equals(list.get(1))); //(3) } } The first print statement in BoxingEquality compares the equality of the primitives i and j. The second print statement compares the equality of the objects created by autoboxing i and j. The third print statement compares the value of the objects created by autoboxing i and j. You would expect the first and the third print statements to return true, but what about the second? The output from running the BoxingEquality program is: It is true that i ==j. It is true that list.get(0) == list.get(1). It is true that list.get(0).equals(list.get(1)). Now change the values of i and j to 2000. import java.util.ArrayList; public class BoxingEquality { public static void main(String[] args) { int i = 2000; int j = 2000; // . . . } Save, recompile, and rerun BoxingEquality. This time the results are different: It is true that i ==j. It is false that list.get(0) == list.get(1). It is true that list.get(0).equals(list.get(1)). The primitives are equal and the values of the boxed ints are equal. But this time the ints point to different objects. What you have discovered is that for small integral values, the objects are cached in a pool much like Strings. When i and j are 2, a single object is referenced from two different locations. When i and j are 2000, two separate objects are referenced. Autoboxing is guaranteed to return the same object for integral values in the range [-128, 127], but an implementation may, at its discretion, cache values outside of that range. It would be bad style to rely on this caching in your code. In fact, testing for object equality using == is, of course, not what you normally intend to do. This cautionary example is included in this tip because it is easy to lose track of whether you are dealing with objects or primitives when the compiler makes it so easy for you to move back and forth between them. For more information on autoboxing, see "Autoboxing" (http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INTRODUCTION TO TABLES WITH JDESKTOP NETWORK COMPONENTS (JDNC) Think of all the routine, boilerplate code you write to create, configure, and display common Swing components. For instance, consider all the things you need to do to display data in a table. The JDesktop Network Components (JDNC) project (https://jdnc.dev.java.net/) aims to make it easier for you to produce rich data-centric Java Desktop clients. In this tip you will use JDNC to read tab-separated data from a file and display it in a table. You will put headings on the columns and select a subset to display. You will then filter the rows to display only those rows that meet a specific condition. Finally, you will sort this list and decorate alternating rows in different colors. To begin, imagine reading weather data from a text file and displaying it in a JTable that's inside of a JScrollPane. The JScrollPane is inside a JPanel, and the JPanel is inside a JFrame. The March 8, 2005 Tech Tip "Printing JTables" (http://java.sun.com/developer/JDCTechTips/2005/tt0308.html#1) showed how to do something similar to this. Using JDNC, you could read and display the weather data with the following XML:
In other words, you simply create a table element and specify the location of the file containing the data. To run the example, download the latest JDNC release from the download page at https://jdnc.dev.java.net/servlets/ProjectDocumentList. The latest version is currently 0.7 and requires J2SE 5.0. Download and expand the file jdnc-0_7-bin.zip. For this tip, create a directory named jdncTip and copy in the three jar files from jdnc-0_7/lib (jdnc-0_7-all, jdnc-runner, and jlfgr-1_0). Also copy the file weather.txt from jdnc-0_7/demo/data and put it in the jdncTip directory. Create the following file and save it as table.jdnc in the jdncTip directory. This is essentially the simpleTable.jdnc example that is contained in jdnc-0_7/demo.
To run the application you will need to have the three jar files you just copied over in your classpath. You must also specify that your main class is org.jdesktop.jdnc.runner.Application. The name of the jdnc file is passed in as a command-line argument. On a Unix or Linux machine this command is: java -cp jdnc-runner.jar:jdnc-0_7-all.jar:jlfgr-1_0.jar org.jdesktop.jdnc.runner.Application table.jdnc On a Windows computer this command is: java -cp jdnc-runner.jar;jdnc-0_7-all.jar;jlfgr-1_0.jar org.jdesktop.jdnc.runner.Application table.jdnc You should see a display of the table containing the weather data. The column headings in the displayed table are generically referred to as column0,column1, and so on. To display the column headings, you need to provide the entire list of them in order. This is done by adding a metaData element as a child of the tabularData element. You label the columns with a tag such as this: By default, the contents of the column are treated like strings. For data that is not of type string, you can specify the type using a tag such as this: The available types are string, float, integer, date, and href. Add metadata elements to the table.jdnc file, so that it looks like this:
Now your table should appear with the column headers you just provided. After you label your columns you can easily specify which ones appear, and the order in which they appear. Create a columns element that contains a column element for each column you want displayed. Here's how you specify a typical included column. You can also specify the justification of the data. For example, the table would look better if the temperature data was centered. That can be easily accomplished easily like this: The title attribute specifies the new heading for the column. In the previous example, no title attribute was specified, so the name you specified in each columnMetaData tag was used. Here is what the table.jdnc file looks like after adding column elements that identify five columns for display, the titles to be displayed for those columns, and justification specifications:
Suppose you only wanted to display the data for Bolivia. You can filter the information by searching for those elements whose COUNTRY has the value Bolivia. To do that, you add a filters tag between the tabularData and the columns element: Rerun the application. The table will now display only the twenty-one rows corresponding to Bolivia. You can click on any column label to resort the table in either ascending or descending order, based on the type for that column. You can also easily sort your data programatically, by adding the following sorter element as a child of the filters element: Now the rows will appear from locations in which the temperature is warmest to those for which the temperature is coldest. As a final touch, color odd rows cyan and even rows light grey by adding the following highlighters tag: Put all of these together and the table.jdnc file should look like this:
The table displays with striped rows, and the rows are sorted in descending order by temperature. For more information about JDNC, see the JDNC project page (https://jdnc.dev.java.net/). . . . . . . . . . . . . . . . . . . . . . . . PRIVACY STATEMENT: Sun respects your online time and privacy (http://sun.com/privacy). You have received this based on your e-mail preferences. If you would prefer not to receive this information, please follow the steps at the bottom of this message to unsubscribe. Please read our Terms of Use and Licensing policies: http://www.sun.com/share/text/termsofuse.html http://developers.sun.com/dispatcher.jsp?uid=6910008 * FEEDBACK Comments? Please enter your feedback on the Tech Tips at: http://developers.sun.com/contact/feedback.jsp?category=sdn * SUBSCRIBE/UNSUBSCRIBE Subscribe to other Java developer Tech Tips: - Enterprise Java Technologies Tech Tips. Get tips on using enterprise Java technologies and APIs, such as those in the Java 2 Platform, Enterprise Edition (J2EE). - Wireless Developer Tech Tips. Get tips on using wireless Java technologies and APIs, such as those in the Java 2 Platform, Micro Edition (J2ME). To subscribe to these and other SDN publications: - Go to the Sun Developer Network - Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), choose the newsletters you want to subscribe to and click "Submit". - To unsubscribe, go to the Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), uncheck the appropriate checkbox, and click "Submit". - To use our one-click unsubscribe facility, see the link at the end of this email: - ARCHIVES You'll find the Core Java Technologies Tech Tips archives at: http://java.sun.com/developer/TechTips/index.html - COPYRIGHT Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4150 Network Circle, Santa Clara, California 95054 USA. This document is protected by copyright. For more information, see: http://java.sun.com/jdc/copyright.html Core Java Technologies Tech Tips April 5, 2005 Trademark Information: http://www.sun.com/suntrademarks/ Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.