Return-Path: <env_44006826-1316630966@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; Fri, 26 Sep 2003 14:38:33 -0400
X-Sieve: CMU Sieve 2.2
Received: from fort-point-station.mit.edu by po10.mit.edu (8.12.4/4.7) id h8QIaNvR023800; Fri, 26 Sep 2003 14:38:27 -0400 (EDT)
Received: from hermes.sun.com (hermes.sun.com [64.124.140.169])
	by fort-point-station.mit.edu (8.12.4/8.9.2) with SMTP id h8QIVb4b022749
	for <alexp@mit.edu>; Fri, 26 Sep 2003 14:31:38 -0400 (EDT)
Date: 26 Sep 2003 09:31:18 -0800
From: "SDN - Core Java Technologies Tech Tips" <sunmail@hermes.sun.com>
To: alexp@mit.edu
Message-Id: <44006826-1316630966@hermes.sun.com>
Subject: Core Java Technologies Tech Tips, September 26, 2003 (Using ChoiceFormat, Component Orientation in Swing)
Mime-Version: 1.0
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: SunMail 1.0
X-Spam-Score: 1.9
X-Spam-Level: * (1.9)
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=44006826-1316630966:1064593140811"><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=44006826-1316630966:1064593140824" style="text-decoration:none;">View this issue as simple text</a></td>
<td align="right" height="20"><span class="purple">September 26, 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, September 9, 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="-">Using ChoiceFormat for Handling Plural Messages</a><br>    
<a href="#2"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt="-">Component Orientation in Swing User Interfaces</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>

<p>
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.
</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>USING CHOICEFORMAT FOR HANDLING PLURAL MESSAGES</h3>

<p>
The August 19, 2003 Tech Tip titled &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140650">Formatting Messages With Variable Content</a>&quot; described how to use the <code>MessageFormat</code> class of the <code>java.text</code> package to create internationalized error messages that contain variable content. Using the <code>MessageFormat</code> class is a good approach when most of the message stays the same, and you can simply &quot;fill in in the blanks&quot; to complete the variable part of the message. But the approach doesn't work particularly well in situations where part of the error message is a quantity, and you need to follow it with a noun that matches the quantity.
</p>

<p>
Matching nouns to quantities is tricky in English. Case in point: when the count of something is zero, the word it modifies is plural, as in &quot;I have no cars in the garage.&quot; (Cars is plural here, even though you have zero of them.) When the count is one, the word it modifies is singular, as in &quot;I just bought one car.&quot; And with more than one, the modified word is plural again: &quot;I won the lottery and bought twelve cars.&quot;
</p>

<p>
This suggests that matching nouns to quantities is also tricky when you display localized error messages, especially when you want to display slightly different messages based on a quantity. However the <code>java.text</code> package includes a class, <a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140676">ChoiceFormat</a>, that handles the mapping of quantities to messages. You use the results produced by <code>ChoiceFormat</code> in conjunction with a <code>MessageFormat</code> object to generate the appropriate quantified message text.
</p>

<p>
Let's look at an example. Here, you'll use a <code>ChoiceFormat</code> (together with <code>MessageFormat</code>) to display the correct message for a given quantity. Specifically, you'll display an English message that contains the correct noun plural for the quantities zero, one, and more than one.
</p>

<p>
Start by creating a resource bundle. To do this, create a file named <code>SampleResources.properties</code>, and place the necessary resources in it:
</p>

<pre>
   none=I have no cars in the garage.
   one=I just bought one car.
   many=I won the lottery and bought {0} cars.
</pre>

<p>
Remember that the <code>{0}</code> in the last line is a placeholder. It means replace this with a number used as an argument.
</p>

<p>
This example is for English only. You need to provide a similar file for every language you want to support. See the May 21, 1998 Tech Tip titled "<a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140696">Resource Bundles</a>" for additional information on using a <code>ResourceBundle</code>.
</p>

<p>
Next, create a <code>ChoiceFormat</code>. A <code>ChoiceFormat</code> allows you to attach a format to a range of numbers. To specify the range, you create an array of ranges for the formats. In this example, you want one format for 0, another format for 1, and yet another format for 2 and beyond. You can specify these &quot;ranges&quot; in the following array:
</p>

