View Single Post
  #1 (permalink)  
Old 01-12-2009, 02:06 AM
Laura Warren Laura Warren is offline
Member
 
Join Date: Nov 2008
Posts: 14
Rep Power: 0
Laura Warren is on a distinguished road
Default Display graph in tabbed panel
Hello:

You must be sick of these but I've got another mortgage example problem. This calculator needs to display an amortization table in one tab and a graph in another. Actually, my instructor says that creating a circle is adequate but I'd love to include a real pie chart based on the data.

My table works fine, except for 2 problems. Once I placed it in a tab, my scroll bar disappeared. I know I must have introduced the JScrollPane in the wrong place, but have tried several ways without success. My other problem with the table is that once I moved it to a tab the first column (payment numbers) appears empty.

However, my first priority is trying to make the graph work. I've found some code from roseindia.net and have tried to adapt it but am in over my head. (We haven't really covered this in the class.) A perfect scenario would be to send the total interest and principal paid to the graph method and display that on the graph panel. I just don't quite know how to call this.

Any help would be greatly appreciated.

Thank you so much!!

Here is my code:


Code:
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.*;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.*;
import javax.swing.JTabbedPane;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
 
class WarrenMortgageAppWeek5
{
    public static void main(String[] args)
    {
        JFrame Mortgageframe = new MortgageFrame(); 
        Mortgageframe.setVisible(true);     
    }
 }  //end of WarrenMortgageAppWeek5 class
 
class MortgageFrame extends JFrame
{
    /* This section will set up the application window
     * and size it to fit the controls.  It will also
     * call a routine called "centerWindow" to calculate
     * the user's screen size and center the application.
     * Finally it adds the panels that will hold the components.
     * 
     */ 
 
    public MortgageFrame()
    {
        setTitle("Laura Warren Mortgage Calculator Week 5");    //title of frame
        setSize(440, 465);                                      //size of frame
        centerWindow(this);                                     //calls method to center window
        setResizable(false);                                    //prevents sizing
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         //sets the default close action for the frame
        JPanel panel = new MortgagePanel();
        this.add(panel);                                        //adds the panel to the frame's content pane
    } // end MortgageFrame method
 
    private void centerWindow(Window w)
    {
        Toolkit tk = Toolkit.getDefaultToolkit();               //determines number of pixels on any screen
        Dimension d = tk.getScreenSize();                       //and calculates center                   
        setLocation((d.width-w.getWidth())/2, (d.height-w.getHeight())/2);
     } // end of centerWindow method
 
 
}// end of MortgageFrame class
// This section will specify the controls (labels, text fields, and buttons)
// It will also declare variables and arrays
class MortgagePanel extends JPanel implements ActionListener
{
    private JLabel              loanAmountLabel; 
    private JTextField          loanAmountTextField;
    private JLabel              totalInterestLabel;                //label and text field for Annual Interest Rate
    private JTextField          totalInterestTextField;
    private JLabel              totalPrincipalLabel;               //label and text field for Term of loan
    private JTextField          totalPrincipalField;
    private JLabel              monthlyPaymentLabel;
    private JTextField          monthlyPaymentTextField;
    private JLabel              errorlbl; 
    private JLabel              rateAndTermLabel;
    private JComboBox           optionsCombo;
    private JTable              paymentsTable;
    private DefaultTableModel   table;
    private JButton             calculateButton;                  //the Calculate button
    private JButton             resetButton;                      //the Reset button
    private JButton             exitButton;                       //the Exit button
    private JScrollPane         paymentsScrollPane;
    int rows = 400;             //months not likely to exceed this value
    int columns = 4;
    int years = 0;
    double monthlyRate = 0;
    String columnHeadings[] = { "Pmt #", "Beg Bal", "Principle", "Interest"  };
    String[][]paymentData = new String[rows][columns];
    int[] TermYears             = {7, 15, 30};        
    double[] AnnualRate         = {5.35, 5.5, 5.75};   
    DecimalFormat PmtFormat = new DecimalFormat("$#,##0.00");
 
/* This next section adds the components and panels to the frame.
 * The extra label field will display any error messages in red. 
 * The frame will be divided into panels
 * The first is the top panel, which includes the loan amount entry field
 * The second contains the error label
 * THe fourth contains the input fields for week 3 rate and term selection
 * The fifth is the option panel, which contains the combo box
 * The sicth is the display of the montly payment amount
 * The seventh contains the table that will display amortization
*/    
 
