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 myFields; private HashMap myToolTips; private JButton myCalculateButton; private JButton myPrintButton; private JButton myResetButton; private JLabel myResultBox; private JLabel myToolTipBox; 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)") }; private static int row = 0; private void addRow(JPanel panel, JComponent c1, JComponent c2) { GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 4, 0, 4); c.ipadx = 2; c.gridwidth = 1; c.gridheight = 1; c.gridx = 0; c.weightx = 0.0; c.gridy = row; panel.add(c1, c); c.gridx++; c.weightx = 1.0; panel.add(c2, c); row++; } private void addDollarRow(JPanel panel, JComponent c1, JComponent c2) { JPanel dollar_panel = new JPanel(); dollar_panel.setLayout(new BoxLayout(dollar_panel, BoxLayout.X_AXIS)); dollar_panel.add(new JLabel("$")); dollar_panel.add(c2); addRow(panel, c1, dollar_panel); } private void addRow(JPanel panel, JComponent c1) { GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 4, 0, 4); c.ipadx = 2; c.gridwidth = 2; c.gridheight = 1; c.gridx = 0; c.weightx = 0.0; c.gridy = row; panel.add(c1, c); row++; } public RetirementCalculatorPanel() { super(new BorderLayout()); myModel = new RetirementCalculatorModel(); myFields = new HashMap(); myToolTips = new HashMap(); JPanel inner = new JPanel(new GridBagLayout()); myToolTipBox = new JLabel(" ", SwingConstants.CENTER); JComponent field; myNameField = new JTextField(); myNameField.addFocusListener(this); myToolTips.put(myNameField, "Enter your name."); myToolTipBox.setText("Enter your name."); addRow(inner, new JLabel("What is your name?", SwingConstants.RIGHT), myNameField); field = new JTextField(); field.addFocusListener(this); myFields.put("age", field); myToolTips.put(field, "Enter your current age."); addRow(inner, new JLabel("What is your age?", SwingConstants.RIGHT), field); addRow(inner, makeDivider()); field = new JTextField(); field.addFocusListener(this); myFields.put("income wanted", field); myToolTips.put(field, "Enter the amount of income that you would like to receive in a year while you are retired."); addDollarRow(inner, new JLabel("How much annual income will you want in retirement?", SwingConstants.RIGHT), field); field = new JTextField(); field.addFocusListener(this); myFields.put("current income", field); myToolTips.put(field, "Enter the amount of income that you currently receive in a year."); addDollarRow(inner, new JLabel("What is your current annual income?", SwingConstants.RIGHT), field); addRow(inner, makeDivider()); addRow(inner, new JLabel("What is your expected annual income after retirement...")); field = new JTextField(); field.addFocusListener(this); myFields.put("employer pension", field); myToolTips.put(field, "If your employer has a pension plan that will pay you a certain amount
after you retire from them, then enter that amount here."); addDollarRow(inner, new JLabel("... from an employer pension plan?", SwingConstants.RIGHT), field); field = new JTextField(); field.addFocusListener(this); myFields.put("part time income", field); myToolTips.put(field, "Enter how much income you expect to make working at a part-time job after retirement."); addDollarRow(inner, new JLabel("... from a part-time job?", SwingConstants.RIGHT), field); field = new JTextField(); field.addFocusListener(this); myFields.put("other income", field); myToolTips.put(field, "If there is any other annual income you expect to receive after retirement
not already accounted for, enter the amount here."); addDollarRow(inner, new JLabel("... other?", SwingConstants.RIGHT), field); addRow(inner, makeDivider()); field = new JTextField(); field.addFocusListener(this); myFields.put("savings", field); myToolTips.put(field, "Enter the amount of money that you have saved right now."); addDollarRow(inner, new JLabel("How much savings do you have to date?", SwingConstants.RIGHT), field); field = new JComboBox(retirement_age_choices); field.addFocusListener(this); myFields.put("retirement age", field); myToolTips.put(field, "Select the age at which you are planning to reture."); addRow(inner, new JLabel("At what age do you expect to retire?", SwingConstants.RIGHT), field); field = new JComboBox(life_expectancy_choices); field.addFocusListener(this); myFields.put("life expectancy", field); myToolTips.put(field, "Select what you think your life expectancy is."); addRow(inner, new JLabel("What is your life expectancy?", SwingConstants.RIGHT), field); addRow(inner, makeDivider()); 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()); addRow(inner, myToolTipBox); // addRow(inner, makeDivider()); addRow(inner, buttons); // addRow(inner, makeDivider()); JScrollPane scrollpane = new JScrollPane(inner, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); add(scrollpane); myResultBox = new JLabel("", SwingConstants.CENTER); myResultBox.setForeground(new Color(0, 0, 200)); add(myResultBox, BorderLayout.SOUTH); 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(); } String tooltip = myToolTips.get(e.getComponent()); if (tooltip != null) { if (tooltip.indexOf("   "; } myToolTipBox.setText("" + tooltip + ""); } } 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("The total amount of savings needed at retirement is $" + String.format("%,.02f", myModel.getField("total additional savings needed")) + ".
The annual amount of savings needed is $" + String.format("%,.02f", myModel.getField("annual savings needed")) + ""); } 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 = "
"; String msg = ""; 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 += ""; 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); } }); } }