/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