    public MortgagePanel()
    {
        //this section creates the top panel
        //holds the user input section for loan amount
        JPanel topPanel = new JPanel();                         //define the panel within the frame
        topPanel.setLayout (new FlowLayout());   
        loanAmountLabel = new JLabel("Amount of Loan:     ");     //add Loan Amount label to panel
        topPanel.add(loanAmountLabel);
        loanAmountTextField = new JTextField(11);               //set size and add Loan text field to panel
        topPanel.add(loanAmountTextField);                      //add Loan Amount to panel
 
        //this section creates the area for the feedback label
        //messages appear in red
        JPanel errorPanel= new JPanel();
        errorPanel.setLayout (new FlowLayout());
        errorlbl = new JLabel("    ");             //set initial value for error label one
        errorlbl.setForeground (Color.red);       
        errorPanel.add(errorlbl);                  //add error label to panel 
 
        //this section creates the area for the option box
        JPanel optionPanel = new JPanel();
        optionPanel.setLayout(new FlowLayout());
        rateAndTermLabel = new JLabel("Rate / Term:            ");
        optionPanel.add(rateAndTermLabel);
        String[]options = {"7 years at 5.35%", "15 years at 5.5%", "30 years at 5.75%"};
        optionsCombo = new JComboBox(options);
        optionPanel.add(optionsCombo);
        //this section contains the calculated monthly payment amount
        JPanel monthlyPaymentPanel = new JPanel();
        monthlyPaymentLabel = new JLabel("Monthly Payment: ");         //add Loan Amount label to panel
        monthlyPaymentPanel.add(monthlyPaymentLabel);
        monthlyPaymentTextField = new JTextField(11); 
        monthlyPaymentTextField.setEditable(false);                   //prevent editing of payment field
        monthlyPaymentTextField.setFocusable(false);                  
        monthlyPaymentPanel.add(monthlyPaymentTextField);             //add field to panel
        //this section contains the total interest paid amount
        JPanel totalInterestPanel = new JPanel();
        totalInterestLabel = new JLabel("Tot Interest Paid:   ");         //add Loan Amount label to panel
        totalInterestPanel.add(totalInterestLabel);
        totalInterestTextField = new JTextField(11); 
        totalInterestTextField.setEditable(false);                   //prevent editing of payment field
        totalInterestTextField.setFocusable(false);                  
        totalInterestPanel.add(totalInterestTextField);             //add field to panel
 
        //this section contains the total interest paid amount
        JPanel totalPrinPanel = new JPanel();
        totalPrincipalLabel = new JLabel("Tot Principal Paid:");         //add Loan Amount label to panel
        totalPrinPanel.add(totalPrincipalLabel);
        totalPrincipalField = new JTextField(11); 
        totalPrincipalField.setEditable(false);                   //prevent editing of payment field
        totalPrincipalField.setFocusable(false);                  
        totalPrinPanel.add(totalPrincipalField);             //add field to panel
 
 
        //This section creates a panel to display the 3 buttons
        //(Calculate, Reset, and Exit)
        JPanel buttonPanel = new JPanel();                          //create a button panel
        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));    //using FlowLayout grid
        calculateButton = new JButton("Calculate");                 //set up Calculate button and listener
        calculateButton.addActionListener(this);
        buttonPanel.add(calculateButton);
 
        resetButton = new JButton("Reset");                         //set up Reset button and listener
        resetButton.addActionListener(this);
        buttonPanel.add(resetButton);
 
        exitButton = new JButton("Exit");                           //set up Exit button and listener
        exitButton.addActionListener(this);
        buttonPanel.add(exitButton);
 
        //this section contains table and graph panes
        JTabbedPane tabbedPane = new JTabbedPane();
 
        //amort pane displays amortization table
        JPanel amort = new JPanel();
        tabbedPane.addTab("Table", amort);
 
        paymentsTable = new JTable();
        table = new DefaultTableModel(columnHeadings,4);      
        paymentsTable.setModel(table);
        paymentsTable.setPreferredScrollableViewportSize(new Dimension(500, 375));
        paymentsTable.setFillsViewportHeight(true);
        paymentsScrollPane = new JScrollPane(paymentsTable);
        amort.add(paymentsScrollPane);
        table.setDataVector(paymentData, columnHeadings); 
 
        //graph pane displays pie graph
        JPanel PieChartPanel = new JPanel();        
        tabbedPane.addTab("Graph", PieChartPanel);
        //I'm not sure what to do here
 
        //adds all sections to the main window using the GridLayout structure
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));;
        this.add(topPanel,BorderLayout.CENTER); 
        this.add(errorPanel,BorderLayout.CENTER);  
        this.add(optionPanel,BorderLayout.CENTER); 
        this.add(monthlyPaymentPanel,BorderLayout.CENTER);
        this.add(totalInterestPanel,BorderLayout.CENTER);
        this.add(totalPrinPanel, BorderLayout.CENTER);
        this.add(buttonPanel, BorderLayout.CENTER);
        this.add(tabbedPane, BorderLayout.CENTER);
 
 
    } //end of MortgagePanel method
 
 
