View Javadoc

1   /*
2    * Created on Apr 9, 2005 by davidson
3    */
4   package ca.spaz.cron.ui;
5   
6   import java.awt.BorderLayout;
7   import java.awt.event.*;
8   import java.util.*;
9   
10  import javax.swing.*;
11  import javax.swing.event.*;
12  
13  import ca.spaz.cron.database.*;
14  import ca.spaz.gui.DoubleField;
15  
16  /***
17   * A measure widget displays the UI for choosing an amount of a food item, based
18   * on various Measures stored for the particular food being weighed.
19   * 
20   * @author davidson
21   */
22  public class MeasureWidget extends JPanel implements ItemListener, ActionListener, KeyListener {
23     // initial weight by default
24     private Measure curMeasure = Measure.GRAM;
25     
26     // list of weights for selected food
27     private JComboBox measures = new JComboBox();
28     
29     // multiplier (amount) of currently showing weight
30     private DoubleField multiplier = new DoubleField(0,8);
31     
32     // change listeners
33     private Vector listeners = new Vector();
34     
35     // determiens if multiplier value is linked to the weight
36     private boolean linked = false;
37     
38     /***
39      * Construct a new measure widget
40      */
41     public MeasureWidget() {
42        multiplier.setRange(0,1000000);
43        multiplier.setValue(1);
44        
45        measures.addItemListener(this);
46        multiplier.addActionListener(this);
47        multiplier.addKeyListener(this);
48        
49        setLayout(new BorderLayout(4,4));
50        add(multiplier, BorderLayout.WEST);
51        add(measures, BorderLayout.CENTER);
52     }
53  
54     /***
55      * Set the measure to display weights for a particular food.
56      */
57     public void setFood(Food f) {
58        measures.setModel(new DefaultComboBoxModel(f.getMeasures().toArray()));
59        curMeasure = Measure.GRAM;
60        fireChangeEvent();
61     }
62  
63     /***
64      * Set the weight to display
65      * @param w the type of measure
66      * @param mult the multiplier for that measure
67      */
68     public void setMeasure(Measure w, double mult) {
69        measures.setSelectedItem(w);
70        multiplier.setValue(mult);
71        fireChangeEvent();
72     }
73  
74     /***
75      * Update the widget after a weight change has occurred.
76      * Called when weight menu is changed or edited
77      */
78     public void updateMeasure() {
79        Measure w = getSelectedMeasure();
80        if (w != curMeasure) {
81           // if linked, the weight translates the multiplier from the last
82           // selected weight, such that the actual amount of food stays constant.         
83           if (linked) {
84              double mult = w.getAmount();
85              if (curMeasure != null) {
86                 double grams = curMeasure.getGrams() * multiplier.getValue();
87                 mult = grams/w.getGrams();
88              }
89              multiplier.setValue(mult);
90           }
91           focus();
92           curMeasure = w;
93        }
94        fireChangeEvent();
95     }      
96  
97     /***
98      * Get the multiplier for the current weight and mult settings.
99      * @return a multiple of the standard nutrient value (x per 100g)
100     */
101    public double getMultiplier() {
102       return getGrams() / 100.0;
103    }
104 
105    /***
106     * Get the number of grams in this measure
107     * @return the number of grams in this state
108     */
109    public double getGrams() {
110       Measure w = getSelectedMeasure();
111       if (w != null) {
112          return multiplier.getValue() * w.getGrams();// * (1.0/w.getAmount()); 
113       }
114       return 0;
115    }
116    
117    public Measure getSelectedMeasure() {
118       return (Measure)measures.getSelectedItem();
119    }
120    
121    /***
122     * Focus the component, selecting the text field and giving it 
123     * keyboard focus.
124     */
125    public void focus() {
126       multiplier.requestFocus();
127       multiplier.selectAll();      
128    }
129    
130    public void addChangeListener(ChangeListener l) {
131       listeners.add(l);
132    }
133 
134    public void addRemoveListener(ChangeListener l) {
135       listeners.remove(l);
136    }
137    
138    public void fireChangeEvent() {
139       ChangeEvent ce = new ChangeEvent(this);
140       Iterator iter = listeners.iterator();
141       while (iter.hasNext()) {
142          ((ChangeListener)iter.next()).stateChanged(ce);
143       }
144    }
145 
146    /***
147     * Called if the weight menu state is changed
148     */
149    public void itemStateChanged(ItemEvent e) {
150       updateMeasure();
151    }
152 
153    /***
154     * Called when the text field is set
155     */
156    public void actionPerformed(ActionEvent arg0) {
157       fireChangeEvent();
158    }
159 
160    public void keyTyped(KeyEvent arg0) {
161    }
162 
163    public void keyPressed(KeyEvent arg0) {
164    }
165 
166    /***
167     * Called when the text field is edited
168     */
169    public void keyReleased(KeyEvent arg0) {
170       fireChangeEvent();
171    }
172 
173    /***
174     * If linked, changing a weight will update the multiplier
175     * to keep the grams constant. Otherwise, the multiplier is left unchanged.
176     * 
177     * @return true if the multiplier is linked to the weight
178     */
179    public boolean isLinked() {
180       return linked;
181    }
182 
183 
184    /***
185     * If linked, changing a weight will update the multiplier
186     * to keep the grams constant. Otherwise, the multiplier 
187     * is left unchanged.
188     */
189    public void setLinked(boolean linked) {
190       this.linked = linked;
191    }
192 }