Return-Path: <env_32061839-426309885@hermes.sun.com>
Received: from po10.mit.edu (po10.mit.edu [18.7.21.66])
	by po10.mit.edu (Cyrus v2.1.5) with LMTP; Tue, 18 Mar 2003 16:17:11 -0500
X-Sieve: CMU Sieve 2.2
Received: from pacific-carrier-annex.mit.edu by po10.mit.edu (8.12.4/4.7) id h2ILH9OZ025742; Tue, 18 Mar 2003 16:17:09 -0500 (EST)
Received: from hermes.sun.com (hermes.sun.com [64.124.140.169])
	by pacific-carrier-annex.mit.edu (8.9.2/8.9.2) with SMTP id QAA02305
	for <alexp@mit.edu>; Tue, 18 Mar 2003 16:17:09 -0500 (EST)
Date: 18 Mar 2003 11:31:18 -0800
From: "JDC Tech Tips" <sunmail@hermes.sun.com>
To: alexp@mit.edu
Message-Id: <32061839-426309885@hermes.sun.com>
Subject: Core Java Technologies Tech Tips, March 18, 2003 (Dragging Text and Images with Swing, Discovering the Calling Method Name)
Mime-Version: 1.0
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: SunMail 1.0
X-Spam-Score: 0.5
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=1048015041907"><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=1048015041922" style="text-decoration:none;">View this issue as simple text</a></td>
<td align="right" height="20"><span class="purple">March 18, 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 Technologies Tech Tips, March 18, 2003. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE).
</p>

<p>
This issue covers:
</p>

<p>
<a href="#1"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt=".">Dragging Text and Images with Swing</a>
<br>    
<a href="#2"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt=".">Discovering the Calling Method Name</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>DRAGGING TEXT AND IMAGES WITH SWING</h3>

<p>
One of the more welcome features of J2SE version 1.4 are the enhancements to the Drag and Drop and data transfer facilities. These facilities are defined in the <code>java.awt.dnd</code> package with some help from the <code>java.awt.datatransfer package</code>. These APIs give you the ability to transfer any object (not just strings) between a Java Runtime Environment (JRE) and itself, another JRE, or an application native to the runtime platform. Earlier versions of J2SE required you to control all aspects of the drag gestures, such as what to do when the user click-drags a mouse over a component and drops it over another component. With the newer release of J2SE, a lot of the work is done for you.
</p>

<p>
The simplest way to add drag and drop support to a program is to use the <code>setDragEnabled</code> method. To drag-enable a <code>Swing</code> component, you simply call the <code>setDragEnabled</code> method, with an argument of true, on the component. The component must be one that supports drag operations. The components that provide this support are <code>JColorChooser</code>, <code>JFileChooser</code>, <code>JList</code>, <code>JTree</code>, <code>JTable</code>, and all the <code>JTextComponent</code> classes except <code>JPasswordField</code>. The following program demonstrates this approach. The program drag-enables a <code>JList</code> and two <code>JTextArea</code> components. You can select an item from the <code>JList</code> and then drop it in the <code>JTextArea</code>, or you can select content from one <code>JTextArea</code> and drop it in the other <code>JTextArea</code>.
</p>

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

    public class Drag1 {
      public static void main(String args[]) {
        JFrame frame = new JFrame(&quot;Drag&quot;);
        frame.setDefaultCloseOperation(
            JFrame.EXIT_ON_CLOSE);
        Container content = frame.getContentPane();
        JPanel inner = new JPanel(new BorderLayout());
        JTextArea top = new JTextArea(5, 40);
        top.setDragEnabled(true);
        JScrollPane topScroll = new JScrollPane(top);
        inner.add(topScroll, BorderLayout.NORTH);
        JTextArea bottom = new JTextArea(5, 40);
        bottom.setDragEnabled(true);
        JScrollPane bottomScroll = 
            new JScrollPane(bottom);
        inner.add(bottomScroll, BorderLayout.SOUTH);
        content.add(inner, BorderLayout.CENTER);
        DateFormatSymbols symbols = 
            new DateFormatSymbols(Locale.US);
        JList list = new JList(symbols.getWeekdays());
        list.setDragEnabled(true);
        JScrollPane leftScroll = new JScrollPane(list);
        content.add(leftScroll, BorderLayout.WEST);
        frame.pack();
        frame.show();
      }
    }
</pre>

