gvsu/cs623/proj1/RetirementCalculator.java
2009-10-06 16:18:20 +00:00

417 lines
13 KiB
Java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
/*
* The main work of the application is done in this JPanel-extending class.
* This allows the java class to be run as a stand-alone application or
* as an applet within a web browser.
*/
class RetirementCalculatorPanel
extends JPanel
implements ActionListener, FocusListener
{
private RetirementCalculatorModel myModel;
private JComponent makeDivider() { return new JLabel(" "); }
private HashMap<String, JComponent> myFields;
private JButton myCalculateButton;
private JButton myPrintButton;
private JButton myResetButton;
private JLabel myResultBox;
private JTextField myNameField;
class ComboChoice
{
private String myDesc;
private int myVal;
ComboChoice(int val, String desc)
{
myDesc = desc;
myVal = val;
}
public String toString() { return myDesc; }
public int getVal() { return myVal; }
}
private final ComboChoice[] retirement_age_choices = {
new ComboChoice(55, "55"),
new ComboChoice(60, "60"),
new ComboChoice(65, "65"),
new ComboChoice(70, "70")
};
private final ComboChoice[] life_expectancy_choices = {
new ComboChoice(82, "82 (Male; 50th percentile)"),
new ComboChoice(86, "86 (Female; 50th percentile)"),
new ComboChoice(89, "89 (Male; 75th percentile)"),
new ComboChoice(92, "92 (Female; 75th percentile)"),
new ComboChoice(94, "94 (Male; 90th percentile)"),
new ComboChoice(97, "97 (Female; 90th percentile)")
};
public RetirementCalculatorPanel()
{
super(new BorderLayout());
myModel = new RetirementCalculatorModel();
myFields = new HashMap<String, JComponent>();
JPanel inner = new JPanel(new GridBagLayout());
JComponent field;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.ipadx = 2;
c.gridwidth = 1;
c.gridheight = 1;
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.0;
inner.add(new JLabel("What is your name?", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
myNameField = new JTextField();
myNameField.addFocusListener(this);
inner.add(myNameField, c);
c.gridx--;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel("What is your age?", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("age", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.gridwidth = 2;
inner.add(makeDivider(), c);
c.gridwidth = 1;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel("How much annual income will you want in retirement?", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("income wanted", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel("What is your current annual income?",
SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("current income", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.gridwidth = 2;
inner.add(makeDivider(), c);
c.gridy++;
inner.add(new JLabel("What is your expected annual income after retirement -"), c);
c.gridwidth = 1;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel(" - from an employer pension plan?",
SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("employer pension", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel(" - from a part-time job?",
SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("part time income", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel(" - other?", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("other income", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.gridwidth = 2;
inner.add(makeDivider(), c);
c.gridwidth = 1;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel("How much savings do you have to date?",
SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JTextField();
field.addFocusListener(this);
myFields.put("savings", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
c.weightx = 0.0;
inner.add(new JLabel("At what age do you expect to retire?",
SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1.0;
field = new JComboBox(retirement_age_choices);
myFields.put("retirement age", field);
inner.add(field, c);
c.gridx--;
c.gridy++;
JPanel p = new JPanel(new BorderLayout());
p.setAlignmentX(Component.RIGHT_ALIGNMENT);
p.add(new JLabel("What is your life expectancy?",
SwingConstants.RIGHT), BorderLayout.CENTER);
field = new JComboBox(life_expectancy_choices);
myFields.put("life expectancy", field);
p.add(field, BorderLayout.EAST);
c.gridwidth = 2;
inner.add(p, c);
c.gridwidth = 1;
c.gridy++;
c.gridwidth = 2;
inner.add(makeDivider(), c);
c.gridwidth = 1;
c.gridy++;
JPanel buttons = new JPanel();
buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
buttons.add(Box.createHorizontalGlue());
myCalculateButton = new JButton("Calculate");
myCalculateButton.addActionListener(this);
buttons.add(myCalculateButton);
buttons.add(Box.createRigidArea(new Dimension(10, 0)));
myPrintButton = new JButton("Print");
myPrintButton.addActionListener(this);
buttons.add(myPrintButton);
buttons.add(Box.createRigidArea(new Dimension(10, 0)));
myResetButton = new JButton("Reset");
myResetButton.addActionListener(this);
buttons.add(myResetButton);
buttons.add(Box.createHorizontalGlue());
c.gridwidth = 2;
inner.add(buttons, c);
c.gridwidth = 1;
c.gridy++;
c.gridwidth = 2;
inner.add(makeDivider(), c);
c.gridwidth = 1;
c.gridy++;
c.gridwidth = 2;
myResultBox = new JLabel(" ", SwingConstants.CENTER);
inner.add(myResultBox, c);
c.gridwidth = 1;
c.gridy++;
JScrollPane scrollpane = new JScrollPane(inner,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
add(scrollpane);
reset();
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == myCalculateButton)
calculate();
else if (e.getSource() == myResetButton)
reset();
else if (e.getSource() == myPrintButton)
print();
}
public void focusGained(FocusEvent e)
{
if (e.getComponent().getClass() == JTextField.class)
{
((JTextField) e.getComponent()).selectAll();
}
}
public void focusLost(FocusEvent e)
{
}
private void calculate()
{
Iterator it = myFields.keySet().iterator();
while (it.hasNext())
{
String key = (String) it.next();
JComponent comp = myFields.get(key);
if (comp.getClass() == JTextField.class)
{
JTextField tf = (JTextField) comp;
myModel.setField(key, Double.parseDouble(tf.getText()));
}
else if (comp.getClass() == JComboBox.class)
{
JComboBox cb = (JComboBox) comp;
myModel.setField(key,
((ComboChoice) cb.getSelectedItem()).getVal());
}
}
myModel.calculate();
myResultBox.setText("<html>The total amount of savings needed at retirement is $" +
String.format("%,.02f", myModel.getField("total additional savings needed")) +
".<br/> The annual amount of savings needed is $" +
String.format("%,.02f", myModel.getField("annual savings needed")) + "</html>");
}
private void reset()
{
myModel.reset();
Iterator it = myFields.keySet().iterator();
while (it.hasNext())
{
String key = (String) it.next();
JComponent comp = myFields.get(key);
if (comp.getClass() == JTextField.class)
{
JTextField tf = (JTextField) comp;
double val = myModel.getField(key);
tf.setText(String.format(
key.equals("age") ? "%.0f" : "%.2f", val));
}
else if (comp.getClass() == JComboBox.class)
{
JComboBox cb = (JComboBox) comp;
int val = (int) myModel.getField(key);
ComboChoice[] ccp = null;
if (key.equals("retirement age"))
ccp = retirement_age_choices;
else if (key.equals("life expectancy"))
ccp = life_expectancy_choices;
if (ccp != null)
{
for (ComboChoice cc : ccp)
{
if (cc.getVal() == val)
{
cb.setSelectedItem(cc);
break;
}
}
}
}
}
myNameField.setText("");
myResultBox.setText(" ");
}
private String fmt(String fmt, String field)
{
return String.format(fmt, myModel.getField(field));
}
private void print()
{
calculate();
String endl = "<br/>";
String msg = "<html>";
msg += "Name: " + myNameField.getText() + endl;
msg += "Age: " + fmt("%.0f", "age") + endl;
msg += "Retirement age: " + fmt("%.0f", "retirement age") + endl;
msg += "Current income: $" + fmt("%,.02f", "current income") + endl;
msg += "Desired annual income: $" +
fmt("%,.02f", "income wanted") + endl;
msg += endl;
msg += "Social Security benefit: $" +
fmt("%,.02f", "social security") + endl;
msg += "Traditional Employer Pension: $" +
fmt("%,.02f", "employer pension") + endl;
msg += "Part-time income: $" + fmt("%,.02f", "part time income") + endl;
msg += "Other income: $" + fmt("%,.02f", "other income") + endl;
msg += "Amount to make up each retirement year: $" +
fmt("%,.02f", "amount to make up") + endl;
msg += endl;
msg += "Total amount to save: $" +
fmt("%,.02f", "amount to save") + endl;
msg += "Early retirement addition: $" +
fmt("%,.02f", "early retirement penalty") + endl;
msg += "Estimated savings at retirement: $" +
fmt("%,.02f", "estimated savings") + endl;
msg += endl;
msg += "Total additional savings needed at retirement: $" +
fmt("%,.02f", "total additional savings needed") + endl;
msg += "Required annual savings: $" +
fmt("%,.02f", "annual savings needed") + endl;
msg += "</html>";
JOptionPane.showMessageDialog(null, msg,
"Basic Retirement Calculator", JOptionPane.PLAIN_MESSAGE);
}
}
/*
* The "main" class of this file allows the app to be run as an applet
* but also provides a "main" method to run as an application.
*/
public class RetirementCalculator extends JApplet
{
final static private String PROG_NAME = "Josh's Retirement Calculator";
RetirementCalculatorPanel panel;
public void init()
{
setLayout(new BorderLayout());
panel = new RetirementCalculatorPanel();
add(panel, BorderLayout.CENTER);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run()
{
JFrame frame = new JFrame(PROG_NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RetirementCalculatorPanel panel =
new RetirementCalculatorPanel();
frame.getContentPane().add(panel);
frame.setPreferredSize(new Dimension(600, 450));
frame.pack();
frame.setVisible(true);
}
});
}
}