View Javadoc

1   /**
2    * Copyright 2009 Timothy Johnston Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3    * file except in compliance with the License. You may obtain a copy of the License at
4    * 
5    * http://www.apache.org/licenses/LICENSE-2.0
6    * 
7    * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8    * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9    * specific language governing permissions and limitations under the License.
10   */
11  package com.timjohnstondev.unitconverter.view;
12  
13  import java.awt.Color;
14  import java.awt.Component;
15  import java.awt.Dimension;
16  import java.awt.GridLayout;
17  import java.awt.event.KeyAdapter;
18  import java.awt.event.KeyEvent;
19  import java.math.BigDecimal;
20  import java.util.ResourceBundle;
21  import javax.swing.BorderFactory;
22  import javax.swing.JLabel;
23  import javax.swing.JPanel;
24  import javax.swing.JTextField;
25  import javax.swing.event.DocumentEvent;
26  import javax.swing.event.DocumentListener;
27  import com.timjohnstondev.unitconverter.controller.LogicController;
28  
29  /**
30   * This panel contains all of the {@code JTextField}s for input, conversion factor and result display. All fields can be
31   * copied from, but only the input field can take number input.
32   */
33  public class CalculationPanel extends JPanel implements Configuration
34  {
35    private LogicController logicController;
36    private JLabel inputLabel;
37    private JLabel conversionFactorLabel;
38    private JLabel resultLabel;
39    private JTextField input;
40    private ConversionTextField conversionFactor;
41    private JTextField result;
42    private ResourceBundle resources;
43  
44    /**
45     * Constructs a {@code CalculationPanel} and sets the layout and size of the panel and its contents.
46     */
47    public CalculationPanel()
48    {
49      setMaximumSize(new Dimension(500, 80));
50      setLayout(new GridLayout(2, 3, 10, 5));
51      setBorder(BorderFactory.createEmptyBorder(20, 10, 5, 10));
52      logicController = new LogicController();
53  
54      resources = ResourceBundle.getBundle("com.timjohnstondev.unitconverter.view.View");
55      inputLabel = new JLabel(resources.getString("CalculationPanel.inputLabel"));
56      conversionFactorLabel = new JLabel(resources.getString("CalculationPanel.conversionFactorLabel"));
57      resultLabel = new JLabel(resources.getString("CalculationPanel.resultLabel"));
58      configureLabels();
59  
60      input = new JTextField();
61      input.setDocument(new InputFilter(resources.getString("CalculationPanel.allowableCharacters")));
62      conversionFactor = new ConversionTextField();
63      result = new JTextField();
64      addListeners();
65  
66      add(inputLabel);
67      add(conversionFactorLabel);
68      add(resultLabel);
69      add(input);
70      add(conversionFactor);
71      add(result);
72    }
73  
74    /**
75     * Updates the conversion factor field and stores the exact number or formula because the display may limit the
76     * characters to show.
77     * 
78     * @param conversion the conversion factor or formula
79     */
80    public final void setConversion(final String conversion)
81    {
82      conversionFactor.setConversion(conversion);
83      final String text = logicController.getConversionFactor(conversion);
84      conversionFactor.setText(text);
85    }
86  
87    /**
88     * Updates the result field if the input field has valid data and a conversion factor is selected.
89     * 
90     * @param molecularWeightCorrection the correction factor to adjust for molecular weight in mole to mass and mass to
91     *          mole conversions
92     */
93    public final void updateCalculations(final BigDecimal molecularWeightCorrection)
94    {
95      final String conversion = conversionFactor.getConversion();
96      final String resultText = logicController.getResult(input.getText(), conversion, molecularWeightCorrection);
97      result.setText(resultText);
98    }
99  
100   private void updateCalculations()
101   {
102     updateCalculations(BigDecimal.ONE);
103   }
104 
105   /**
106    * Clears out the text of the conversion factor and results displays by setting their text to {@code null}.
107    */
108   public final void clearFactor()
109   {
110     conversionFactor.setConversion(null);
111     conversionFactor.setText(null);
112     result.setText(null);
113   }
114 
115   private void configureLabels()
116   {
117     final JLabel[] labels = {inputLabel, conversionFactorLabel, resultLabel};
118     for (JLabel label : labels)
119     {
120       label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
121     }
122   }
123 
124   private void addListeners()
125   {
126     input.getDocument().addDocumentListener(new InputDocumentListener());
127     conversionFactor.addKeyListener(new DoNothingKeyListener());
128     result.addKeyListener(new DoNothingKeyListener());
129   }
130 
131   private class InputDocumentListener implements DocumentListener
132   {
133     @Override
134     public final void changedUpdate(final DocumentEvent e)
135     {
136       updateCalculations();
137     }
138 
139     @Override
140     public final void insertUpdate(final DocumentEvent e)
141     {
142       changedUpdate(e);
143     }
144 
145     @Override
146     public final void removeUpdate(final DocumentEvent e)
147     {
148       changedUpdate(e);
149     }
150   }
151 
152   private class DoNothingKeyListener extends KeyAdapter
153   {
154     @Override
155     public final void keyPressed(final KeyEvent e)
156     {
157       if (e.getKeyCode() == KeyEvent.VK_V)
158       {
159         e.consume();
160       }
161     }
162 
163     @Override
164     public final void keyTyped(final KeyEvent e)
165     {
166       e.consume();
167     }
168   }
169 
170   private class ConversionTextField extends JTextField
171   {
172     private String conversion;
173 
174     private void setConversion(final String newConversion)
175     {
176       conversion = newConversion;
177     }
178 
179     private String getConversion()
180     {
181       return conversion;
182     }
183   }
184 
185   @Override
186   public final void setBackgroundColor(final Color color)
187   {
188     setBackground(color);
189     final Component[] children = getComponents();
190     for (Component child : children)
191     {
192       if (child instanceof JLabel)
193       {
194         child.setBackground(color);
195       }
196       if (child instanceof JTextField)
197       {
198         child.setBackground(color.brighter());
199       }
200     }
201   }
202 
203   @Override
204   public final void setForegroundColor(final Color color)
205   {
206     setForeground(color);
207     final Component[] children = getComponents();
208     for (Component child : children)
209     {
210       child.setForeground(color);
211     }
212   }
213 
214   @Override
215   public final void setFontSize(final float fontSize)
216   {
217     setFont(getFont().deriveFont(fontSize));
218     final Component[] children = getComponents();
219     for (Component child : children)
220     {
221       child.setFont(child.getFont().deriveFont(fontSize));
222     }
223   }
224 }