<pre>
   double limits[] = {0, 1, 2};
</pre>

<p>
Although the array doesn't look as though it specifies ranges, it actually does. Technically, the array specification means: for ranges from 0 to just below 1, use the first format; for 1 to just below 2 use the next; and for 2 and above use the last. However, because the example uses only integer values for the value to print, you don't have to consider this technicality yet.
</p>

<p>
Next, specify the formats for each <code>MessageFormat</code> string to use: 
</p>

<pre>
   String none = resourceBundle.getString(&quot;none&quot;);
   String one = resourceBundle.getString(&quot;one&quot;);
   String many = resourceBundle.getString(&quot;many&quot;);
   String formats[] = {none, one, many};
</pre>

<p>  
Notice that the formats are the strings in the resource bundle.  
</p>

<p>
Now you can create the <code>ChoiceFormat</code>:
</p>

<pre>
   ChoiceFormat cf = new ChoiceFormat(limits, formats);
</pre>

<p>
The <code>ChoiceFormat</code> class has a format method that you can use to go directly from something like an integer to a formatted string. However, because the &quot;many&quot; formatting string has a placeholder (<code>the {0}</code>), you need to go from <code>ChoiceFormat</code> to <code>MessageFormat</code>. You do this by creating a <code>MessageFormat</code> and telling the object to use the <code>ChoiceFormat</code> as its formats:
</p>

<pre>
   MessageFormat mf = new MessageFormat(&quot;{0}&quot;);
   mf.setFormats(new Format[]{cf});
</pre>

<p>
The first line says create a <code>MessageFormat</code> object, where the entire content is provided by the formats. The second argument is the array of formatting objects, that is, the single <code>ChoiceFormat</code> object. The <code>{0}</code> in the <code>MessageFormat</code> maps into the <code>ChoiceFormat</code>. The <code>{0}</code> in the specific <code>ChoiceFormat</code> selected is the argument provided to the <code>MessageFormat</code>'s format method. 
</p>

<p>
Next, add a <code>for</code> loop, and loop from 0 to 4:
</p>

<pre>
   for (int i=0; i&lt;5; i++) {
     Object messageArgs[] = {new Integer(i)};
     System.out.println(&quot;i: &quot; + i + &quot; / &quot; +
       mf.format(messageArgs));
   }
</pre>

<p>
For each pass through the loop, create an <code>Integer</code> for the loop index, and tell the <code>MessageFormat</code> to format the output string. The <code>MessageFormat</code> then determines which <code>ChoiceFormat</code> object to use, and passes its argument to the <code>ChoiceFormat</code> for formatting of the message. 
</p>

<p>
Here's what the complete example looks like:
</p>

<pre>
   import java.text.*;
   import java.util.*;

   public class ChoiceFormatExample {
     public static void main (String args[]) {
       ResourceBundle resourceBundle =
         ResourceBundle.getBundle(
                         &quot;SampleResources&quot;, Locale.US);
       double limits[] = {0, 1, 2};
       String none = resourceBundle.getString(&quot;none&quot;);
       String one = resourceBundle.getString(&quot;one&quot;);
       String many = resourceBundle.getString(&quot;many&quot;);
       String formats[] = {none, one, many};
       ChoiceFormat cf = 
                     new ChoiceFormat(limits, formats);
       MessageFormat mf = new MessageFormat(&quot;{0}&quot;);
       mf.setFormats(new Format[]{cf});
       for (int i=0; i&lt;5; i++) {
         Object messageArgs[] = {new Integer(i)};
         System.out.println(&quot;i: &quot; + i + &quot; / &quot; +
           mf.format(messageArgs));
       }
     }
   }
</pre>

<p>
When you run the example program, you should see the following displayed:
</p>

<pre>
   i: 0 / I have no cars in the garage.
   i: 1 / I just bought one car.
   i: 2 / I won the lottery and bought 2 cars.
   i: 3 / I won the lottery and bought 3 cars.
   i: 4 / I won the lottery and bought 4 cars.
