30. MVC and Swing Models

 
[Page 875 ( continued )]

26.4. Formatting Numbers

Formatting numbers is highly locale-dependent. For example, number 5000.555 is displayed as 5,000.555 in the United States, but as 5 000,555 in France and as 5.000,555 in Germany.

Numbers are formatted using the java.text.NumberFormat class, an abstract base class that provides the methods for formatting and parsing numbers, as shown in Figure 26.8.

Figure 26.8. The NumberFormat class provides the methods for formatting and parsing numbers.
(This item is displayed on page 876 in the print version)

With NumberFormat , you can format and parse numbers for any locale. Your code will be completely independent of locale conventions for decimal points, thousands-separators, currency format, and percentage formats.


[Page 876]

26.4.1. Plain Number Format

You can get an instance of NumberFormat for the current locale using NumberFormat.getInstance() or NumberFormat.getNumberInstance and for the specified locale using NumberFormat.getInstance(Locale) or NumberFormat.getNumberInstance(Locale) . You can then invoke format(number) on the NumberFormat instance to return a formatted number as a string.

For example, to display number 5000.555 in France, use the following code:

 NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE); System.out.println(numberFormat.format(   5000.555   )); 

You can control the display of numbers with such methods as setMaximumFractionDigits and setMinimumFractionDigits . For example, 5000.555 would be displayed as 5000.6 if you use numberFormat.setMaximumFractionDigits(1) .


[Page 877]

26.4.2. Currency Format

To format a number as a currency value, use NumberFormat.getCurrencyInstance to get the currency number format for the current locale or NumberFormat.getCurrencyInstance(Locale) to get the currency number for the specified locale.

For example, to display number 5000.555 as currency in the United States, use the following code:

 NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US); System.out.println(currencyFormat.format(   5000.555   )); 

5000.555 is formatted into $5,000,56 . If the locale is set to France, the number would be formatted into 5 000,56 ‚ .

26.4.3. Percent Format

To format a number in a percent, use NumberFormat.getPercentInstance() or NumberFormat.getPercentInstance(Locale) to get the percent number format for the current locale or the specified locale.

For example, to display number 0.555367 as a percent in the United States, use the following code:

 NumberFormat percentFormat = NumberFormat.getPercentInstance(Locale.US); System.out.println(percentFormat.format(   0.555367   )); 

0.555367 is formatted into 56% . By default, the format truncates the fraction part in a percent number. If you want to keep three digits after the decimal point, use percentFormat.setMinimumFractionDigits(3) . So 0.555367 would be displayed as 55.537% .

26.4.4. Parsing Numbers

You can format a number into a string using the format(numericalValue) method. You can also use the parse(String) method to convert a formatted plain number, currency value, or percent number with the conventions of a certain locale into an instance of java.lang.Number . The parse method throws a java.text.ParseException if parsing fails. For example, U.S. $5,000.56 can be parsed into a number using the following statements:

 NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);   try   { Number number = currencyFormat.parse(   "$5,000.56"   ); System.out.println(number.doubleValue()); }   catch   (java.text.ParseException ex) { System.out.println(   "Parse failed"   ); } 

26.4.5. The DecimalFormat Class

If you want even more control over the format or parsing, or want to give your users more control, cast the NumberFormat you get from the factory methods to a java.text.DecimalFormat , which is a subclass of NumberFormat . You can then use the applyPattern(String pattern) method of the DecimalFormat class to specify the patterns for displaying the number.


[Page 878]

A pattern can specify the minimum number of digits before the decimal point and the maximum number of digits after the decimal point. The characters ' ' and ' # ' are used to specify a required digit and an optional digit, respectively. The optional digit is not displayed if it is zero. For example, the pattern " 00.0## " indicates minimum two digits before the decimal point and maximum three digits after the decimal point. If there are more actual digits before the decimal point, all of them are displayed. If there are more than three digits after the decimal point, the number of digits is rounded. Applying the pattern " 00.0## ", number 111.2226 is formatted to 111.223 , number 1111.2226 to 1111.223 , number 1.22 to 01.22 , and number 1 to 01.0 . Here is the code:

 NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); DecimalFormat decimalFormat = (DecimalFormat)numberFormat; decimalFormat.applyPattern(   "00.0##"   ); System.out.println(decimalFormat.format(   111.2226   )); System.out.println(decimalFormat.format(   1111.2226   )); System.out.println(decimalFormat.format(   1.22   )); System.out.println(decimalFormat.format(   1   )); 