<p>    
Drop works here because <code>Swing</code> has arranged for any component with a <code>TransferHandler</code> to automatically receive a drop target. <code>Swing</code> provides default <code>TransferHandler</code> objects to some components so that they support drop &quot;out of the box&quot;. These components are <code>JColorChooser</code> and all the <code>JTextComponent</code> classes (including <code>JPasswordField</code>).
</p>

<p>
While <code>setDragEnabled</code> allows you to turn on and off drag support, the actual mechanism of importing and exporting data is supplied by <code>Swing</code>'s <code>TransferHandler</code> class. <code>TransferHandler</code> is responsible for all data transfer into and out of a component. Specifically, <code>TransferHandler</code> handles the export of data for drag, cut, and copy, as well as the import for drop and paste. As mentioned above, <code>Swing</code> provides default <code>TransferHandler</code> implementations for some components. You can replace this default implementation with a <code>TransferHandler</code> of your own design by calling <code>setTransferHandler</code> on the component. This works together with <code>setDragEnabled</code> to allow for easy Drag and Drop customization. (Note that when you replace a <code>TransferHandler</code>, you not only change the behavior of Drag and Drop, but also cut, copy, and paste).
</p>

<p>
Components that don't support <code>setDragEnabled</code> still support a <code>TransferHandler</code>. But you'll be required to do a little more work to initiate a drag, such as supplying a <code>MouseListener</code> that watches for a drag gesture and calling the <code>TransferHandler</code>'s <code>exportAsDrag</code> method.
</p>

<p>
One type of custom <code>TransferHandler</code> exposes the current setting of a property as a draggable object. To use it, you create a <code>TransferHandler</code> that identifies the property name, and associate it with the start drag gesture you define for that component (such as <code>mousePress</code>). The <code>TransferHandler</code> handles the rest. Here's a program that uses a <code>TransferHandler</code> to drag-enable a text label for a <code>JLabel</code> component. Run the program and drag the label into the <code>JTextField</code>.
</p>

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

    public class Drag2 {
      public static void main(String args[]) {
        JFrame frame = new JFrame(&quot;Drag&quot;);
        frame.setDefaultCloseOperation(
            JFrame.EXIT_ON_CLOSE);
        Container content = frame.getContentPane();
        JTextField top = new JTextField();
        content.add(top, BorderLayout.NORTH);
        JLabel label = new JLabel(&quot;Drag Me&quot;);
        label.setTransferHandler(
            new TransferHandler(&quot;text&quot;));
        MouseListener listener = new MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            JComponent c = (JComponent)e.getSource();
            TransferHandler th = c.getTransferHandler();
            th.exportAsDrag(c, e, TransferHandler.COPY);
          }
        };
        label.addMouseListener(listener);
        content.add(label, BorderLayout.SOUTH);
        frame.setSize(100, 100);
        frame.show();
      }
    }
</pre>

<p>
How about dragging and dropping images, in other words &quot;transferring&quot; images? That's more complicated than moving text around. To transfer an image, you need to create a <code>TransferHandler</code> object that supports the <code>DataFlavor</code> of <code>imageFlavor</code>. A <code>DataFlavor</code> is an object that represents the data format of an object being transferred, that is, as it would appear on a clipboard during a drag and drop operation. In an image transfer, the transfer is done under a particular data flavor. This allows the receiver to determine what formats the transferable object can move. The receiver can compare that with the formats it supports receiving, and then find the richest format available for the transfer. To do this, you need to create a custom <code>TransferHandler</code> implementation. 
</p>

<p>
To demonstrate transferring images, let's define a <code>TransferHandler</code> object that supports transferring images from a <code>JLabel</code> to or from anywhere. 
</p>

<p>
In the <code>TransferHandler</code> object, you need to define what type of operations are supported. Use the <code>getSourceActions</code> method to do that. The available operations defined in the <code>TransferHandler</code> class are: <code>NONE</code>, <code>COPY</code>, <code>MOVE</code>, and <code>COPY_OR_MOVE</code>. In this example, let's assume that the image shouldn't be removed from the <code>JLabel</code>, so specify <code>COPY</code> as the supported operation:
</p>

<pre>
    public int getSourceActions(JComponent c) {
      return TransferHandler.COPY;
    }
</pre>

<p>
Next, implement the <code>canImport</code> method to check if a given set of flavors can be imported into the potential drop target. To do this, you need to first create an array of supported flavors:
</p>

<pre>
    public static final DataFlavor flavors[] = 
      {DataFlavor.imageFlavor};