</pre>

<p>
There's more to <code>ChoiceFormat</code> than what's presented through this simple example. First, recall the technicality that was previously mentioned about the ranges in the limits array. Instead of specifically saying 2 for the third argument in the array, you could specify the next double after the value 1. You might think this is something like 1.00000000001, however there is a simpler way to specify the next double value. The <code>ChoiceFormat</code> class offers a <code>nextDouble</code> method for this exact purpose. Using <code>nextDouble</code>, you can specify the next double value as follows:
</p>

<pre>
   {0, 1, ChoiceFormat.nextDouble(1)}
</pre>

<p>
There is even a <code>previousDouble</code> method for specifying the previous double value.
</p>

<p>
In addition, the <code>ChoiceFormat</code> constructor allows you to specify all the formats in one string -- the string is parsed into its component pieces. Here, each limit is separated by the pipe (|) character, and each limit itself is specified by either a #, &lt;, or &gt; character. In other words, you could specify the previous set of resource strings in the following single line (for readability, the formats are shown below on two lines):
</p>

<pre>
   0#I have no cars in the garage.|1#I just bought
   one car.|1&lt;I won the lottery and bought {0} cars.
</pre>

<p>
This translates to: for the number 0, use &quot;I have no cars in the garage.&quot; For the number 1, use &quot;I just bought one car.&quot; For everything greater than 1, use &quot;I won the lottery and bought {0} cars.&quot;
</p>

<p>
Let's look at one more example. This example doesn't use a <code>MessageFormat</code>. Instead, it simply uses <code>ChoiceFormat</code> to map an array of limits to a specific string.
</p>

<p>
The limits are from 0-5, 5-10, and beyond 10:
</p>

<pre>
  double limits[] = {0, 5, 10};
</pre>

<p>
The strings are Low, Medium, and High:
</p>

<pre>
  String formats[] = {&quot;Low&quot;, &quot;Medium&quot;, &quot;High&quot;};
</pre>

<p>
Taking these two arrays, you again create the <code>ChoiceFormat</code>:
</p>

<pre>
  ChoiceFormat cf = new ChoiceFormat(limits, formats);
</pre>

<p>
Here's the complete example. It takes a number from the command line, and use the <code>ChoiceFormat</code> to display the appropriate message.
</p>

<pre>
   import java.text.*;

   public class Choice2 {
     public static void main(String args[]) {
       if (args.length == 0) {
         System.err.println(
              &quot;Please provide a number when starting&quot;);
         System.exit(-1);
       }
       double limits[] = {0, 5, 10};
       String formats[] = {&quot;Low&quot;, &quot;Medium&quot;, &quot;High&quot;};
       ChoiceFormat cf = 
                    new ChoiceFormat(limits, formats);
       System.out.println(cf.format(
                          Integer.parseInt(args[0])));
     }
   }
</pre>

<p>
Run the example program with an argument of 3 to produce an output of Low, with 5 to display Medium, and an argument above 10 to display High.
</p>

<pre>
   java Choice2 3
   Low

   java Choice2 5
   Medium

   java Choice2 13
   High
</pre>

<p>
<code>ResourceBundle</code>, <code>MessageFormat</code>, and <code>ChoiceFormat</code> give you the capabilities you need to properly localize both variable and quantified text.
</p>

<p>
For more information on internationalizing your applications, see the <a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140716">Internationalization trail</a> in the Java Tutorial.
</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>COMPONENTORIENTATION IN SWING USER INTERFACES</h3>

<p>
One of the often-overlooked aspects of internationalization is component orientation. While English and the Western European languages have letters and words that go left-to-right and top-to-bottom, not all do. For instance, many Middle Eastern languages such as Hebrew and Arabic are right-to-left, top-to-bottom. Others such as Mongolian are top-to-bottom first, then right-to-left. And Far Eastern languages such as Japanese, Chinese, and Korean can be either like the Western European ones or more appropriately top-to-bottom, right-to-left.
</p>

<p>
Here's an aid to visualize the differences. For a 3x3 grid of characters:
</p>

