_chapter 10.htm
来自「Core Java 2(中文名称:JAVA 2 核心技术 卷二:高级特性)这是英」· HTM 代码 · 共 1,361 行 · 第 1/4 页
HTM
1,361 行
30. {
31. setSize(WIDTH, HEIGHT);
32. setTitle("NumberFormatTest");
33.
34. getContentPane().setLayout(new GridBagLayout());
35.
36. ActionListener listener = new
37. ActionListener()
38. {
39. public void actionPerformed(ActionEvent event)
40. {
41. updateDisplay();
42. }
43. };
44.
45. JPanel p = new JPanel();
46. addRadioButton(p, numberRadioButton, rbGroup, listener);
47. addRadioButton(p, currencyRadioButton, rbGroup, listener);
48. addRadioButton(p, percentRadioButton, rbGroup, listener);
49.
50. GridBagConstraints gbc = new GridBagConstraints();
51. gbc.fill = GridBagConstraints.NONE;
52. gbc.anchor = GridBagConstraints.EAST;
53. add(new JLabel("Locale"), gbc, 0, 0, 1, 1);
54. add(p, gbc, 1, 1, 1, 1);
55. add(parseButton, gbc, 0, 2, 1, 1);
56. gbc.anchor = GridBagConstraints.WEST;
57. add(localeCombo, gbc, 1, 0, 1, 1);
58. gbc.fill = GridBagConstraints.HORIZONTAL;
59. add(numberText, gbc, 1, 2, 1, 1);
60.
61. locales = NumberFormat.getAvailableLocales();
62. for (int i = 0; i < locales.length; i++)
63. localeCombo.addItem(locales[i].getDisplayName());
64. localeCombo.setSelectedItem(
65. Locale.getDefault().getDisplayName());
66. currentNumber = 123456.78;
67. updateDisplay();
68.
69. localeCombo.addActionListener(listener);
70.
71. parseButton.addActionListener(new
72. ActionListener()
73. {
74. public void actionPerformed(ActionEvent event)
75. {
76. String s = numberText.getText();
77. try
78. {
79. Number n = currentNumberFormat.parse(s);
80. if (n != null)
81. {
82. currentNumber = n.doubleValue();
83. updateDisplay();
84. }
85. else
86. {
87. numberText.setText("Parse error: " + s);
88. }
89. }
90. catch(ParseException e)
91. {
92. numberText.setText("Parse error: " + s);
93. }
94. }
95. });
96. }
97.
98. /**
99. A convenience method to add a component to given grid bag
100. layout locations.
101. @param c the component to add
102. @param gbc the grid bag constraints to use
103. @param x the x grid position
104. @param y the y grid position
105. @param w the grid width
106. @param h the grid height
107. */
108. public void add(Component c, GridBagConstraints gbc,
109. int x, int y, int w, int h)
110. {
111. gbc.gridx = x;
112. gbc.gridy = y;
113. gbc.gridwidth = w;
114. gbc.gridheight = h;
115. getContentPane().add(c, gbc);
116. }
117.
118. /**
119. Adds a radio button to a container.
120. @param p the container into which to place the button
121. @param b the button
122. @param g the button group
123. @param listener the button listener
124. */
125. public void addRadioButton(Container p, JRadioButton b,
126. ButtonGroup g, ActionListener listener)
127. {
128. b.setSelected(g.getButtonCount() == 0);
129. b.addActionListener(listener);
130. g.add(b);
131. p.add(b);
132. }
133.
134. /**
135. Updates the display and formats the number according
136. to the user settings.
137. */
138. public void updateDisplay()
139. {
140. Locale currentLocale = locales[
141. localeCombo.getSelectedIndex()];
142. currentNumberFormat = null;
143. if (numberRadioButton.isSelected())
144. currentNumberFormat
145. = NumberFormat.getNumberInstance(currentLocale);
146. else if (currencyRadioButton.isSelected())
147. currentNumberFormat
148. = NumberFormat.getCurrencyInstance(currentLocale);
149. else if (percentRadioButton.isSelected())
150. currentNumberFormat
151. = NumberFormat.getPercentInstance(currentLocale);
152. String n = currentNumberFormat.format(currentNumber);
153. numberText.setText(n);
154. }
155.
156. private Locale[] locales;
157.
158. private double currentNumber;
159.
160. private JComboBox localeCombo = new JComboBox();
161. private JButton parseButton = new JButton("Parse");
162. private JTextField numberText = new JTextField(30);
163. private JRadioButton numberRadioButton
164. = new JRadioButton("Number");
165. private JRadioButton currencyRadioButton
166. = new JRadioButton("Currency");
167. private JRadioButton percentRadioButton
168. = new JRadioButton("Percent");
169. private ButtonGroup rbGroup = new ButtonGroup();
170. private NumberFormat currentNumberFormat;
171. private static final int WIDTH = 400;
172. private static final int HEIGHT = 200;
173. }
</pre>
<h4 class="docSection2Title" id="ch10lev2sec2"><tt>java.text.NumberFormat</tt></h4>
<p><img alt="graphics/api.gif" src="api.gif" border="0" width="46" height="45"><br>
</p>
<ul>
<li>
<p class="docList"><tt>static Locale[] getAvailableLocales()</tt></p>
<p class="docList">returns an array of <tt>Locale</tt> objects for which <tt>
NumberFormat</tt> formatters are available.</li>
<li>
<p class="docList"><tt>static NumberFormat getNumberInstance()</tt></li>
<li>
<p class="docList"><tt>static NumberFormat getNumberInstance(Locale l)</tt></li>
<li>
<p class="docList"><tt>static NumberFormat getCurrencyInstance()</tt></li>
<li>
<p class="docList"><tt>static NumberFormat getCurrencyInstance(Locale l)</tt></li>
<li>
<p class="docList"><tt>static NumberFormat getPercentInstance()</tt></li>
<li>
<p class="docList"><tt>static NumberFormat getPercentInstance(Locale l)</tt></p>
<p class="docList">return a formatter for numbers, currency amounts, or
percentage values for the current locale or for the given locale.</li>
<li>
<p class="docList"><tt>String format(double x)</tt></li>
<li>
<p class="docList"><tt>String format(long x)</tt></p>
<p class="docList">return the string resulting from formatting the given
floating-point number or integer.</li>
<li>
<p class="docList"><tt>Number parse(String s)</tt></p>
<p class="docList">parses the given string and returns the number value, as a
<tt>Double</tt> if the input string described a floating-point number, and as
a <tt>Long</tt> otherwise. The beginning of the string must contain a number;
no leading white space is allowed. The number can be followed by other
characters, which are ignored. Throws a <tt>ParseException</tt> if parsing was
not successful.</li>
<li>
<p class="docList"><tt>void setParseIntegerOnly(boolean b)</tt></li>
<li>
<p class="docList"><tt>boolean isParseIntegerOnly()</tt></p>
<p class="docList">set or get a flag to indicate whether this formatter should
parse only integer values.</li>
<li>
<p class="docList"><tt>void setGroupingUsed(boolean b)</tt></li>
<li>
<p class="docList"><tt>boolean isGroupingUsed()</tt></p>
<p class="docList">set or get a flag to indicate whether this formatter emits
and recognizes decimal separators (such as <tt>100,000</tt>).</li>
<li>
<p class="docList"><tt>void setMinimumIntegerDigits(int n)</tt></li>
<li>
<p class="docList"><tt>int getMinimumIntegerDigits()</tt></li>
<li>
<p class="docList"><tt>void setMaximumIntegerDigits(int n)</tt></li>
<li>
<p class="docList"><tt>int getMaximumIntegerDigits()</tt></li>
<li>
<p class="docList"><tt>void setMinimumFractionDigits(int n)</tt></li>
<li>
<p class="docList"><tt>int getMinimumFractionDigits()</tt></li>
<li>
<p class="docList"><tt>void setMaximumFractionDigits(int n)</tt></li>
<li>
<p class="docList"><tt>int getMaximumFractionDigits()</tt></p>
<p class="docList">set or get the maximum or minimum number of digits allowed
in the integer or fractional part of a number.</li>
</ul>
<h3 class="docSection1Title" id="c10s3">Date and Time</h3>
<p class="docText">When you are formatting date and time, there are four
locale-dependent issues you need to worry about:</p>
<ul>
<li>
<p class="docList">The names of months and weekdays should be presented in the
local language.</li>
<li>
<p class="docList">There will be local preferences for the order of year,
month, and day.</li>
<li>
<p class="docList">The Gregorian calendar may not be the local preference for
expressing dates.</li>
<li>
<p class="docList">The time zone of the location must be taken into account.</li>
</ul>
<p class="docText">The Java <tt>DateFormat</tt> class handles these issues. It
is easy to use and quite similar to the <tt>NumberFormat</tt> class. First, you
get a locale. You can use the default locale or call the static <tt>
getAvailableLocales</tt> method to obtain an array of locales that support date
formatting. Then, you call one of the three factory methods:</p>
<pre>fmt = DateFormat.getDateInstance(dateStyle, loc);
fmt = DateFormat.getTimeInstance(timeStyle, loc);
fmt = DateFormat.getDateTimeInstance(dateStyle, timeStyle, loc);
</pre>
<p class="docText">To specify the desired style, these factory methods have a
parameter that is one of the following constants:</p>
<blockquote>
<p class="docList"><tt>DateFormat.DEFAULT</tt></p>
<p class="docList"><tt>DateFormat.FULL</tt> (e.g., Thursday, September 18,
1997 8:42:46 o'clock A.M.PDT for the U.S. locale)</p>
<p class="docList"><tt>DateFormat.LONG</tt> (e.g., September 18, 1997 8:42:46
A.M. PDT for the U.S. locale)</p>
<p class="docList"><tt>DateFormat.MEDIUM</tt> (e.g., Sep 18, 1997 8:42:46 A.M.
for the U.S. locale)</p>
<p class="docList"><tt>DateFormat.SHORT</tt> (e.g., 9/18/97 8:42 A.M. for the
U.S. locale)</p>
</blockquote>
<p class="docText">The factory method returns a formatting object that you can
then use to format dates.</p>
<pre>Date now = new Date();
String s = fmt.format(now);
</pre>
<p class="docText">Just as with the <tt>NumberFormat</tt> class, you can use the
<tt>parse</tt> method to parse a date that the user typed. For example, the
following code parses the value that the user typed into a text field.</p>
<pre>TextField inputField;
. . .
DateFormat fmt = DateFormat.getDateInstance(DateFormat.MEDIUM);
// get date formatter for default locale
Date input = fmt.parse(inputField.getText().trim());
</pre>
<p class="docText">If the number was not typed correctly, this code throws a <tt>
ParseException</tt>. Note that leading white space in the string is
<span class="docEmphasis">not</span> allowed here, either. You should again call
<tt>trim</tt> to remove it. However, any characters that follow the number in
the string will again be ignored. Unfortunately, the user must type the date
exactly in the expected format. For example, if the format is set to <tt>MEDIUM</tt>
in the U.S. locale, then dates are expected to look like</p>
<pre>Sep 18, 1997
</pre>
<p class="docText">If the user types</p>
<pre>Sep 18 1997
</pre>
<p class="docText">(without the comma) or the short format</p>
<pre>9/18/97
</pre>
<p class="docText">then a parse error results.</p>
<p class="docText">A <tt>lenient</tt> flag interprets dates leniently. For
example, <tt>February 30, 1999</tt> will be automatically converted to <tt>March
2, 1999</tt>. This seems dangerous, but, unfortunately, it is the default. You
should probably turn off this feature. The calendar object that is used to
interpret the parsed date will throw an <tt>IllegalArgumentException</tt> when
the user enters an invalid day/month/year combination.</p>
<p class="docText"><a class="docLink" href="#ch10list02">Example 10-2</a> shows
the <tt>DateFormat</tt> class in action. You can select a locale and see how the
date and time are formatted in different places around the world. If you see
question-mark characters in the output, then you don't have the fonts installed
for displaying characters in the local language. For example, if you pick a
Chinese locale, the date may be expressed as</p>
<pre>1997?9?19?
</pre>
<p class="docText"><a class="docLink" href="#ch10fig02">Figure 10-2</a> shows
the program running under Chinese Windows; as you can see, it correctly displays
the output.</p>
<center>
<h5 id="ch10fig02" class="docFigureTitle">Figure 10-2. The <tt>DateFormatTest</tt> program
running under Chinese Windows</h5>
<p>
<img alt="graphics/10fig02.gif" src="10fig02.gif" border="0" width="402" height="202"><br>
</p>
</center>
<p class="docText">You can also experiment with parsing. Type in a date or time,
click the Parse lenient checkbox if desired, and click on the Parse date or
Parse time button.</p>
<p class="docText">The only mysterious feature about the code is probably the
<tt>EnumCombo</tt> class. We used this class to solve the following technical
problem. We wanted to fill a combo with values such as <tt>Short</tt>, <tt>
Medium</tt>, and <tt>Long</tt> and then automatically convert the user's
selection to integer values <tt>DateFormat.SHORT</tt>, <tt>DateFormat.MEDIUM</tt>,
and <tt>DateFormat.LONG</tt>. To do this, we convert the user's choice to upper
case, replace all spaces with underscores, and then use reflection to find the
value of the static field with that name. (See Chapter 5 of Volume 1 for more
details about reflection.)</p>
<h5 id="ch10list02" class="docExampleTitle">Example 10-2 DateFormatTest.java</h5>
<pre> 1. import java.awt.*;
2. import java.awt.event.*;
3. import java.text.*;
4. import java.util.*;
5. import javax.swing.*;
6.
7. /**
8. This program demonstrates formatting dates under
9. various locales.
10. */
11. public class DateFormatTest
12. {
13. public static void main(String[] args)
14. {
15. JFrame frame = new DateFormatFrame();
16. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
17. frame.show();
18. }
19. }
20.
21. /**
22. This frame contains combo boxes to pick a locale, date and
23. time formats, text fields to display formatted date and time,
24. buttons to parse the text field contents, and a "lenient"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?