</pre>

<p>
Then, in the <code>canImport</code> method, you check if the component drop target supports the flavor. If it can, return true, if not false. 
</p>

<pre>
    public boolean canImport(
        JComponent comp, DataFlavor flavor[]) {
      if (!(comp instanceof JLabel)) {
        return false;
      }
      for (int i=0, n=flavor.length; i&lt;n; i++) {
        for (int j=0, m=flavors.length; j&lt;m; j++) {
          if (flavor[i].equals(flavors[j])) {
            return true;
          }
        }
      }
      return false;
    }
</pre>

<p> 
Next, define the <code>createTransferable</code> method. This is called when something wants to be placed on the clipboard or used in a drag operation. However, no data is really placed on the clipboard just yet. Instead, a reference to a <code>Transferable</code> object is placed on the clipboard. The <code>Transferable</code> implementation does the actual copy. Notice that the <code>Transferable</code> implementation is an anonymous inner class here. It will simply return the Image just saved as the transferable data.
</p>

<pre>
    public Transferable createTransferable(
        JComponent comp) {

        if (comp instanceof JLabel) {
          JLabel label = (JLabel)comp;
          Icon icon = label.getIcon();
          if (icon instanceof ImageIcon) {
            final Image image = ((
                ImageIcon)icon).getImage();
            final JLabel source = label;
            Transferable transferable = 
                new Transferable() {

              public Object getTransferData(
                  DataFlavor flavor) {
                if (isDataFlavorSupported(flavor)) {
                    return image;
                }
                return null;
              }

              public DataFlavor[] getTransferDataFlavors() {
                return flavors;
              }

              public boolean isDataFlavorSupported(
                  DataFlavor flavor) {
                return flavor.equals(
                    DataFlavor.imageFlavor);
              }
            };
            return transferable;
          }
        }
      return null;
    }
</pre>

<p>
The last part is support for a paste operation. To get an image, you can paste it to replace the existing image on the <code>JLabel</code>. Remember that the Java platform supports <code>GIF</code>, <code>JPEG</code>, and <code>PNG</code>. As long as an image in one of those formats is on the system clipboard, it can be pasted onto the associated <code>JLabel</code>. This is done with the <code>importData</code> method:
</p>

<pre>
    public boolean importData(
        JComponent comp, Transferable t) {
      if (comp instanceof JLabel) {
        JLabel label = (JLabel)comp;
        if (t.isDataFlavorSupported(flavors[0])) {
          try {
            Image image = (
                Image)t.getTransferData(flavors[0]);
            ImageIcon icon = new ImageIcon(image);
            label.setIcon(icon);
            return true;
          } catch (UnsupportedFlavorException ignored) {
          } catch (IOException ignored) {
          }
        }
      }
      return false;
    }
</pre>

<p>
Putting all this together, gives the following <code>ImageSelection</code> class definition:
</p>

<pre>
    import java.awt.*;
    import java.awt.image.*;
    import java.awt.datatransfer.*;
    import java.io.*;
    import javax.swing.*;


    public class ImageSelection extends TransferHandler {


      private static final DataFlavor flavors[] = 
          {DataFlavor.imageFlavor};


      public int getSourceActions(JComponent c) {
        return TransferHandler.COPY;
      }


      public boolean canImport(
          JComponent comp, DataFlavor flavor[]) {
            if (!(comp instanceof JLabel)) {
              return false;
            }
        for (int i=0, n=flavor.length; i&lt;n; i++) {
          for (int j=0, m=flavors.length; j&lt;m; j++) {
            if (flavor[i].equals(flavors[j])) {
              return true;
            }
          }
        }
        return false;
      }


      public Transferable createTransferable(
          JComponent comp) {

        if (comp instanceof JLabel) {
          JLabel label = (JLabel)comp;
          Icon icon = label.getIcon();
          if (icon instanceof ImageIcon) {
            final Image image = ((
                ImageIcon)icon).getImage();
            final JLabel source = label;
            Transferable transferable = 
                new Transferable() {

              public Object getTransferData(
                  DataFlavor flavor) {
                if (isDataFlavorSupported(flavor)) {
                    return image;
                }
                return null;
              }

              public DataFlavor[] getTransferDataFlavors() {
                return flavors;
              }

              public boolean isDataFlavorSupported(
                  DataFlavor flavor) {
                return flavor.equals(
                    DataFlavor.imageFlavor);
              }
            };
            return transferable;
          }
        }
        return null;
      }

      public boolean importData(
          JComponent comp, Transferable t) {
        if (comp instanceof JLabel) {
          JLabel label = (JLabel)comp;
          if (t.isDataFlavorSupported(flavors[0])) {
            try {
              Image image = (
                  Image)t.getTransferData(flavors[0]);
              ImageIcon icon = new ImageIcon(image);
              label.setIcon(icon);
              return true;
            } catch (UnsupportedFlavorException ignored) {
            } catch (IOException ignored) {
            }
          }
        }
        return false;
      }
    }
