Return-Path: <env_305717631455463446@hermes.sun.com>
Received: from po10.mit.edu ([unix socket])
	by po10.mit.edu (Cyrus v2.1.5) with LMTP; Thu, 20 Feb 2003 19:30:29 -0500
X-Sieve: CMU Sieve 2.2
Received: from fort-point-station.mit.edu by po10.mit.edu (8.12.4/4.7) id h1L0USdX027580; Thu, 20 Feb 2003 19:30:28 -0500 (EST)
Received: from hermes.sun.com (hermes.sun.com [64.124.140.169])
	by fort-point-station.mit.edu (8.9.2/8.9.2) with SMTP id TAA07930
	for <alexp@mit.edu>; Thu, 20 Feb 2003 19:30:27 -0500 (EST)
Date: 20 Feb 2003 16:24:57 -0800
From: "JDC Tech Tips" <sunmail@hermes.sun.com>
To: alexp@mit.edu
Message-Id: <305717631455463446@hermes.sun.com>
Subject: Core Java Technologies Tech Tips (Choosing a Collections Framework Implementation, Providing a Scalable Image Icon)
Mime-Version: 1.0
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: SunMail 1.0
X-Spam-Score: 2.2
X-Spam-Level: ** (2.2)
X-Spam-Flag: NO
X-Scanned-By: MIMEDefang 2.28 (www . roaringpenguin . com / mimedefang)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>
Core Java Technologies Technical Tips
</title>

<style type="text/css">