<p>
Left-to-right, top-to-bottom
</p>

<pre>
  A B C
  D E F
  G H I
</pre>

<p>  
Right-to-left, top-to-bottom
</p>

<pre>
  C B A
  F E D
  I H G
</pre>

<p>  
Top-to-bottom, left-to-right
</p>

<pre>
  A D G
  B E H
  C F I
</pre>

<p>  
Top-to-bottom, right-to-left
</p>

<pre>
  G D A
  H E B
  I F C
</pre>

<p>
What does this have to do with Swing and graphical interfaces? When targeting an international market for your programs, you should design considering their <code>ComponentOrientation</code> property.
</p>

<p>
Found in the <code>java.awt</code> package, the <a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140741">ComponentOrientation class</a> allows you to discover the current orientation for a <code>Locale</code>, and design screens accordingly. You ask for the <code>ComponentOrientation</code> of a <code>Locale</code> with the <code>getOrientation(Locale)</code> method. Then, you can ask if that orientation is horizontal with the <code>isHorizontal</code> method (horizontal corresponds to both the Left-to-right, top-to-bottom, and Right-to-left, top-to-bottom grids shown above). You can also ask if the orientation is left-to-right with the <code>isLeftToRight</code> method (left-to-right corresponds to both the Left-to-right and Top-to-bottom, left-to-right grids above).
</p>

<p>
Why do you need to know the direction? One common reason is for building screens. The <code>BorderLayout</code> class is commonly used to create screens. Using the <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>, and <code>WEST</code> constants, you can place components on the top, bottom, left, or right sides. And, you can place a component in the center with <code>CENTER</code>. But, many people don't know, or at least don't bother using, another set of constants: <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>. (Note that these names were simplified in J2SE 1.4 from the earlier names that were added in the J2SE 1.2: <code>BEFORE_FIRST_LINE</code> (<code>PAGE_START</code>), <code>AFTER_LAST_LINE</code> (<code>PAGE_END</code>), <code>BEFORE_LINE_BEGINS</code> (<code>LINE_START</code>), and <code>AFTER_LINE_ENDS</code> (<code>LINE_END</code>).) Although <code>EAST</code> and <code>WEST</code> might make perfect sen!
 se for a Roman language, they don't necessarily make sense for other languages. For example, if you need to place a component at the beginning of the line, that component would need to be on the <code>WEST</code> side for a right-to-left language, but the <code>EAST</code> side for a left-to-right language. Instead of adding that component with an orientation of <code>EAST</code> or <code>WEST</code>, you should add it with a constraint of <code>LINE_START</code>. This will ensure the correct internationalized behavior. 
</p>

<p>
To illustrate the point, run the following program, <code>BorderOrientation</code>. It will display two screens, one for a US-English locale and another for an Israel-Hebrew locale.
</p>

<p>
<img src="http://developer.java.sun.com/developer/JDCTechTips/images/tt092603_comporntUS.gif" width="176" height="110" border="0" alt="comporntUS">
<br><br>
<img src="http://developer.java.sun.com/developer/JDCTechTips/images/tt092603_comporntIsr.gif" width="176" height="110" border="0" alt="comporntIsr">
</p>

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

   public class BorderOrientation {
      public static void main(String args[]) {
        JFrame frame1 = new JFrame(&quot;US&quot;);
        frame1.setDefaultCloseOperation(
                                 JFrame.EXIT_ON_CLOSE);
        ComponentOrientation usOrientation =
          ComponentOrientation.getOrientation(
                                            Locale.US);
        Container contentPane1 = 
                               frame1.getContentPane();
        contentPane1.setComponentOrientation(
                                        usOrientation);
        contentPane1.add(new JButton(
                    &quot;LineEnd&quot;), BorderLayout.LINE_END);
        contentPane1.add(new JButton(
                &quot;LineStart&quot;), BorderLayout.LINE_START);
        contentPane1.add(new JButton(
                &quot;PageStart&quot;), BorderLayout.PAGE_START);
        contentPane1.add(new JButton(
                    &quot;PageEnd&quot;), BorderLayout.PAGE_END);
        frame1.pack();
        frame1.setLocation(100, 100);
        frame1.show();

        JFrame frame2 = new JFrame(&quot;Israel&quot;);
        frame2.setDefaultCloseOperation(
                                 JFrame.EXIT_ON_CLOSE);
        Locale israel = new Locale(&quot;he&quot;, &quot;IL&quot;);
        ComponentOrientation hebrewOrientation =
          ComponentOrientation.getOrientation(israel);
        Container contentPane2 = 
                              frame2.getContentPane();
        contentPane2.setComponentOrientation(
                                    hebrewOrientation);
        contentPane2.add(new JButton(
                      &quot;LineEnd&quot;), BorderLayout.LINE_END);
        contentPane2.add(new JButton(
                  &quot;LineStart&quot;), BorderLayout.LINE_START);
        contentPane2.add(new JButton(
                  &quot;PageStart&quot;), BorderLayout.PAGE_START);
        contentPane2.add(new JButton(
                      &quot;PageEnd&quot;), BorderLayout.PAGE_END);
        frame2.pack();
        frame2.setLocation(200, 200);
        frame2.show();
      }
   }
