In the following article, I outline the process of making a simple interest calculator in Java and leveraging Swing GUI widget toolkit for Java.
Method: calculateInterest (float, float, short)
Prerequisites
- JDK Version: Downloaded and installed Java SE Development Kit 8 for Windows
- IDE: IntelliJ IDEA for Windows Integrated Development Environment (IDE)
Application Goal
To write a Java program that calculates interest of the given amount using following formulas:
A = P(1 + rt)
R = r * 100
Where
A = total accrued amount (principal + interest)
P = principal amount
r = rate of interest per year in decimal; r = R/100
**t **= period of years
Example
If P = 10,000, R = 3.875% per year and t = 5 years. Then A = 10,000(1 + (0.03875 × 5)) = 11,937.50
**Class InterestCalculator **
I created an empty project in my IDE. I have named my public class: InterestCalculator. In the class itself and before I call the main method (and any other methods), I define three private static text boxes and submit buttons, all of which become available to other methods that leverage their functionality (Figure 1).
Figure 1 – InterestCalculator Class (Jarosciak, 2018)
Methods
I have included 4 methods in my code.
- ‘main’ method - Used to call the form creation process and also includes a calculate button action listener.
- ‘createForm’ method – I use it to design and present the input form to the user.
- ‘isNumeric’ method - Used for form input validation.
- ‘calculateInterest’ method - Used for calculation of the interest
Let’s cover each of the methods.
Method: main
This is the main method I created, where I do the following:
** Create Form**
- First, I call the ‘createForm’ method that generates the form with input fields and submit button. The input fields of the form are collected upon a button click on JButton ‘calculateButton’.
- I added a listener for the JButton ‘calculateButton’ to get a text from the three JTextField input fields:
textPrincipalAmount
- textInterestRate
- textTimePeriod
Error Handling
Before I call the ‘calculateInterest’ method that calculates the interest, I decided to add the two error checking if statements.
-
Check if all input fields are entered. If not, I present the user with "Please fill the form input fields!" message by leveraging JOptionPane dialog box and showMessageDialog method.
- Once I know that all fields are entered, the next error checking I have implemented is to check if the content submitted is in the numeric form. For this, I use ‘isNumeric’ method (described below).
Call calculate interest method
- Once all the fields passed through error checking, I call the ‘calculateInterest’ method, that takes three input text fields as parameters.
Figure 2 shows the entire code of the main method.
Figure 2 – main Method (Jarosciak, 2018)
Method: createForm
The first thing the main method runs is a call to ‘createForm’ method. I had a specific look in mind for the input form, as shown in Figure 3, so instead of using JOptionPane’s dialog box for individual input queries, I decided to use Swing GUI.
Figure 3 – Basic Interest Calculator Form (Jarosciak, 2018)
“Swing is a GUI toolkit for Java, a part of the Java Foundation Class (JFC).” (Jayaswal, 2007).
Swing as a graphical user interface for Java programs is a very lightweight set of components that, “to the maximum degree possible, work the same on all platforms.” Docs.oracle.com. (2018).
To do so, I first needed to import java Swing using: import java.swing.*;
The code for ‘createForm’ method is thoroughly commented out, so it is easily visible directly from the code itself as to what was accomplished using this method, but primarily I am building the form by using Swing components.
- Added JFrame for my form and into it I added a JPanel.
- Defined labels and text fields
- Configured form attributes. Note, I used GridBagLayout, because it allowed me to put labels and text fields next to each other on the grid, as well as use the north property to place the calculateInterest button underneath.
- Added defined labels, text fields and calculate button to JPanel panel.
- Then rendered the form visible.
Figure 4 shows the entire code of the createForm method.
Figure 4 – createForm Method (Jarosciak, 2018)
Method: isNumeric
This method was already described above; it is designed to give ‘true’ Boolean return if the string passed to it is numeric or ‘false’ when it is not. I am using this method for error handling in the main method upon button click.
Figure 5 – isNumeric Method (Jarosciak, 2018)
Method: calculateInterest (float, float, short)
This method is a heart of the application.
Figure 6 shows the code of calculateInterest() method that takes three parameters, namely:
- P = principal amount as **float**
Float takes 4 bytes of storage and takes 6-7 significant decimal digits, and that is long enough for the principal value. I could have gone with the integer here, but we may expect decimals in principal amount. Double with 8 bytes of storage, on the other hand, would be unnecessarily too big for the calculation.
- r = rate of interest per year as a **float**
This is another float to accommodate decimals in the interest rate.
- t = period involved in years as **short**
This is a number of years, so I went with the short data type. Of course, byte data type would likely do as well, as it takes values up to 127, but just to be sure I went with a short data type that allows users to go above 127 years and up to 32,767.
Figure 6 – calculateInterest Method (Jarosciak, 2018)
The next step was to calculate total accrued amount principal + interest: A = P(1 + rt), assigning it to a new float value A:
float A = P * (1 + ((r / 100) * t));
Please note, I have decided to format my result before I display it using DecimalFormat class, which allows me to put commas after thousands and cap my result at two decimal places:
DecimalFormat decimalFormatter = new DecimalFormat("#,##0.00");
As the last call, I display results using showMessageBox from JPlease note, I have decided to format my result before I display it using DecimalFormat class, which allows me put thousands separator as well as cap the results at two decimal places.
Demo
Here is a demo of the application: Basic Interest Calculator.
Figure 7 shows the input dialog:
Figure 7 – Input Dialog (Jarosciak, 2018)
Figure 8 illustrates the result calculation based on values entered in Figure 7.
Figure 8 – Result (Jarosciak, 2018)
As we can see the results were successfully and accurately provided back to the user of the application.
Complete Code in Plain Text
package com.jarosciak.interestcalculator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import static javax.swing.JOptionPane.*;
public class InterestCalculator {
// Define static fields shared by methods
private static JTextField textPrincipalAmount = new JTextField();
private static JTextField textInterestRate = new JTextField();
private static JTextField textTimePeriod = new JTextField();
private static JButton calculateButton = new JButton();
public static void main(String[] args) {
// Create form
createForm();
// Add listener for button click
calculateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// If all input fields entered
if (!textPrincipalAmount.getText().isEmpty()
&& !textInterestRate.getText().isEmpty()
&& !textTimePeriod.getText().isEmpty()) {
// And all input fields are numeric
if ((isNumeric(textPrincipalAmount.getText()))
&& (isNumeric(textInterestRate.getText()))
&& (isNumeric(textTimePeriod.getText()))) {
// Calculate Interest
calculateInterest(
Float.parseFloat(textPrincipalAmount.getText()),
Float.parseFloat(textInterestRate.getText()),
Short.parseShort(textTimePeriod.getText())
);
} else {
showMessageDialog(null, "Values must be in numeric form!", "Warning", WARNING_MESSAGE);
}
} else {
// If any of the input fields is not entered, show warning
showMessageDialog(null, "Please fill the form input fields!", "Warning", WARNING_MESSAGE);
}
}
});
}
public static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
private static void calculateInterest(float P, float r, short t) {
/*
calculateInterest() method takes parameters in following order:
P = principal amount
r = rate of interest per year (or month) in decimal; r = R/100
t = time period involved in years (or months)
*/
// Calculate total accrued amount principal + interest: A = P(1 + rt)
float A = P * (1 + ((r / 100) * t));
// Format
DecimalFormat decimalFormatter = new DecimalFormat("#,##0.00");
// Display Result
showMessageDialog(null,
"Principal Amount: " + decimalFormatter.format(P) + "\n"
+ "Interest: " + decimalFormatter.format(A - P) + "\n"
+ "Total with Interest: " + decimalFormatter.format(A), "Result", PLAIN_MESSAGE);
}
private static void createForm() {
// Create Form
JFrame frame = new JFrame("Basic Interest Calculator"); // title of the form
JPanel panel = new JPanel();
// Define Labels and Text Fields
JLabel labelPrincipalAmount = new JLabel("Enter Principal Amount ");
JLabel labelInterestRate = new JLabel("Enter Yearly Interest Rate (%) ");
JLabel labelTimePeriod = new JLabel("Enter Time Period (years) ");
calculateButton.setText("Calculate Interest");
// Input Form Attributes
panel.setLayout(new GridBagLayout());
panel.setBackground(Color.lightGray);
frame.getContentPane().add(panel);
GridBagConstraints left = new GridBagConstraints();
left.anchor = GridBagConstraints.EAST;
GridBagConstraints right = new GridBagConstraints();
right.weightx = 2.0;
right.fill = GridBagConstraints.HORIZONTAL;
right.gridwidth = GridBagConstraints.REMAINDER;
// Add labels and textboxes to panel
panel.add(labelPrincipalAmount, left);
panel.add(textPrincipalAmount, right);
panel.add(labelInterestRate, left);
panel.add(textInterestRate, right);
panel.add(labelTimePeriod, left);
panel.add(textTimePeriod, right);
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//Add button to the bottom of the form
frame.getContentPane().add(BorderLayout.SOUTH, calculateButton);
// Set form attributes, make it visible and show
frame.pack();
frame.setSize(400, 180); // form size
frame.setLocationRelativeTo(null); // Center form
frame.setVisible(true);
}
}
References
Docs.oracle.com. (2018). javax.swing (Java Platform SE 8 ). [online] Available at: https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html [Accessed 20 Jan. 2018].
Jayaswal, C. P. (2007). Automated Software Testing Using Covering Arrays.