The character ' % ' can be put at the end of a pattern to indicate that a number is formatted as a percentage. This causes the number to be multiplied by 100 and appends a percent sign %.

26.4.6. Example: Formatting Numbers

Create a loan calculator similar to the one in Listing 16.1, LoanApplet.java. This new loan calculator allows the user to choose locales, and displays numbers in accordance with locale-sensitive format. As shown in Figure 26.9, the user enters interest rate, number of years, and loan amount, then clicks the Compute button to display the interest rate in percentage format, the number of years in normal number format, and the loan amount, total payment, and monthly payment in currency format. Listing 26.6 gives the solution to the problem.

Figure 26.9. The locale determines the format of the numbers displayed in the loan calculator.

Listing 26.6. NumberFormatDemo.java
(This item is displayed on pages 878 - 881 in the print version)
 1   import   java.awt.*; 2   import   java.awt.event.*; 3   import   javax.swing.*; 4   import   javax.swing.border.*; 5   import   java.util.*; 6   import   java.text.NumberFormat; 7 

[Page 879]
 8   public class   NumberFormatDemo   extends   JApplet { 9  // Combo box for selecting available locales  10   private   JComboBox jcboLocale =   new   JComboBox(); 11 12  // Text fields for interest rate, year, and loan amount  13   private   JTextField jtfInterestRate =   new   JTextField(   "6.75"   ); 14   private   JTextField jtfNumberOfYears =   new   JTextField(   "15"   ); 15   private   JTextField jtfLoanAmount =   new   JTextField(   "107000"   ); 16   private   JTextField jtfFormattedInterestRate =   new   JTextField(   10   ); 17   private   JTextField jtfFormattedNumberOfYears =   new   JTextField(   10   ); 18   private   JTextField jtfFormattedLoanAmount =   new   JTextField(   10   ); 19 20  // Text fields for monthly payment and total payment  21   private   JTextField jtfTotalPayment =   new   JTextField(); 22   private   JTextField jtfMonthlyPayment =   new   JTextField(); 23 24  // Compute button  25   private   JButton jbtCompute =   new   JButton(   "Compute"   ); 26 27  // Current locale  28   private  Locale locale = Locale.getDefault();  29 30  // Declare locales to store available locales  31    private   Locale locales[] = Calendar.getAvailableLocales();  32 33  /** Initialize the combo box */  34   public void   initializeComboBox() { 35  // Add locale names to the combo box  36   for   (   int   i =     ; i < locales.length; i++) 37 jcboLocale.addItem(locales[i].getDisplayName()); 38 } 39 40  /** Initialize the applet */  41   public void   init() { 42  // Panel p1 to hold the combo box for selecting locales  43 JPanel p1 =   new   JPanel(); 44 p1.setLayout (   new   FlowLayout()); 45 p1.add(jcboLocale); 46 initializeComboBox(); 47 p1.setBorder(   new   TitledBorder(   "Choose a Locale"   )); 48 49  // Panel p2 to hold the input  50 JPanel p2 =   new   JPanel(); 51 p2.setLayout(   new   GridLayout(   3   ,   3   )); 52 p2.add(   new   JLabel(   "Interest Rate"   )); 53 p2.add(jtfInterestRate); 54 p2.add(jtfFormattedInterestRate); 55 p2.add(   new   JLabel(   "Number of Years"   )); 56 p2.add(jtfNumberOfYears); 57 p2.add(jtfFormattedNumberOfYears); 58 p2.add(   new   JLabel(   "Loan Amount"   )); 59 p2.add(jtfLoanAmount); 60 p2.add(jtfFormattedLoanAmount); 61 p2.setBorder(   new   TitledBorder(   "Enter Annual Interest Rate, "   + 62   "Number of Years, and Loan Amount"   )); 63 64  // Panel p3 to hold the result  65 JPanel p3 =   new   JPanel(); 66 p3.setLayout(   new   GridLayout(   2   ,   2   )); 67 p3.setBorder(   new   TitledBorder(   "Payment"   )); 

[Page 880]
 68 p3.add(   new   JLabel(   "Monthly Payment"   )); 69 p3.add(jtfMonthlyPayment); 70 p3.add(   new   JLabel(   "Total Payment"   )); 71 p3.add(jtfTotalPayment); 72 73  // Set text field alignment  74 jtfFormattedInterestRate.setHorizontalAlignment(JTextField.RIGHT); 75 jtfFormattedNumberOfYears.setHorizontalAlignment(JTextField.RIGHT); 76 jtfFormattedLoanAmount.setHorizontalAlignment(JTextField.RIGHT); 77 jtfTotalPayment.setHorizontalAlignment(JTextField.RIGHT); 78 jtfMonthlyPayment.setHorizontalAlignment(JTextField.RIGHT); 79 80  // Set editable false  81 jtfFormattedInterestRate.setEditable(   false   ); 82 jtfFormattedNumberOfYears.setEditable(   false   ); 83 jtfFormattedLoanAmount.setEditable(   false   ); 84 jtfTotalPayment.setEditable(   false   ); 85 jtfMonthlyPayment.setEditable(   false   ); 86 87  // Panel p4 to hold result payments and a button  88 JPanel p4 =   new   JPanel(); 89 p4.setLayout(   new   BorderLayout()); 90 p4.add(p3, BorderLayout.CENTER); 91 p4.add(jbtCompute, BorderLayout.SOUTH); 92 93  // Place panels to the applet  94 add(p1, BorderLayout.NORTH); 95 add(p2, BorderLayout.CENTER); 96 add(p4, BorderLayout.SOUTH); 97 98  // Register listeners  99 jcboLocale.addActionListener(   new   ActionListener() { 100   public void   actionPerformed(ActionEvent e) { 101 locale = locales[jcboLocale.getSelectedIndex()]; 102 computeLoan(); 103 } 104 }); 105 106 jbtCompute.addActionListener(   new   ActionListener() { 107   public void   actionPerformed(ActionEvent e) { 108 computeLoan(); 109 } 110 }); 111 } 112 113  /** Compute payments and display results locale-sensitive format */  114   private void   computeLoan() { 115  // Retrieve input from user  116   double   loan =   new   Double(jtfLoanAmount.getText()).doubleValue(); 117   double   interestRate = 118   new   Double(jtfInterestRate.getText()).doubleValue() /   1240   ; 119   int   numberOfYears = 120   new   Integer(jtfNumberOfYears.getText()).intValue(); 121 122  // Calculate payments  123   double   monthlyPayment = loan * interestRate/ 124 (   1   - (Math.pow(   1   / (   1   + interestRate), numberOfYears *   12   ))); 125   double   totalPayment = monthlyPayment * numberOfYears *   12   ; 126 

[Page 881]
 127  // Get formatters  128 NumberFormat percentFormatter = 129  NumberFormat.getPercentInstance(locale);  130 NumberFormat currencyForm = 131  NumberFormat.getCurrencyInstance(locale);  132 NumberFormat numberForm =  NumberFormat.getNumberInstance(locale);  133  percentFormatter.setMinimumFractionDigits(   2   );  134 135  // Display formatted input  136 jtfFormattedInterestRate.setText( 137 percentFormatter.format(interestRate *   12   )); 138 jtfFormattedNumberOfYears.setText 139 (  numberForm.format(numberOfYears)  ); 140 jtfFormattedLoanAmount.setText(  currencyForm.format(loan)  ); 141 142  // Display results in currency format  143 jtfMonthlyPayment.setText(  currencyForm.format(monthlyPayment)  ); 144 jtfTotalPayment.setText(  currencyForm.format(totalPayment)  ); 145 } 146 } 

The computeLoan method (lines 114 “145) gets the input on interest rate, number of years, and loan amount from the user, computes monthly payment and total payment, and displays annual interest rate in percentage format, number of years in normal number format, and loan amount, monthly payment, and total payment in locale-sensitive format.

The statement percentFormatter.setMinimumFractionDigits(2) (line 133) sets the minimum number of fractional parts to 2. Without this statement, 0.075 would be displayed as 7% rather than 7.5%.

 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net