code {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
pre {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
body, div, span {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
td, th {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
tr {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
table {font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
p {color: #333333; font-family: arial,helvetica,sans-serif; font-size: 10pt}
li {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
br {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
div {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
sup {font-family: Arial, Helvetica, sans-serif; font-size: 5pt}
h3 {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 11pt}
h4, b {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
blockquote, input, select {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
ul, ol {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
a:link {font-size: 10pt; font-family: Arial, Helvetica, sans-serif; color:#666699 }
span.purple {font-weight: bold; color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
span.small {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#333333 }
span.link {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#666699 }
</style>

</head>

<body bgcolor="#ffffff">
<a name="top"></a>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="."></td>
</tr>

<tr>
<td bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="."></td>

<td>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="2"><a href="http://bulkmail2.sun.com/CTServlet?id=1045777986875"><img src="http://developer.java.sun.com/images/headers/core_ttips_hdr.jpg" width="611" height="160" alt="Core Java Technologies Technical Tips" border="0"></a></td>
</tr>

<tr>
<td colspan="2" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="."></td>
</tr>

<!-- ================== -->
<!-- Start Main Content -->
<!-- ================== -->

<tr>
<td height="20">&nbsp;&nbsp;&nbsp;<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986891" style="text-decoration:none;">View this issue as simple text</a></td>
<td align="right" height="20"><span class="purple">February 20, 2003</span>&nbsp;&nbsp;&nbsp;&nbsp;</td>
</tr>

<tr><td colspan="2">

<table border="0" cellpadding="10" cellspacing="0" width="100%">
<tr>
<td>
     
<FORM METHOD="GET" ACTION="http://search.java.sun.com/search/java/">   
<table border="0" cellpadding="3" cellspacing="0" width="100%">
<tr> 
<td align="left" VALIGN="middle" width="20%"><h3>In this Issue</h3></td>
              
<td valign="middle" align="right" width="70%">
<font size="2">
<INPUT TYPE="text" SIZE="15" MAXLENGTH="128" NAME=qt></FONT></td>
            
<td VALIGN="middle" WIDTH="55">
<INPUT TYPE="image" SRC="http://developer.java.sun.com/images/v4a_search.gif" ALT="Search" value="search" BORDER="0" WIDTH="55"></td>
</tr>
</table>

</FORM>

<p>
Welcome to the Core Java<font size="-2"><sup>TM</sup></font> Technologies Tech Tips, February 20, 2003. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE<font size="-2"><sup>TM</sup></font>).
</p>

<p>
This issue covers:
</p>

<p>
<a href="#1"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt=".">Choosing A Collections Framework Implementation</a>
<br>    
<a href="#2"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt=".">Providing a Scalable Image Icon</a>
<br>    
<a href="#3"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt=".">An Addition to Last Month's Tip on Reading Files From JARs</a>
</p>

<p>
These tips were developed using Java 2 SDK, Standard Edition, v 1.4. 
</p>

<p>
This issue of the Core Java Technologies Tech Tips is written by John Zukowski, president of <a href="http://www.jzventures.com">JZ Ventures, Inc.</a>
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table> 

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<a name="1"></a>

<h3>CHOOSING A COLLECTIONS FRAMEWORK IMPLEMENTATION</h3>

<p>
The Collections Framework has been a part of the Java 2 Platform, Standard Edition (J2SE) since version 1.2. The framework offers a series of classes, interfaces, and implementations for working with collections of data. You can produce different behaviors by choosing different implementations of the core interfaces. This tip examines some considerations in choosing the right implementation for your needs.
</p>

<p>
First, understand that to minimize the programming changes required when changing to a different interface implementation, your programs should typically access the interface, not the specific implementations. In other words, typically use:
</p>

<pre>
   List list = new ArrayList();
   Set set = new HashSet();
   Map map = new TreeMap();
</pre>

<p>
Don't use:
</p>

<pre>
   ArrayList list = new ArrayList();
   HashSet set = new HashSet();
   TreeMap map = new TreeMap();
</pre>

<p>
This allows you to change the collection implementation without affecting the rest of your code.   
</p>

<p>
The key three interfaces of the framework are <code>Set</code>, <code>List</code>, and <code>Map</code>. A <code>Set</code> offers a collection of unique elements. A <code>List</code> provides ordered access (by index), but it doesn't guarantee uniqueness. The <code>Map</code> interface is different than the other two. Instead of just offering a collection of single elements, a <code>Map</code> provides a collection of key-value pairs. Based on a key, you find its value through a lookup operation. In other words, it's similar to checking for the phone number of a friend.
</p>

<p>
There are three concrete <code>Set</code> implementations that are part of the Collection Framework: <code>HashSet</code>, <code>TreeSet</code>, and <code>LinkedHashSet</code>. All three implementations provide a collection of unique elements. Typically, you use <code>HashSet</code>, which maintains its collection in an unordered manner. If this doesn't suit your needs, you can use <code>TreeSet</code>. A <code>TreeSet</code> keeps the elements in the collection in sorted order. For example, if a set of names (Mary, John, and Sam) are in a <code>Set</code>, a <code>TreeSet</code> iterates through the elements in an ordered fashion: John, Mary, and Sam. By comparison, the order of elements in a <code>HashSet</code> is undefined. Finally, there is <code>LinkedHashSet</code>. While <code>HashSet</code> has an undefined order for its elements, <code>LinkedHashSet</code> supports iterating through its elements in the order they were inserted. It maintains a secondary linked list to!
 manage insertion order. Understand that the additional features provided by <code>TreeSet</code> and <code>LinkedHashSet</code> add to the runtime costs.  
</p>

<p>
The <code>List</code> interface offers two such concrete implementations: <code>ArrayList</code> and <code>LinkedList</code>. There is a third implementation, <code>Vector</code>, but it is part of the historical collection classes. (These are classes from an earlier release. They're provided as a retrofit into the collections framework, and are typically avoided with newer programs.) Of the newer classes, the <code>ArrayList</code> provides a collection backed by an array. It provides quick indexed access to its elements, and works best when elements are only added and removed at the end. To make this happen, <code>ArrayList</code> performs an internal move operation when an element is added or removed. By comparison, <code>LinkedList</code> is best when add and remove operations happen anywhere, not only at the end. <code>LinkList</code> doesn't do an internal move operation for an element insert or remove, it just manipulates reference pointers. But <code>LinkedList</code>'!
s added flexibility comes at an added cost -- it results in much slower indexed operations. So if you frequently access random elements, for example, you often make requests like &quot;give me the value of element N&quot;, using an <code>ArrayList</code> is better. But if you frequently add and remove elements from positions other than the end, <code>LinkedList</code> is better. 
</p>

<p>
The final core interface is <code>Map</code>. There are five implementations of <code>Map</code> provided as part of the framework: <code>HashMap</code>, <code>TreeMap</code>, <code>LinkedHashMap</code>, <code>IdentityHashMap</code>, and <code>WeakHashMap</code>. There is also one historical implementation: <code>Hashtable</code>. While there are more implementations here, it's actually easier to choose the right implementation for your needs:
</p>

<ul>
  <li>By default, choose <code>HashMap</code>. Typically, it serves the most needs.<br><br></li>
 
  <li>Choose the <code>TreeMap</code> implementation if you need to maintain the keys of the map in a sorted order. However, if you only need the keys sorted when you are done with the <code>Map</code> or need to generate a report, sometimes it's better to simply keep everything in a <code>HashMap</code> while adding, and create a <code>TreeMap</code> at the end:<br><br>
  
  <blockquote>
  <code>
     Map map = new HashMap();<br>
     // Add and remove elements from unsorted map<br>
     map.put(&quot;Foo&quot;, &quot;Bar&quot;);<br>
     map.put(&quot;Bar&quot;, &quot;Foo&quot;);<br>
     map.remove(&quot;Foo&quot;);<br>
     map.put(&quot;Foo&quot;, &quot;Baz&quot;);<br>
     // Then sort before displaying elements<br>
     // in sorted order<br>
     map = new TreeMap(map);<br>
  </code>
  </blockquote>
   
  This avoids the overhead of maintaining the map sort, and leaves the burden of sorting to the end.<br><br></li>
  
  <li><code>LinkedHashMap</code> works like the <code>LinkedHashSet</code>. It maintains the ability to traverse the map elements in insertion order. Typically, maps use the equals method to check if an element is in the <code>Map</code>.<br><br></li>
  
  <li><code>IndentityHashMap</code> uses <code>==</code> to check for equality of elements. Use <code>IndentityHashMap</code> in those (probably rare) cases where you need strict reference equality.<br><br></li>
  
  <li><code>WeakHashMap</code> is rarely used. It keeps its keys as weak references. A weak reference allows a program to maintain a reference to an object, but it doesn't prevent the object from being considered for reclamation by the garbage collector. If the only access to the key is through the weak reference, the garbage collector can get rid of the key-value entry. If you don't need weak references, avoid the <code>WeakHashMap</code>.</li>

</ul>

<p>
As is the case with <code>Vector</code>, the <code>Hashtable</code> is typically avoided in newer programs in favor of <code>HashMap</code>.
</p>

<p>
The pointers offered in this tip should help you choose a Collections Framework interface implementation. Although sometimes the best way to choose between two implementations is to run them both and compare the results. If you're unsure which of two implementations to choose, write a quick test program that manipulates each interface 10 or 20 thousand times. Then see which one works better for your specific requirements.
</p>

<p>
For more information about the Collections Framework, see &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986816">The Collections Framework</a>.&quot;
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<a name="2"></a>

<h3>PROVIDING A SCALABLE IMAGE ICON</h3>

<p>
The <code>Icon</code> interface in JFC/Swing provides a flexible way to include images with GUI components such as buttons and labels. By simply implementing the three methods in the interface, you can make anything be the image for a component.
</p>

<pre>
  public interface Icon {
    public void paintIcon(Component c,
                          Graphics g,
                          int x,
                          int y);
    public int getIconWidth();
    public int getIconHeight();
  }
</pre>

<p>
However there's a scalability problem here -- the width and height of the image must be fixed. The <code>ImageIcon</code> class provides an <code>Icon</code> implementation that works with <code>Image</code> files. If the size of the <code>Image</code> in the file isn't the size of the <code>Icon</code> you want, you must manually scale an <code>Image</code> before making the <code>Icon</code>. 
</p>

<p>
This tip presents an <code>Icon</code> implementation that does the scaling for you. The implementation lets the image scale itself when it is time to paint the icon. That way, you can adjust what the scaling factors are without creating multiple <code>Image</code> or <code>Icon</code> objects.
</p>

<p>
There are two ways to scale an <code>Image</code> object. The <code>Image</code> class offers a <code>getScaledInstance</code> that lets you create a cached version of the <code>Image</code> for drawing:
</p>

<pre>
  getScaledInstance(int width, int height, int hints)
</pre>

<p>
Or you can scale the image &quot;on the fly&quot; at drawing time with the <code>drawImage</code> methods:
</p>

<pre>
  drawImage(Image image, int x, int y, int width, 
      int height, ImageObserver observer) 
  drawImage(Image image, int x, int y, int width, 
      int height, Color bgcolor, ImageObserver observer) 
</pre>

<p>
Let's first look at <code>getScaledInstance</code>. The <code>getScaledInstance</code> method works by taking a new size and a hint about how to do the scaling. There are five constants in the <code>Image</code> class that define how to do the scaling:
</p>

<ul>
  <li><code>SCALE_DEFAULT</code> to use the default algorithm</li>
  <li><code>SCALE_FAST</code> to favor speed over smoothness</li>
  <li><code>SCALE_SMOOTH</code> to favor smoothness over speed</li>
  <li><code>SCALE_REPLICATE</code> to use the <code>ReplicateScaleFilter</code> for scaling</li>
  <li><code>SCALE_AREA_AVERAGING</code> to use <code>AreaAveragingScaleFilter</code> for scaling</li>
</ul>

<p>
While there are five constants here, there are really only two settings. The <code>SCALE_FAST</code> constant offers the same behavior as <code>SCALE_REPLICATE</code>. The <code>SCALE_SMOOTH</code> constant offers the same behavior as <code>SCALE_AREA_AVERAGING</code>. And with <code>Image</code> being an abstract class, <code>SCALE_DEFAULT</code> provides the default of the two scaling mechanisms for a specific <code>Image</code> implementation.
</p>

<p>
What do the scaling operations do? <code>SCALE_REPLICATE</code> copies lines when scaling up, and removes lines when scaling down. <code>SCALE_AREA_AVERAGING</code> looks at neighboring pixels to get a smoother look when scaling in either direction.
</p>

<p>
It might seem sensible to scale an <code>Image</code> once with <code>getScaledInstance</code>, and repeatedly draw the scaled <code>Image</code> with a version of <code>drawImage</code> that doesn't do scaling. However, there are several factors that should be considered that actually favor doing on-the-fly scaling with the <code>drawImage</code> versions that scale. The technology behind on-the-fly scaling is continually improving, and as hardware acceleration through D3D and OpenGL becomes available, the performance difference approaches zero. The key factor is the extra memory required to cache scaled instances. With on-the-fly scaling, there is no caching. For a large image, multiple megabytes can be involved here. If you cache multiple images, memory usage adds up quickly. A third difference has to do with some implementation deficiencies in the Toolkit image code, but that isn't obvious from the sample application without &quot;digging under the covers&quot;.
</p>

<p>
Here's a demonstration of an <code>Icon</code> that scales. The following <code>ImageIconScalable</code> class subclasses <code>ImageIcon</code> and adds a <code>setScaledSize</code> method that lets you change the size of the drawn <code>Image</code>. Use -1 for a width and height to reset the dimensions back to the original size. The bulk of the code offers constructors to match with those of <code>ImageIcon</code>.
</p>

<pre>
import java.awt.*;
import javax.swing.*;
import java.net.*;

public class ImageIconScalable extends ImageIcon {

  int width = -1;
  int height = -1;

  public ImageIconScalable() {
    super();
  }

  public ImageIconScalable(byte imageData[]) {
    super(imageData);
  }
  
  public ImageIconScalable(byte imageData[],
                 String description) {
    super(imageData, description);
  }
  
  public ImageIconScalable(Image image) {
    super(image);
  }
  
  public ImageIconScalable(Image image,
                 String description) {
    super(image, description);
  }
  
  public ImageIconScalable(String filename) {
    super(filename);
  }
  
  public ImageIconScalable(String filename,
                 String description) {
    super(filename, description);
  }
               
  public ImageIconScalable(URL location) {
    super(location);
  }
  
  public ImageIconScalable(URL location,
                 String description) {
    super(location, description);
  }

  public int getIconHeight() {
    int returnValue;
    if (height == -1) {
      returnValue = super.getIconHeight();
    } else {
      returnValue = height;
    }
    return returnValue;
  }

  public int getIconWidth() {
    int returnValue;
    if (width == -1) {
      returnValue = super.getIconWidth();
    } else {
      returnValue = width;
    }
    return returnValue;
  }

  public void paintIcon(Component c,
                        Graphics g,
                        int x,
                        int y) {
    if ((width == -1) && (height == -1)) {
      g.drawImage(getImage(), x, y, c);
    } else {
      g.drawImage(getImage(), x, y, width, height, c);
    }
  }

  public void setScaledSize(int width,
                            int height) {
    this.width = width;
    this.height = height;
  }
}
</pre>

<p>
To test the new scaling ability, the following test program takes an image file name from the command line and places it in a button. The display gives you the opportunity to make the size of the image larger or smaller.
</p>

<p>
<img src="http://developer.java.sun.com/developer/JDCTechTips/images/tt022003_imgtestfig.gif" width="400" height="400" alt="IISTest" border="0">
</p>

<p>
Select different size multipliers. Notice that the icon size changes without reloading the <code>Image</code> icon. One line worth mentioning specifically is the call to revalidate the button that contains the scalable <code>ImageIcon</code>:
</p>

<pre>
    jbImage.revalidate();
</pre>

<p>
Because the added <code>setScaledSize</code> method doesn't change any properties of the component associated with the icon, the program needs to manually notify the component that its state changed. This both redraws the component and revalidates the display. This affects the button size, because the width and height changed.
</p>

<pre>
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class IISTest extends JFrame 
                    implements ActionListener {

  ImageIconScalable imageIcon;

  JButton    jbDiv2,
             jbDiv4,
             jbMult2,
             jbOrig,
             jbImage;

  public IISTest(String filename) {
    setTitle(&quot;IISTest&quot;);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    imageIcon = new ImageIconScalable( 
      getClass().getResource(filename));
    jbDiv2 = new JButton(&quot;Div2&quot;);
    jbDiv4 = new JButton(&quot;Div4&quot;);
    jbMult2 = new JButton(&quot;Mult2&quot;);
    jbOrig = new JButton(&quot;Original&quot;);
    jbImage = new JButton(imageIcon);

    jbDiv2.addActionListener(this);
    jbDiv4.addActionListener(this);
    jbMult2.addActionListener(this);
    jbOrig.addActionListener(this);
    JPanel jpNorth = new JPanel();
    jpNorth.add(jbDiv2);
    jpNorth.add(jbDiv4);
    jpNorth.add(jbMult2);
    jpNorth.add(jbOrig);

    JPanel jpCenter = new JPanel();
    jpCenter.add(jbImage);

    Container cp = getContentPane();
    cp.add(jpNorth, BorderLayout.NORTH);
    cp.add(jpCenter, BorderLayout.CENTER);
    setSize(400, 400);
    show();
  }

  public void doChange(
      int proportion, boolean multiply) {
    int width = imageIcon.getIconWidth();
    int height = imageIcon.getIconHeight();
    if (multiply) {
      imageIcon.setScaledSize(
          width * proportion, 
          height * proportion); 
    } else {
      imageIcon.setScaledSize(
          width / proportion, 
          height / proportion); 
    }
  }
    
  public void actionPerformed(ActionEvent ae) {
    JButton source = (JButton)ae.getSource();
    if (source.equals(jbDiv2)) {
      doChange(2, false);
    } else if(source.equals(jbDiv4)) {
      doChange(4, false);
    } else if(source.equals(jbMult2)) {
      doChange(2, true);
    } else if(source.equals(jbOrig)) {
      imageIcon.setScaledSize(-1, -1);
    }
    // Changing &quot;icon&quot; without changing icon
    // So, need to revalidate associated component(s)
    jbImage.revalidate();
  }

  public static void main(String args[]) {
    if (args.length != 1) {
      System.err.println(
         &quot;Please provide an image file name to load&quot;);
    } else {
      new IISTest(args[0]);
    }
  }
}
</pre>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table>

<!-- Grey Horizontal Line ends Here -->

<a name="3"></a>

<h3>AN ADDITION TO LAST MONTH's TIP ON READING FILES FROM JARS</h3>

<p>
The January 22, 2003 tip &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986833">Reading files from Java Archives (JARs)</a>&quot; discussed the use of the <code>JarFile</code> class to read files from within a JAR file. You should note that the <code>JarFile</code> class is useful for reading files from a JAR when the files are not in the class path. The <code>JarFile</code> class is also useful for reading files from a JAR when you want to specify the target JAR file. However, if the JAR file is in the class path, there is a simpler way of reading from it. You can use:
</p>

<pre>
  URL url = ClassLoader.getSystemResource(name);
</pre>
  
<p>
or
</p>

<pre>
  InputStream stream = 
     ClassLoader.getSystemResourceAsStream(name);
</pre>

<p>
These techniques allow you to read a file out of a JAR file that is located in your class path. You don't need to specify the JAR filename.
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<FORM METHOD="POST" ACTION="http://developer.java.sun.com/servlet/jdc.survey.TabulationServlet">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td></tr>

<tr><td>
<h3>Reader Feedback</h3> 

<INPUT TYPE="hidden" NAME="survey_id" VALUE="2600">
<INPUT TYPE="hidden" NAME="anonymous" VALUE="True">
<INPUT TYPE="hidden" NAME="answer_count" VALUE="3">
<INPUT TYPE="hidden" NAME="answer1" VALUE="FebCore_tt022003">
<INPUT NAME="answer2" TYPE="RADIO" VALUE="2">&nbsp; Very worth reading&nbsp; 
<INPUT NAME="answer2" TYPE="RADIO" VALUE="1">&nbsp; Worth reading&nbsp; 
<INPUT NAME="answer2" TYPE="RADIO" VALUE="0">&nbsp; Not worth reading&nbsp; 
 
<p>
If you have other comments or ideas for future technical tips, please type them  here: 
</p>
 
<p>
<TEXTAREA NAME="answer3" ROWS="6" COLS="50"></TEXTAREA> 
</p>
 
<p>
<INPUT TYPE="SUBMIT" VALUE="Submit"> &nbsp; <INPUT TYPE="RESET"> 
</p>

<p> 
Have a question about Java<font size="-2"><sup>TM</sup></font> programming? Use  
<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986905">Java Online Support.</a> 
</p>

</td></tr></table>
</FORM> 

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="." border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<br>

<span class="small">IMPORTANT: Please read our Terms of Use, Privacy, and Licensing 
policies:<br>
<a href="http://www.sun.com/share/text/termsofuse.html"><span class="link">http://www.sun.com/share/text/termsofuse.html</span></a><br>
<a href="http://www.sun.com/privacy/"><span class="link">http://www.sun.com/privacy/</span></a><br> 
<a href="http://developer.java.sun.com/berkeley_license.html"><span class="link">http://developer.java.sun.com/berkeley_license.html</span></a>
</span><br><br>


<span class="small">
Comments? Send your feedback on the Core Java<sup>TM</sup> Technologies Tech Tips to: <a href="mailto:jdc-webmaster@sun.com"><span class="link">jdc-webmaster@sun.com</span></a>
</span><br><br>

<span class="small">
Subscribe to other Java developer Tech Tips:
</span><br><br>

<span class="small">
- 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<sup>TM</sup>).<br>
- Wireless Developer Tech Tips. Get tips on using wireless Java technologies and APIs, such as those in the Java 2 Platform, Micro Edition (J2ME<sup>TM</sup>).<br><br>
</span>
   
<span class="small">
To subscribe to these and other JDC publications:<br>
- Go to the JDC Newsletters and Publications page, choose the newsletters you want to <a href="http://bulkmail2.sun.com/CTServlet?id=1045777986845"><span class="link">subscribe</span></a> to and click &quot;Update&quot;.<br>
  - To unsubscribe, go to the <a href="http://bulkmail2.sun.com/CTServlet?id=1045777986845"><span class="link">subscriptions page</span></a>, uncheck the appropriate checkbox, and click &quot;Update&quot;.
</span><br><br>

<span class="small">ARCHIVES: You'll find the Core Java Technologies Tech Tips archives at:<br>
<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986920"><span class="link">http://java.sun.com/jdc/TechTips/index.html</span></a>
</span><br><br>

<span class="small">Copyright 2003 <a href="http://bulkmail2.sun.com/CTServlet?id=1045777986935"><span class="link">Sun Microsystems, Inc.</span></a> All rights reserved.
<br>4150 Network Circle, Santa Clara, CA 95054 USA.
</span><br><br>

<span class="small">This document is protected by copyright. For more information, see:
<br><a href="http://java.sun.com/jdc/copyright.html"><span class="link">http://java.sun.com/jdc/copyright.html</span></a>
</span><br><br>

<span class="small">Sun, Sun Microsystems, Java, Java Developer Connection, J2SE, J2EE, and J2ME are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.</span><br><br>


<!-- ================ -->
<!-- End Main Content -->
<!-- ================ -->

<center>
<a href="http://bulkmail2.sun.com/CTServlet?id=1045777986935"><img src="http://developer.java.sun.com/images/lgsun.gif" border="0" alt="Sun Microsystems, Inc."></a>
</center>

</td>
</tr>
</table>

</td></tr>
</table>
</td>

<td bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="."></td>
</tr>
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="."></td>
</tr>
</table>

<table bgcolor = "#efefef"><tr><td><a href="http://bulkmail.sun.com/unsubscribe?305717631455463446">Please unsubscribe me from this newsletter.</a><img src="http://bulkmail2.sun.com/OTServlet?id=305717631455463446" width=1 height=1></td></tr></table></body>
</html>