/* 
 This section defines what happens when each button is clicked.
 *  The Exit button will close the application.
 *  The Reset button will clear all fields.  
 *  The Calculate button will test for missing loan amount 
 *  When valid loan amount is entered, the monthly payment calculates.
*/    
    public void actionPerformed(ActionEvent e) throws NumberFormatException
    {
        Object source = e.getSource();
//      Exit button has been clicked        
        if (source == exitButton)      
            System.exit(0);            
//      Calculate button has been clicked
        if (source == calculateButton)            
        {
            resetTable();
            errorlbl.setText("     ");
            double loanAmount = 0.0;       
            double monthlyPayment = 0.0;
            double interestRate = 0.0;
            //test for missing field by checking length of entry     
             if(loanAmountTextField.getText().length() == 0)      
             {  
                errorlbl.setText("Please enter Loan Amount");  
                loanAmountTextField.requestFocus();
             }   
             else //loan amount is not blank
             {
 
             try 
             {
             loanAmount = Double.parseDouble(loanAmountTextField.getText());
             } // end try
             catch(NumberFormatException p) 
             {
                //catch null pointer exception if Principal is null
               JOptionPane.showMessageDialog(null, "Invalid Entry!  Please Try Again",
                                              "ERROR", JOptionPane.ERROR_MESSAGE);
               loanAmountTextField.setText("");
               loanAmountTextField.requestFocus();  
             } // end catch number format exception           
            if (loanAmount <=0)
            {
               errorlbl.setText("Please enter a positive amount.");
               loanAmountTextField.setText("");
               loanAmountTextField.requestFocus();   
            }
            else 
            {
            errorlbl.setText("Thank you!");  
            //select rate and term from combination box
                switch (optionsCombo.getSelectedIndex()) 
                {
                case 0:
                    interestRate = 5.35;
                    years = 7;
                    break;
                case 1:
                    interestRate = 5.5;
                    years= 15;
                    break;
                case 2:
                    interestRate = 5.75;
                    years = 30;
                    break;
                } // end switch  
 
 
            //format and place monthly payment calculation
            //call method to calculate values for Loan Amount
            //calculates table      
        double monthlyRate = interestRate / 12 /100;
        int termMonths = years * 12;
        monthlyPayment = loanAmount * monthlyRate/(1-(1/Math.pow(1 + monthlyRate,termMonths))); 
 
 
        //declare and initialize variable for amortization calculations
        double BeginningBal = Double.parseDouble(loanAmountTextField.getText());
        double EndingBal;
        double Principal;   
        double InterestPaid; 
        double CumInterest      = 0; 
        double CumPrincipal     = 0;
        //this section loops through all payments and calculates 
        //Beginning Balance, Principle, and Interest Paid values
 
        for (int MonthCounter = 1; MonthCounter <= termMonths; MonthCounter++ )
            {
             InterestPaid  = BeginningBal * monthlyRate;  
             Principal     = monthlyPayment - InterestPaid;  
             EndingBal     = BeginningBal - Principal; 
             CumInterest   = CumInterest + InterestPaid;
             CumPrincipal  = CumPrincipal + Principal;
 
             //this section will fill in table values row by row until all payments calculated
             paymentData[MonthCounter-1][0] = ""+MonthCounter;
             paymentData[MonthCounter-1][1] = PmtFormat.format(BeginningBal);
             paymentData[MonthCounter-1][2] = PmtFormat.format(Principal);
             paymentData[MonthCounter-1][3] = PmtFormat.format(InterestPaid);
 
             //the Ending Balance for one month becomes the Beginning Balance for the next
             BeginningBal  = EndingBal;
 
            } // end for   
 
 
            monthlyPaymentTextField.setText(PmtFormat.format(monthlyPayment));
            totalInterestTextField.setText(PmtFormat.format(CumInterest));
            totalPrincipalField.setText(PmtFormat.format(CumPrincipal));  
 
            table.setDataVector(paymentData, columnHeadings);    
 
            } // loan amount entered
          } // loan amount blank
        }// end calculate button
         if (source ==resetButton)     
        {
          loanAmountTextField.setText(""); 
          monthlyPaymentTextField.setText("");
          totalInterestTextField.setText("");
          totalPrincipalField.setText("");
          errorlbl.setText("                     ");
          resetTable();
 
        }//end if source reset
//========================================================   
    } // end ActionPerformed