</pre>

<p>
After the <code>ImageSelection</code> class is defined, you can create a program that supports transferring images. The following program does just that. 
</p>

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

    public class DragImage {

      public static void main(String args[]) {

        JFrame frame = new JFrame(&quot;Drag Image&quot;);
        frame.setDefaultCloseOperation(
            JFrame.EXIT_ON_CLOSE);
        Container contentPane = frame.getContentPane();

        final Clipboard clipboard =
          frame.getToolkit().getSystemClipboard();

        final JLabel label = new JLabel();
        if (args.length &gt; 0) {
          Icon icon = new ImageIcon(args[0]);
         label.setIcon(icon);
        }
        label.setTransferHandler(new ImageSelection());

        MouseListener mouseListener = 
            new MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            JComponent comp = (JComponent)e.getSource();
            TransferHandler handler = 
                comp.getTransferHandler();
            handler.exportAsDrag(
                comp, e, TransferHandler.COPY);
          }
        };
        label.addMouseListener(mouseListener);

        JScrollPane pane = new JScrollPane(label);
        contentPane.add(pane, BorderLayout.CENTER); 

        JButton copy = new JButton(&quot;Copy&quot;);
        copy.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
          // fire TransferHandler's built-in copy 
          // action with a new actionEvent having 
          // "label" as the source
          Action copyAction = 
              TransferHandler.getCopyAction();
          copyAction.actionPerformed(
            new ActionEvent(
               label, ActionEvent.ACTION_PERFORMED,
              (String)copyAction.getValue(Action.NAME),
              EventQueue.getMostRecentEventTime(),
              0));
         }
        });

        JButton clear = new JButton(&quot;Clear&quot;);
        clear.addActionListener(new ActionListener() {
          public void actionPerformed(
              ActionEvent actionEvent) {
            label.setIcon(null);
          }
        });
    
        JButton paste = new JButton(&quot;Paste&quot;);
        paste.addActionListener(new ActionListener() {
          public void actionPerformed(
              ActionEvent actionEvent) {
            // use TransferHandler's built-in 
            // paste action
            Action pasteAction = 
               TransferHandler.getPasteAction();
            pasteAction.actionPerformed(
               new ActionEvent(label,
              ActionEvent.ACTION_PERFORMED,
              (String)pasteAction.getValue(Action.NAME),
              EventQueue.getMostRecentEventTime(),
              0));
            }
        });

        JPanel p = new JPanel();
        p.add(copy);
        p.add(clear);
        p.add(paste);
        contentPane.add(p, BorderLayout.SOUTH);

        frame.setSize(300, 300);
        frame.show();
      }
    }
</pre>

<p>    
Notice how the copy and paste actions are just reusing the built-in behavior of the <code>TransferHandler</code>. By simply passing in the appropriate object to act as the source of the <code>ActionEvent</code>, the <code>TransferHandler</code> will invoke the <code>exportToClipboard</code> and <code>importDate</code> methods on that component, respectively. See the <a href="http://bulkmail2.sun.com/CTServlet?id=1048015041821">javadoc for the <code>TranferHandler</code> class</a> for more information on these methods. It is always possible to manually do this copy and paste behavior. However, since the system provides the behavior for you, why not reuse it? You just have to create the Action.
</p>

<p>   
Specify an image in the command line when you run the program. That will put an initial image into the <code>JLabel</code>. For example:
</p>

<pre> 
    java DragImage myimage.gif  
</pre>

<p>
The program supports five different copy/paste operations. The Copy button copies the image on the screen's <code>JLabel</code> to the system clipboard. The Paste button copies the image from the system clipboard to the <code>JLabel</code>. The Clear button clears the current image from the <code>JLabel</code>. The last two operations aren't obvious. One of these is that you can initiate a drag operation from the <code>JLabel</code> and drop it in anywhere that permits dropping images of the flavor supported by the Java runtime. For instance, you can drop an image into Microsoft Excel, but not Word. The other operation that isn't obvious is dropping an image onto the JLabel. When you do that, you'll see the image displayed on the <code>JLabel</code>. Try dragging an image from your browser onto the <code>JLabel</code>, and see what happens.
</p>