</pre>

<p>
For simplicity, the previous example used hard-coded strings for button labels. Remember that in &quot;real&quot; internationalized programs, button labels should come from resource bundles.
</p>

<p>
You don't always have to build screens differently based on the locale and its associated component orientation. Containers using <code>FlowLayout</code>, for instance, will draw their components in the reverse order when the orientation is right-to-left. Some components, such as the text components, will lay out their contents accordingly, based on their orientation setting. Other components, such as <code>JTree</code>, reorient the tree to the other side of the display when the orientation is right-to-left. For example, run the following program, <code>TreeSample</code>. Notice that for the right-to-left component orientation, the <code>JTree</code> displays a &quot;flipped&quot; tree.
</p>

<p>
<img src="http://developer.java.sun.com/developer/JDCTechTips/images/tt092603_fliptree.gif" width="300" height="200" border="0" alt="fliptree">
</p>

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

   public class TreeSample {
      public static void main (String args[]) {
        JFrame f = new JFrame(&quot;Flipped&quot;);
        f.setDefaultCloseOperation(
                                 JFrame.EXIT_ON_CLOSE);
        Container content = f.getContentPane();
        JTree tree = new JTree();
        tree.setComponentOrientation(
                   ComponentOrientation.RIGHT_TO_LEFT);
        JScrollPane scrollPane = new JScrollPane(tree);
        content.add(scrollPane, BorderLayout.CENTER);
        f.setSize (300, 200);
        f.show();
      }
   }
</pre>

<p>
Other <code>AWT</code> and <code>Swing</code> components also reorient their content based on the current component orientation setting. For a <code>JTable</code>, column order is reversed when the orientation is right-to-left. With a <code>JMenuBar</code>, the menus are reversed. For instance, the <code>File</code> menu, typically found on the far left, is on the other side when reversed. As a developer, you don't have to do anything differently to manipulate these components, you just need to be aware that not everything will appear the way you expect it to. <code>JOptionPane</code> is probably one of the exceptions -- its definition states the location of its various elements.
</p>

<p>
For more information on <code>ComponentOrientation</code> in <code>Swing</code> see the article &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140761">Component Orientation in Swing: How JFC Components Support 'BIDI' Text</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 -->

<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="SeptCore_tt092603">
<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=44006826-1316630966:1064593140848">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="http://developers.sun.com/contact/feedback.jsp?category=sdn"><span class="link">http://developers.sun.com/contact/feedback.jsp?category=sdn</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://developer.java.sun.com/subscription/"><span class="link">subscribe</span></a> to and click &quot;Update&quot;.<br>
  - To unsubscribe, go to the <a href="http://developer.java.sun.com/subscription/"><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=44006826-1316630966:1064593140871"><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=44006826-1316630966:1064593140908"><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.</span>
<br><br>

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

<center>
<a href="http://bulkmail2.sun.com/CTServlet?id=44006826-1316630966:1064593140908"><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>

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


