1  import java.util.*;
  2  import java.text.NumberFormat;
  3  import javafx.application.Application;
  4  import javafx.geometry.Pos;
  5  import javafx.scene.Scene;
  6  import javafx.scene.control.Button;
  7  import javafx.scene.control.ComboBox;
  8  import javafx.scene.control.Label;
  9  import javafx.scene.control.TextField;
 10  import javafx.scene.layout.GridPane;
 11  import javafx.scene.layout.HBox;
 12  import javafx.scene.layout.VBox;
 13  import javafx.stage.Stage;
 14  
 15  public class ResourceBundleDemo extends Application {
 16    private ResourceBundle res 
 17      = ResourceBundle.getBundle("MyResource");
 18    
 19    // Create labels
 20    private Label lblInterestRate =
 21      new Label(res.getString("Annual_Interest_Rate"));
 22    private Label lblNumberOfYears =
 23      new Label(res.getString("Number_Of_Years"));
 24    private Label lblLoanAmount = 
 25      new Label(res.getString("Loan_Amount"));
 26    private Label lblMonthlyPayment =
 27      new Label(res.getString("Monthly_Payment"));
 28    private Label lblTotalPayment =
 29      new Label(res.getString("Total_Payment"));
 30    private Label lblPayment =
 31      new Label(res.getString("Payment"));
 32    private Label lblChooseALocale =
 33      new Label(res.getString("Choose_a_Locale"));
 34    private Label lblEnterInterestRate =
 35      new Label(res.getString("Enter_Interest_Rate"));
 36    
 37    // Combo box for selecting available locales
 38    private ComboBox<String> cboLocale = new ComboBox<>();
 39  
 40    // Text fields for interest rate, year, and loan amount
 41    private TextField tfInterestRate = new TextField("6.75");
 42    private TextField tfNumberOfYears = new TextField("15");
 43    private TextField tfLoanAmount = new TextField("107000");
 44    private TextField tfFormattedInterestRate = new TextField();
 45    private TextField tfFormattedNumberOfYears = new TextField();
 46    private TextField tfFormattedLoanAmount = new TextField();
 47  
 48    // Text fields for monthly payment and total payment
 49    private TextField tfTotalPayment = new TextField();
 50    private TextField tfMonthlyPayment = new TextField();
 51  
 52    // Compute button
 53    private Button btCompute = new Button("Compute");
 54  
 55    // Current locale
 56    private Locale locale = Locale.getDefault();
 57  
 58    // Declare locales to store available locales
 59    private Locale locales[] = Calendar.getAvailableLocales();
 60  
 61    /** Initialize the combo box */
 62    public void initializeComboBox() {
 63      // Add locale names to the combo box
 64      for (int i = 0; i < locales.length; i++)
 65        cboLocale.getItems().add(locales[i].getDisplayName());
 66    }
 67  
 68    @Override // Override the start method in the Application class
 69    public void start(Stage primaryStage) {
 70      initializeComboBox();
 71      
 72      // Pane to hold the combo box for selecting locales
 73      HBox hBox = new HBox(5);
 74      hBox.getChildren().addAll(lblChooseALocale, cboLocale);
 75  
 76      // Pane to hold the input
 77      GridPane gridPane = new GridPane();
 78      gridPane.add(lblInterestRate, 0, 0);
 79      gridPane.add(tfInterestRate, 1, 0);
 80      gridPane.add(tfFormattedInterestRate, 2, 0);
 81      gridPane.add(lblNumberOfYears, 0, 1);
 82      gridPane.add(tfNumberOfYears, 1, 1);
 83      gridPane.add(tfFormattedNumberOfYears, 2, 1);
 84      gridPane.add(lblLoanAmount, 0, 2);
 85      gridPane.add(tfLoanAmount, 1, 2);
 86      gridPane.add(tfFormattedLoanAmount, 2, 2);
 87  
 88      // Pane to hold the output
 89      GridPane gridPaneOutput = new GridPane();
 90      gridPaneOutput.add(lblMonthlyPayment, 0, 0);
 91      gridPaneOutput.add(tfMonthlyPayment, 1, 0);
 92      gridPaneOutput.add(lblTotalPayment, 0, 1);
 93      gridPaneOutput.add(tfTotalPayment, 1, 1);
 94  
 95      // Set text field alignment
 96      tfFormattedInterestRate.setAlignment(Pos.BASELINE_RIGHT);
 97      tfFormattedNumberOfYears.setAlignment(Pos.BASELINE_RIGHT);
 98      tfFormattedLoanAmount.setAlignment(Pos.BASELINE_RIGHT);
 99      tfTotalPayment.setAlignment(Pos.BASELINE_RIGHT);
100      tfMonthlyPayment.setAlignment(Pos.BASELINE_RIGHT);
101  
102      // Set editable false
103      tfFormattedInterestRate.setEditable(false);
104      tfFormattedNumberOfYears.setEditable(false);
105      tfFormattedLoanAmount.setEditable(false);
106      tfTotalPayment.setEditable(false);
107      tfMonthlyPayment.setEditable(false);
108  
109      VBox vBox = new VBox(5);
110      vBox.getChildren().addAll(hBox, lblEnterInterestRate, 
111        gridPane, lblPayment, gridPaneOutput, btCompute);
112  
113      // Create a scene and place it in the stage
114      Scene scene = new Scene(vBox, 400, 300);
115      primaryStage.setTitle("ResourceBundleDemo"); // Set the stage title
116      primaryStage.setScene(scene); // Place the scene in the stage
117      primaryStage.show(); // Display the stage
118  
119      // Register listeners
120      cboLocale.setOnAction(e -> {
121        locale = locales[cboLocale
122          .getSelectionModel().getSelectedIndex()];
123        updateStrings();
124        computeLoan();
125      });
126  
127      btCompute.setOnAction(e -> computeLoan());
128    }
129  
130    /** Compute payments and display results locale-sensitive format */
131    private void computeLoan() {
132      // Retrieve input from user
133      double loan = new Double(tfLoanAmount.getText()).doubleValue();
134      double interestRate =
135        new Double(tfInterestRate.getText()).doubleValue() / 1240;
136      int numberOfYears =
137        new Integer(tfNumberOfYears.getText()).intValue();
138  
139      // Calculate payments
140      double monthlyPayment = loan * interestRate/
141       (1 - (Math.pow(1 / (1 + interestRate), numberOfYears * 12)));
142      double totalPayment = monthlyPayment * numberOfYears * 12;
143  
144      // Get formatters
145      NumberFormat percentFormatter =
146        NumberFormat.getPercentInstance(locale);
147      NumberFormat currencyForm =
148        NumberFormat.getCurrencyInstance(locale);
149      NumberFormat numberForm = NumberFormat.getNumberInstance(locale);
150      percentFormatter.setMinimumFractionDigits(2);
151  
152      // Display formatted input
153      tfFormattedInterestRate.setText(
154        percentFormatter.format(interestRate * 12));
155      tfFormattedNumberOfYears.setText
156        (numberForm.format(numberOfYears));
157      tfFormattedLoanAmount.setText(currencyForm.format(loan));
158  
159      // Display results in currency format
160      tfMonthlyPayment.setText(currencyForm.format(monthlyPayment));
161      tfTotalPayment.setText(currencyForm.format(totalPayment));
162    }
163  
164    /** Update resource strings */
165    private void updateStrings() {
166      res = ResourceBundle.getBundle("MyResource", locale);
167      lblInterestRate.setText(res.getString("Annual_Interest_Rate"));
168      lblNumberOfYears.setText(res.getString("Number_Of_Years"));
169      lblLoanAmount.setText(res.getString("Loan_Amount"));
170      lblTotalPayment.setText(res.getString("Total_Payment"));
171      lblMonthlyPayment.setText(res.getString("Monthly_Payment"));
172      btCompute.setText(res.getString("Compute"));
173      lblChooseALocale.setText(res.getString("Choose_a_Locale"));
174      lblEnterInterestRate.setText(
175        res.getString("Enter_Interest_Rate"));
176      lblPayment.setText(res.getString("Payment"));
177    }
178    
179    /**
180     * The main method is only needed for the IDE with limited
181     * JavaFX support. Not needed for running from the command line.
182     */
183    public static void main(String[] args) {
184      launch(args);
185    }
186  }