<p>
For more information about the the Drag and Drop enhancements in J2SE release 1.4, see &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1048015041835">Drag and Drop</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>DISCOVERING THE CALLING METHOD NAME</h3>

<p>
A common request for developers working with J2SE prior to version 1.4 was to programmatically determine the current location in a program, that is the current method. Typically, developers made this request for logging purposes. Developers still ask the same question today, that is, with J2SE v 1.4. However getting the answer is much more straightforward.
</p>

<p>
The old way of finding the current location in a program involved generating an exception, printing the stack trace to an in-memory buffer, and then reading back the trace to find out the specific information you were after. After removing the extraneous characters from the line, you're left with the specific method name, as shown here.
</p>

<pre>
    import java.io.*;

    public class ManualDump {
      public static void main(String args[]) 
          throws IOException {
            Throwable t = new Throwable();
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            t.printStackTrace(pw);
            String input = sw.getBuffer().toString();
            StringReader sr = new StringReader(input);
            BufferedReader br = new BufferedReader(sr);
            br.readLine(); // Exception name
            String line = br.readLine();
            int paren = line.indexOf('(');
            line = line.substring(0, paren);
            int period = line.lastIndexOf('.');
            line = line.substring(period+1);
            System.out.println(&quot;Method: &quot; + line);
          }
    }
</pre> 

<p>  
Running <code>ManualDump</code> displays:
</p>

<pre>
    Method: main     
</pre>

<p>
While the old way still works with J2SE version 1.4, there is a much cleaner way to parse stack dumps. A new feature in J2SE version 1.4 is the Chained Exception Facility. This facility allows you to say that Exception X was the cause of Exception Y. The facility also gives you the ability to go beyond printing a stack trace -- instead, you can get the trace and &quot;print&quot; it yourself. You simply call the new <code>getStackTrace</code> method of <code>Throwable</code>. This returns an array of <code>StackTraceElement</code> objects. A part of the class definition is the <code>getMethodName</code> method. The <code>StackTraceElement</code> at index zero is the current method:
</p>

<pre>
    public class AutoDump {
      public static void main(String args[]) {
        Throwable t = new Throwable();
        StackTraceElement elements[] = t.getStackTrace();
        String method = elements[0].getMethodName();
        System.out.println(&quot;Method: &quot; + method);
      }
    }
</pre>

<p>  
Running <code>AutoDump</code> displays:  
</p>

<pre>
    Method: main  
</pre>

<p>
With <code>getStackTrace</code> you can completely recreate the results of <code>printStackTrace</code>, or generate your own style of output. You are not limited to getting the method name.
</p>

<p>
You might think that with <code>StackTraceElement</code> you have everything you need, and technically you do. However, there is one more thing worth mentioning. If you are getting the method name for logging purposes, don't forget about the Java Logging APIs. The classes found in the <code>java.util.logging</code> package let you log away, and record what the current method is. More importantly the Java Logging APIs allow you to do that without you having to manually discover the method. These APIs were covered in the October 2002 issue of the Core Java Technologies Tech Tips in the tip titled &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1048015041852">Filtering Logged Messages</a>&quot;. You can look at the source for the <code>getSourceMethodName</code> method of <code>LogRecord</code> to see code similar to that used in the <code>AutoDump</code> example to fetch the given method name.
</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="MarCore_tt031803">
<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 programming? Use  
<a href="http://bulkmail2.sun.com/CTServlet?id=1048015041937">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 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).<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).<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=1048015041865"><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=1048015041865"><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=1048015041952"><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=1048015041967"><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">Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks or registered trademarks (<a href="http://www.sun.com/suntrademarks/"><span class="link">http://www.sun.com/suntrademarks/</span></a>) of Sun Microsystems, Inc. in the United States and other countries.<br><br>



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

<center>
<a href="http://bulkmail2.sun.com/CTServlet?id=1048015041967"><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?32061839-426309885">Please unsubscribe me from this newsletter.</a><img src="http://bulkmail2.sun.com/OTServlet?id=32061839-426309885" width=1 height=1></td></tr></table></body>
</html>