public void resetTable()
    {
        //clear existing values from table and text fields
        for(int MonthCounter=0; MonthCounter<=360; MonthCounter++)
            {
            paymentData[MonthCounter][0]=" ";
            paymentData[MonthCounter][1]=" ";
            paymentData[MonthCounter][2]=" ";
            paymentData[MonthCounter][3]=" ";
            }
         table.setDataVector(paymentData, columnHeadings);
         errorlbl.setText("Values Cleared");
 
    } // end resetTable
 class PieChartPanel extends JPanel
{
    BufferedImage image;
    final int PAD = 30;
    Font font;
    NumberFormat numberFormat;
 
  public PieChartPanel()
    {
        font = new Font("Arial", Font.BOLD, 15);
        numberFormat = NumberFormat.getPercentInstance();
        addMouseListener(new Visibility(this));
        addComponentListener(new ComponentAdapter()
        {});
    }
 protected void paintComponent(Graphics graphics)
    {
        super.paintComponent(graphics);
        Graphics2D graphics2d = (Graphics2D)graphics;
        graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        createChartImage();
        graphics2d.drawImage(image, 0, 0, this);
    }
    private void createChartImage()
    {
        //I would like to replace these values by total interest and total principal
        int[] marks = { 199994, 220172};
        int width = getWidth();
        int height = getHeight();
        int cp = width/2;
        int cq = height/2;
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = image.createGraphics();
        g2.setPaint(Color.yellow);
        g2.fillRect(0, 0, width, height);
        g2.setPaint(Color.black);
        int pie = Math.min(width,height) - 2*PAD;
        g2.draw(new Ellipse2D.Double(cp - pie/2, cq - pie/2, pie, pie));
        double total = 0;
        for(int j = 0; j < marks.length; j++)
            total += marks[j];
        double theta = 0, phi = 0;
        double p, q;
        for(int j = 0; j < marks.length; j++)
        {
            p = cp + (pie/2) * Math.cos(theta);
            q = cq + (pie/2) * Math.sin(theta);
            g2.draw(new Line2D.Double(cp, cq, p, q));
            phi = (marks[j]/total) * 2 * Math.PI;
            p = cp + (9*pie/24) * Math.cos(theta + phi/2);
            q = cq + (9*pie/24) * Math.sin(theta + phi/2);
            g2.setFont(font);
            String st = String.valueOf(marks[j]);
            FontRenderContext frc = g2.getFontRenderContext();
            float textWidth = (float)font.getStringBounds(st, frc).getWidth();
            LineMetrics lm = font.getLineMetrics(st, frc);
            float sp = (float)(p - textWidth/2);
            float sq = (float)(q + lm.getAscent()/2);
            g2.drawString(st, sp, sq);
            p = cp + (pie/2 + 4*PAD/5) * Math.cos(theta + phi/2);
            q = cq + (pie/2 + 4*PAD/5) * Math.sin(theta+ phi/2);
            st = numberFormat.format(marks[j]/total);
            textWidth = (float)font.getStringBounds(st, frc).getWidth();
            lm = font.getLineMetrics(st, frc);
            sp = (float)(p - textWidth/2);
            sq = (float)(q + lm.getAscent()/2);
            g2.drawString(st, sp, sq);
            theta += phi;
        }
        g2.dispose();
    }
 public void toggleVisibility()
    {
        repaint();
    }
}
class Visibility extends MouseAdapter
{
    PieChartPanel piechart;
    public Visibility(PieChartPanel pc)
    {
        piechart = pc;
    }
}
} // end MortgagePanel class
__________________
Laura
Reply With Quote