Reputation: 37
I'm a java novice, and by far my weakest point in java is using graphics. I'm trying to make a retirement calculator that allows a user to input several pieces of data into an application through JTextFields and then press a button to calculate an account balance at each year (i.e. create an array of the balances at the end of each year). However, I want to display this information using a bar graph representing these balances, so the bar graph must draw its rectangles using the numbers in the array. However, since paintComponent is called at the beginning of the program and the values of the array aren't initialized until the press of the JButton, I can't have the paintComponent method refer to those values, otherwise I get a nullPointerException upon running and things don't render properly. Here's my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JPanel
{
static double start;
static double age;
static double retirement;
static double apr;
static double inflation;
static double daily;
static double life;
static double income;
static int yearsToRetirement = (int)(retirement - age);
static int yearsPostRetirement = (int)(life - retirement);
static double real = (1.0 + (apr / 100.0))/(1.0 + (inflation/100.0)) - 1.0;
static double[] balance;
static double[] yearEndBalance;
static double[] balance2;
public Calculator()
{
setLayout(new BorderLayout());
JPanel subpanel = new JPanel();
add(subpanel, BorderLayout.LINE_END);
subpanel.setBackground(Color.GRAY);
subpanel.setLayout(new GridLayout(9, 1));
// Daily savings
JPanel pnlDailySavings = new JPanel();
JLabel lblDailySavings = new JLabel("Daily savings amount:");
final JTextField txtDailySavings = new JTextField(10);
pnlDailySavings.add(lblDailySavings);
pnlDailySavings.add(txtDailySavings);
subpanel.add(pnlDailySavings);
// Age
JPanel pnlAge = new JPanel();
JLabel lblAge = new JLabel(" Current age:");
final JTextField txtAge = new JTextField(10);
pnlAge.add(lblAge);
pnlAge.add(txtAge);
subpanel.add(pnlAge);
// Starting amount of savings
JPanel pnlStart = new JPanel();
JLabel lblStart = new JLabel("Starting amount of savings:");
final JTextField txtStart = new JTextField(10);
pnlStart.add(lblStart);
pnlStart.add(txtStart);
subpanel.add(pnlStart);
// Age of retirement
JPanel pnlRetirement = new JPanel();
JLabel lblRetirement = new JLabel("Expected age of retirement:");
final JTextField txtRetirement = new JTextField(10);
pnlRetirement.add(lblRetirement);
pnlRetirement.add(txtRetirement);
subpanel.add(pnlRetirement);
// Annual retirement income
JPanel pnlIncome = new JPanel();
JLabel lblIncome = new JLabel("Annual retirement income:");
final JTextField txtIncome = new JTextField(10);
pnlIncome.add(lblIncome);
pnlIncome.add(txtIncome);
subpanel.add(pnlIncome);
// Life expectancy
JPanel pnlLife = new JPanel();
JLabel lblLife = new JLabel("Life expectancy:");
final JTextField txtLife = new JTextField(10);
pnlLife.add(lblLife);
pnlLife.add(txtLife);
subpanel.add(pnlLife);
// Estimated rate of return on savings
JPanel pnlReturn = new JPanel();
JLabel lblReturn = new JLabel("Estimated rate of return on savings:");
final JTextField txtReturn = new JTextField(10);
pnlReturn.add(lblReturn);
pnlReturn.add(txtReturn);
subpanel.add(pnlReturn);
// Estimated rate of inflation
JPanel pnlInflation = new JPanel();
JLabel lblInflation = new JLabel("Estimated rate of inflation:");
final JTextField txtInflation = new JTextField(10);
pnlInflation.add(lblInflation);
pnlInflation.add(txtInflation);
subpanel.add(pnlInflation);
JButton btnCalculate = new JButton("Calculate your retirement savings");
btnCalculate.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
daily = Double.parseDouble(txtDailySavings.getText());
age = Double.parseDouble(txtAge.getText());
start = Double.parseDouble(txtStart.getText());
retirement = Double.parseDouble(txtRetirement.getText());
income = Double.parseDouble(txtIncome.getText());
life = Double.parseDouble(txtLife.getText());
apr = Double.parseDouble(txtReturn.getText());
inflation = Double.parseDouble(txtInflation.getText());
System.out.printf("%f%n%f%n%f%n%f%n%f%n%f%n%f%n%f%n", daily, age, start, retirement, income, life, apr, inflation);
balance = new double[365 * yearsToRetirement];
yearEndBalance = new double[yearsToRetirement];
balance2 = new double[yearsPostRetirement];
double total = start;
for (int i = 0; i < balance.length; i++)
{
total = total * (1 + real/365.0) + daily;
balance[i] = total;
}
for (int i = 0; i < balance2.length; i++)
{
total = total * Math.pow((1 + real/365.0), 365) - income;
balance2[i] = total;
}
for (int i = 0; i < yearEndBalance.length; i++)
{
yearEndBalance[i] = balance[365 * i];
}
printArray(yearEndBalance);
printArray(balance2);
printArray(balance);
repaint();
}
});
subpanel.add(btnCalculate);
}
public static void printArray(double[] array)
{
for (int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
}
public void paintComponent(Graphics g)
{
int width = this.getWidth();
int height = this.getHeight();
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}
This code is obviously a work in progress, but right now my biggest hurdle is facilitating the communication between the arrays created upon JButton and creation of a bar graph. Can anyone help?
Upvotes: 0
Views: 57
Reputation: 347184
Five things...
balance2
is not null
and is not empty (length
> 0
)paintComponent
over paint
, see Performing Custom Painting for more details.super.paint
(or super.paintComponent
if you've overridden paintComponent
) to preserve the paint chain. See Painting in AWT and Swing for more details (nb: You are calling super.paintComponent
from within paint
, this is bad idea and could affect updates to the GUI)repaint
on the bar component when you want to repaint it's contentFor example..
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
if (balance2 != null && balance2.length > 0) {
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}
Upvotes: 2