Beruflich Dokumente
Kultur Dokumente
message text.
Let's look at an example. Here, you'll use a ChoiceFormat
(together with MessageFormat) 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.
Start by creating a resource bundle. To do this, create a file
named SampleResources.properties, and place the necessary
resources in it:
none=I have no cars in the garage.
one=I just bought one car.
many=I won the lottery and bought {0} cars.
Remember that the {0} in the last line is a placeholder. It means
replace this with a number used as an argument.
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 "Resource Bundles"
(http://java.sun.com/jdc/TechTips/1998/tt0521.html#tip2) for
additional information on using a ResourceBundle.
Next, create a Choice Format. A ChoiceFormat 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 "ranges" in the following array:
double limits[] = {0, 1, 2};
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.
Next, specify the formats for each MessageFormat string to use:
String
String
String
String
none = resourceBundle.getString("none");
one = resourceBundle.getString("one");
many = resourceBundle.getString("many");
formats[] = {none, one, many};
Notice that the formats are the strings in the resource bundle.
Now you can create the ChoiceFormat:
ChoiceFormat cf = new ChoiceFormat(limits, formats);
The ChoiceFormat class has a format method that you can use to go
directly from something like an integer to a formatted string.
However, because the "many" formatting string has a placeholder
(the {0}), you need to go from ChoiceFormat to MessageFormat. You
do this by creating a MessageFormat and telling the object to use
the ChoiceFormat as its formats:
0
1
2
3
4
/
/
/
/
/
I
I
I
I
I
have no cars in
just bought one
won the lottery
won the lottery
won the lottery
the garage.
car.
and bought 2 cars.
and bought 3 cars.
and bought 4 cars.
A D G
B E H
C F I
Top-to-bottom, right-to-left
G D A
H E B
I F C
What does this have to do with Swing and graphical interfaces?
When targeting an international market for your programs, you
should design considering their ComponentOrientation property.
Found in the java.awt package, the ComponentOrientation class
(http://java.sun.com/j2se/1.4.2/docs/api/java/awt/ComponentOrientation.html)
allows you to discover the current orientation for a Locale, and
design screens accordingly. You ask for the ComponentOrientation
of a Locale with the getOrientation(Locale) method. Then, you can
ask if that orientation is horizontal with the isHorizontal 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 isLeftToRight
method (left-to-right corresponds to both the Left-to-right and
Top-to-bottom, left-to-right grids above).
Why do you need to know the direction? One common reason is for
building screens. The BorderLayout class is commonly used to
create screens. Using the NORTH, SOUTH, EAST, and WEST constants,
you can place components on the top, bottom, left, or right sides.
And, you can place a component in the center with CENTER. But,
many people don't know, or at least don't bother using, another
set of constants: PAGE_START, PAGE_END, LINE_START, and LINE_END.
(Note that these names were simplified in J2SE 1.4 from the
earlier names that were added in the J2SE 1.2: BEFORE_FIRST_LINE
(PAGE_START), AFTER_LAST_LINE (PAGE_END), BEFORE_LINE_BEGINS
(LINE_START), and AFTER_LINE_ENDS (LINE_END).) Although EAST and
WEST might make perfect sense 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 WEST side for a right-to-left
language, but the EAST side for a left-to-right language. Instead
of adding that component with an orientation of EAST or WEST, you
should add it with a constraint of LINE_START. This will ensure
the correct internationalized behavior.
To illustrate the point, run the following program,
BorderOrientation. It will display two screens, one for a
US-English locale and another for an Israel-Hebrew locale.
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class BorderOrientation {
public static void main(String args[]) {
JFrame frame1 = new JFrame("US");
frame1.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
ComponentOrientation usOrientation =
ComponentOrientation.getOrientation(
Locale.US);
Container contentPane1 =
frame1.getContentPane();
contentPane1.setComponentOrientation(
usOrientation);
contentPane1.add(new JButton(
"LineEnd"), BorderLayout.LINE_END);
contentPane1.add(new JButton(
"LineStart"), BorderLayout.LINE_START);
contentPane1.add(new JButton(
"PageStart"), BorderLayout.PAGE_START);
contentPane1.add(new JButton(
"PageEnd"), BorderLayout.PAGE_END);
frame1.pack();
frame1.setLocation(100, 100);
frame1.show();
JFrame frame2 = new JFrame("Israel");
frame2.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
Locale israel = new Locale("he", "IL");
ComponentOrientation hebrewOrientation =
ComponentOrientation.getOrientation(israel);
Container contentPane2 =
frame2.getContentPane();
contentPane2.setComponentOrientation(
hebrewOrientation);
contentPane2.add(new JButton(
"LineEnd"), BorderLayout.LINE_END);
contentPane2.add(new JButton(
"LineStart"), BorderLayout.LINE_START);
contentPane2.add(new JButton(
"PageStart"), BorderLayout.PAGE_START);
contentPane2.add(new JButton(
"PageEnd"), BorderLayout.PAGE_END);
frame2.pack();
frame2.setLocation(200, 200);
frame2.show();
}
}
For simplicity, the previous example used hard-coded strings for
button labels. Remember that in "real" internationalized programs,
button labels should come from resource bundles.
You don't always have to build screens differently based on the
locale and its associated component orientation. Containers using
FlowLayout, 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 JTree, reorient the tree to the other side of
the display when the orientation is right-to-left. For example,
run the following program, TreeSample. Notice that for the
right-to-left component orientation, the JTree displays a
"flipped" tree.
import java.awt.*;
import javax.swing.*;
(http://developer.java.sun.com/subscription/),
choose the newsletters you want to subscribe to and click
"Update".
- To unsubscribe, go to the subscriptions page,
(http://developer.java.sun.com/subscription/),
uncheck the appropriate checkbox, and click "Update".
- To use our one-click unsubscribe facility, see the link at
the end of this email:
- ARCHIVES
You'll find the Core Java Technologies Tech Tips archives at:
http://java.sun.com/jdc/TechTips/index.html
- COPYRIGHT
Copyright 2003 Sun Microsystems, Inc. All rights reserved.
4150 Network Circle, Santa Clara, California 95054 USA.
This document is protected by copyright. For more information, see:
http://java.sun.com/jdc/copyright.html
Core Java Technologies Tech Tips
September 26, 2003
Trademark Information: http://www.sun.com/suntrademarks/
Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks
or registered trademarks of Sun Microsystems, Inc. in the
United States and other countries.