/**
  * setup a dummy mortgage payment that gives us a large set of values so that the table can resize
  * its columns based on what is likely a "worst-case" scenario. this should leave plenty of room
  * for real mortgage payments without making the window overly large and yet still reacting to
  * local system visual sizes.
  */
 private void sizeMortgageTable() {
   resetMortgage();
   final MortgagePayment p = new MortgagePayment(999999.99, 999999.99, 999999.99, 99999999.99);
   paymentsModel.setPayments(new MortgagePayment[] {p});
   paymentsTable.resizeTableColumns();
   paymentsTable.limitTableViewport(VISIBLE_PAYMENT_TABLE_ROWS, true, false);
   resetMortgage();
 }
  /** Creates all of the UI components used by this application. */
  private void createComponents() {
    // the data entry fields need their focus watched...
    final FocusWatcher focusWatcher = new FocusWatcher();

    // create the label and field for the mortgage principal amount
    fieldPrincipal = new JTextField();
    fieldPrincipal.addFocusListener(focusWatcher);
    fieldPrincipal.setColumns(FIELD_COLUMNS);

    labelPrincipal = new JLabel(LABEL_PRINCIPAL);
    labelPrincipal.setLabelFor(fieldPrincipal);

    // create the label and field for the mortgage terms combo-box/list
    fieldMortgageChoices = new JComboBox();
    fieldMortgageChoices.addActionListener(new FieldActionListener());

    labelMortgageChoices = new JLabel(LABEL_MORTGAGE_CHOICES);
    labelMortgageChoices.setLabelFor(fieldMortgageChoices);

    // create the label and field for the mortgage term period
    fieldTerm = new JTextField();
    fieldTerm.addFocusListener(focusWatcher);
    fieldTerm.setColumns(FIELD_COLUMNS);

    labelTerm = new JLabel(LABEL_TERM);
    labelTerm.setLabelFor(fieldTerm);

    // create the label and field for the mortgage annual interest rate
    fieldRate = new JTextField();
    fieldRate.addFocusListener(focusWatcher);
    fieldRate.setColumns(FIELD_COLUMNS);

    labelRate = new JLabel(LABEL_RATE);
    labelRate.setLabelFor(fieldRate);

    // create the label that will provide the header text for the panel
    labelHeader = new JLabel(MSG_HEADER);

    // create the label that will provide any mesages to the user,
    // including the newly calculated mortgage payment amounts
    labelMessage = new JLabel("");

    // create a chart used to display the mortgage payment detail; a small
    // pixel size is used so our primary window isn't sized too large
    paymentsChart = new Chart(320, 240);
    paymentsChart.setBorder(BorderFactory.createLineBorder(Color.BLACK));

    // TODO
    paymentsModel = new MortgagePaymentsTableModel();
    paymentsTable = new JTableHelper(paymentsModel);
    paymentsTable.setColumnSelectionAllowed(false);
    paymentsTable.setRowSelectionAllowed(true);
    paymentsTable.setDefaultRenderer(Double.class, new CurrencyRenderer());

    // create the button that will allow the user to calculate a mortgage
    // payment schedule from the current input
    final Action calcAction = new CalcAction();
    calcButton = new JButton(calcAction);
    getRootPane().setDefaultButton(calcButton);

    // set default values for all of the fields to make the user feel cozy
    fieldPrincipal.setText(FMT_PRINCIPAL.format(DEFAULT_PRINCIPAL));
    fieldRate.setText(FMT_RATE.format(DEFAULT_RATE));
    fieldTerm.setText(FMT_TERM.format(DEFAULT_TERM));

    // watch the documents of our input fields so that we can reset our
    // current mortgage calculate whenever the user changes anything
    final DocumentListener docWatcher = new DocumentWatcher();
    fieldPrincipal.getDocument().addDocumentListener(docWatcher);
    fieldRate.getDocument().addDocumentListener(docWatcher);
    fieldTerm.getDocument().addDocumentListener(docWatcher);
  }