// Make it easy to access packaged code. import java.awt.*; import java.awt.event.*; import java.applet.*; /** * This class subclasses Applet to define an applet for calculating and * displaying the result of compounding an investment. It implements the * ActionListener and ItemListener interfaces to respond to events. * * Written by: Jon Huhtala */ public class App extends Applet implements ActionListener, ItemListener { // Instance variables for the amount to be invested, the interest rate, and // the term in years. private double amount; private double rate; private int term; // Instance variables for referencing the amount heading and its text field. private Label amountHdg; private TextField amountField; // Instance variables for referencing the rate heading and its choices. private Label rateHdg; private Choice rateChoice; // Instance variables for referencing the term heading and its choices. private Label termHdg; private Choice termChoice; // Instance variable for referencing the graph to be displayed. private Graph graph; // This method defines initial (one-time) applet processing. public void init() { // Set the background color and size for the applet window. setSize(250, 350); setBackground(Color.lightGray); // Declare a label and a text field in which the user may enter the amount // to be invested. Add the components to the applet window and register a // listener to be notified whenever the user presses the "ENTER" key within // the text field. amountHdg = new Label("Amount invested"); add(amountHdg); amountField = new TextField(5); add(amountField); amountField.addActionListener(this); // Declare a label and a menu of choices by which the user may select the // annual interest rate of the investment. Add the components to the applet // window and register a listener to be notified whenever the user makes a // selection. The default selection is 8 percent. rateHdg = new Label("Annual percentage rate"); add(rateHdg); rateChoice = new Choice(); rateChoice.addItem("2"); rateChoice.addItem("3"); rateChoice.addItem("4"); rateChoice.addItem("5"); rateChoice.addItem("6"); rateChoice.addItem("7"); rateChoice.addItem("8"); rateChoice.addItem("9"); rateChoice.addItem("10"); rateChoice.addItem("11"); rateChoice.addItem("12"); add(rateChoice); rateChoice.addItemListener(this); rateChoice.select("8"); rate = .08; // Declare a label and a menu of choices by which the user may select the // term of the investment. Add the components to the applet window and // register a listener to be notified whenever the user makes a selection. // The default selection is 10 years. termHdg = new Label("Term in years"); add(termHdg); termChoice = new Choice(); termChoice.addItem("1"); termChoice.addItem("2"); termChoice.addItem("3"); termChoice.addItem("4"); termChoice.addItem("5"); termChoice.addItem("6"); termChoice.addItem("7"); termChoice.addItem("8"); termChoice.addItem("9"); termChoice.addItem("10"); termChoice.addItem("15"); termChoice.addItem("20"); termChoice.addItem("25"); termChoice.addItem("30"); termChoice.addItem("35"); termChoice.addItem("40"); termChoice.addItem("45"); termChoice.addItem("50"); add(termChoice); termChoice.addItemListener(this); termChoice.select("10"); term = 10; // Instantiate a graph object for displaying the result of compounding and // add it to the applet window. graph = new Graph(); add(graph); } // This method implements the abstract event handler method of the // ActionListener interface to handle ActionEvents. public void actionPerformed(ActionEvent e) { // If the user pressed the "ENTER" key in the amount text field and the // field isn't empty, get the String from the field, strip leading and // trailing spaces, convert it to a primitive value, and store it. // Otherwise, set the amount to zero. if (e.getSource().equals(amountField)) { if (amountField.getText().trim().length() > 0) { amount = Double.parseDouble(amountField.getText().trim()); } else { amount = 0; } } // Draw the graph. drawGraph(); } // This method implements the abstract event handler method of the // ItemListener interface to handle ItemEvents (selections from a Choice). public void itemStateChanged(ItemEvent e) { // If the amount text field isn't empty, get the String from the amount // text field, strip leading and trailing spaces, convert it to a primitive // value, and store it. Otherwise, set the amount to zero. if (amountField.getText().trim().length() > 0) { amount = Double.parseDouble(amountField.getText().trim()); } else { amount = 0; } // If the user selected an item from the rate menu choices, get the object, // convert it to a String with no leading or trailing spaces, convert it to // its primitive value, divide by 100 to convert to a percentage, and store // it. if (e.getSource().equals(rateChoice)) { rate = Double.parseDouble(rateChoice.getSelectedItem())/100; } // If the user selected an item from the term menu choices, get the object, // convert it to a String with no leading or trailing spaces, convert it to // its primitive value, and store it. if (e.getSource().equals(termChoice)) { term = Integer.parseInt(termChoice.getSelectedItem()); } // Draw the graph. drawGraph(); } // Draw a graph that shows the result of compounding the investment. private void drawGraph() { // Pass the original amount and the compounded amount to the graph object. // It will use the values to draw a stacked bar graph. graph.setValues(amount, amount * Math.pow(1+rate,term)); // Force the graph to be re-painted. graph.repaint(); } } // This class subclasses Canvas to draw a stacked bar graph. class Graph extends Canvas { // Instance variables for holding the height and value of the lower (first) // portion of the stacked bar. private int bar1Height; private double bar1Value; // Instance variable for holding the height of the upper (second) portion of // the stacked bar. private int bar2Height; // Instance variable for holding the total value of the two bars. private double totalValue; // This method constructs a graph object. public Graph() { // Set the graph size. setSize(220, 240); // Initialize the lower bar and total bar values to zero. bar1Value = 0; totalValue = 0; } // This method may be called to set the lower bar and total bar values. The // values are then used to calculate the relative bar heights. public void setValues(double value1, double value2) { // Store the lower bar and total bar values. bar1Value = value1; totalValue = value2; // Calculate the relative bar heights. bar1Height = (int) (200 * (bar1Value / totalValue)); bar2Height = 200 - bar1Height; // Re-paint the graph. repaint(); } // This method is automatically called whenever the graph needs to be // rendered. It receives a Graphics object (its context) as a parameter. public void paint(Graphics g) { // Determine the size of the graph and fill it with black. Dimension graphSize = this.getSize(); g.setColor(Color.black); g.fillRect(0, 0, graphSize.width, graphSize.height); // If the lower bar value and total bar value are valid, draw the bars and // display their values. if (bar1Value != 0 && totalValue >= 0) { // Set the color of the top bar, draw it, and display its value in // currency format. g.setColor(Color.green); g.fillRect(80, 20, 40, bar2Height); g.drawString(Utility.moneyFormat(totalValue), 130, 20); // Set the color of the lower bar, draw it, and display its value in // currency format. g.setColor(Color.red); g.fillRect(80, 20 + bar2Height, 40, bar1Height); g.drawString(Utility.moneyFormat(bar1Value), 10, 20 + bar2Height); } // Otherwise, display a message. else { g.setColor(Color.red); g.drawString("Enter an amount greater than zero", 18, 125); } } }