/Users/lyon/j4p/src/gui/dialogs/FormattedTextDialog.java
|
1 package gui.dialogs;
2
3 import gui.run.RunButton;
4
5 import javax.swing.*;
6 import javax.swing.text.DefaultFormatterFactory;
7 import javax.swing.text.NumberFormatter;
8 import java.awt.*;
9 import java.beans.PropertyChangeEvent;
10 import java.beans.PropertyChangeListener;
11 import java.text.NumberFormat;
12 import java.text.ParseException;
13
14 /**
15 * Copyright DocJava, inc.
16 * User: lyon
17 * Date: Sep 3, 2004
18 * Time: 9:53:56 AM
19 */
20 public class FormattedTextDialog extends JDialog
21 implements PropertyChangeListener {
22 //Values for the text fields
23 private double amount = 100000;
24 private double rate = .075; //7.5 %
25 private int numPeriods = 30;
26
27 //Labels to identify the fields
28 private JLabel amountLabel = new JLabel("loan");
29 private JLabel rateLabel = new JLabel("years");
30 private JLabel numPeriodsLabel = new JLabel("yrs");
31 private JLabel paymentLabel = new JLabel("mnthy pmnt");
32
33 //Fields for data entry
34 private JFormattedTextField amountField=getAmountField();
35 private JFormattedTextField rateField;
36 private JFormattedTextField numPeriodsField;
37 private JFormattedTextField paymentField;
38
39 //Formats to format and parse numbers
40 private NumberFormat amountDisplayFormat;
41 private NumberFormat amountEditFormat;
42 private NumberFormat percentDisplayFormat;
43 private NumberFormat percentEditFormat;
44 private NumberFormat paymentFormat;
45
46 public FormattedTextDialog() {
47 Container c = getContentPane();
48 c.setLayout(new BorderLayout());
49 setUpFormats();
50 double payment = computePayment(amount,
51 rate,
52 numPeriods);
53
54 NumberFormatter percentEditFormatter = getPercentFormatter();
55 rateField = new JFormattedTextField(new DefaultFormatterFactory(
56 new NumberFormatter(percentDisplayFormat),
57 new NumberFormatter(percentDisplayFormat),
58 percentEditFormatter));
59 rateField.setValue(new Double(rate));
60 rateField.setColumns(10);
61 rateField.addPropertyChangeListener("value", this);
62
63 numPeriodsField = new JFormattedTextField();
64 numPeriodsField.setValue(new Integer(numPeriods));
65 numPeriodsField.setColumns(10);
66 numPeriodsField.addPropertyChangeListener("value", this);
67
68 paymentField = new JFormattedTextField(paymentFormat);
69 paymentField.setValue(new Double(payment));
70 paymentField.setColumns(10);
71 paymentField.setEditable(false);
72 paymentField.setForeground(Color.red);
73
74 //Tell accessibility tools about label/textfield pairs.
75 amountLabel.setLabelFor(amountField);
76 rateLabel.setLabelFor(rateField);
77 numPeriodsLabel.setLabelFor(numPeriodsField);
78 paymentLabel.setLabelFor(paymentField);
79
80 //Lay out the labels in a panel.
81 JPanel labelPane = new JPanel(new GridLayout(0, 1));
82 labelPane.add(amountLabel);
83 labelPane.add(rateLabel);
84 labelPane.add(numPeriodsLabel);
85 labelPane.add(paymentLabel);
86
87 //Layout the text fields in a panel.
88 JPanel fieldPane = getTextFieldPanel();
89
90 //Put the panels in this panel, labels on left,
91 //text fields on right.
92
93 //setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
94 c.add(labelPane, BorderLayout.CENTER);
95 c.add(fieldPane, BorderLayout.LINE_END);
96 c.add(getButtonPanel(this),BorderLayout.SOUTH);
97 pack();
98 setModal(true);
99 }
100
101 private NumberFormatter getPercentFormatter() {
102 NumberFormatter percentEditFormatter =
103 new NumberFormatter(percentEditFormat) {
104 public String valueToString(Object o)
105 throws ParseException {
106 Number number = (Number) o;
107 if (number != null) {
108 double d = number.doubleValue() * 100.0;
109 number = new Double(d);
110 }
111 return super.valueToString(number);
112 }
113
114 public Object stringToValue(String s)
115 throws ParseException {
116 Number number = (Number) super.stringToValue(s);
117 if (number != null) {
118 double d = number.doubleValue() / 100.0;
119 number = new Double(d);
120 }
121 return number;
122 }
123 };
124 return percentEditFormatter;
125 }
126
127 private JFormattedTextField getAmountField() {
128 JFormattedTextField amountField = new JFormattedTextField(new DefaultFormatterFactory(
129 new NumberFormatter(amountDisplayFormat),
130 new NumberFormatter(amountDisplayFormat),
131 new NumberFormatter(amountEditFormat)));
132 amountField.setValue(new Double(amount));
133 amountField.setColumns(10);
134 amountField.addPropertyChangeListener("value", this);
135 return amountField;
136 }
137
138 private JPanel getTextFieldPanel() {
139 JPanel fieldPane = new JPanel(new GridLayout(0, 1));
140 fieldPane.add(amountField);
141 fieldPane.add(rateField);
142 fieldPane.add(numPeriodsField);
143 fieldPane.add(paymentField);
144 return fieldPane;
145 }
146
147 public JPanel getButtonPanel(final JDialog parent) {
148 JPanel jp = new JPanel(new FlowLayout());
149 jp.add(new RunButton("OK"){
150 public void run() {
151 parent.setVisible(false);
152 }
153 });
154 return jp;
155 }
156
157 /**
158 * Called when a field's "value" property changes.
159 */
160 public void propertyChange(PropertyChangeEvent e) {
161 Object source = e.getSource();
162 if (source == amountField) {
163 amount = ((Number) amountField.getValue()).doubleValue();
164 } else if (source == rateField) {
165 rate = ((Number) rateField.getValue()).doubleValue();
166 } else if (source == numPeriodsField) {
167 numPeriods = ((Number) numPeriodsField.getValue()).intValue();
168 }
169
170 double payment = computePayment(amount, rate, numPeriods);
171 paymentField.setValue(new Double(payment));
172 }
173
174 public static void main(String[] args) {
175 FormattedTextDialog ftf = new FormattedTextDialog();
176
177 ftf.show();
178 System.out.println("done");
179
180 }
181
182 //Compute the monthly payment based on the loan amount,
183 //APR, and length of loan.
184 double computePayment(double loanAmt, double rate, int numPeriods) {
185 double I, partial1, denominator, answer;
186
187 numPeriods *= 12; //get number of months
188 if (rate > 0.001) {
189 I = rate / 12.0; //get monthly rate from annual
190 partial1 = Math.pow((1 + I), (0.0 - numPeriods));
191 denominator = (1 - partial1) / I;
192 } else { //rate ~= 0
193 denominator = numPeriods;
194 }
195
196 answer = (-1 * loanAmt) / denominator;
197 return answer;
198 }
199
200 //Create and set up number formats. These objects also
201 //parse numbers input by user.
202 private void setUpFormats() {
203 amountDisplayFormat = NumberFormat.getCurrencyInstance();
204 amountDisplayFormat.setMinimumFractionDigits(0);
205 amountEditFormat = NumberFormat.getNumberInstance();
206
207 percentDisplayFormat = NumberFormat.getPercentInstance();
208 percentDisplayFormat.setMinimumFractionDigits(2);
209 percentEditFormat = NumberFormat.getNumberInstance();
210 percentEditFormat.setMinimumFractionDigits(2);
211
212 paymentFormat = NumberFormat.getCurrencyInstance();
213 }
214 }
215