| ABMISpreadsheetView.java |
package lectures.mvc.toolkit;
import util.annotations.WebDocuments;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.JTextField;
/**
* Here we see how to write our own observer.
*
* Study the code.
*
* Debug-run MVCToolkitMain.
*
* Then, put a break point at the start of propertyChange method (after
* it is already debug-running).
*
* Edit the height field in the OE UI.
*
* When the breakpoint is hit, look at all the methods in the stack
* (in the "Debug" window).
*
* Look at the value of the argument to the method.
*
* Step over until you reach the end of the method.
*
* Which is true:
* (a) propertyChange in ABMISpreadsheetView is called directly by
* notifyAllListeners in APropertyListenerSupport.
* (b) notifyAllListeners in APropertyListenerSupport is called directly by
* propertyChange in ABMISpreadsheetView.
*
* Which is true:
* (a) notifyAllListeners in APropertyListenerSupport is called directly by
* setHeight in AnObservableBMISpreadsheet.
* (b) setHeight in AnObservableBMISpreadsheet is called directly by
* notifyAllListeners in APropertyListenerSupport.
*
* When the height property is set in the model, the resulting calls to propertyChange
* in the view call:
* (a) heightField.setText()
* (b) weightField.setText()
* (c) bmiSlider.setValue()
* (d) bmiProgressBar.setValue()
*
* Terminate the running program.
*
* Debug-run it again, while keeping the same break point from the start.
*
* Which is true:
* (a) propertyChange in ABMISpreadsheetView is called directly by setHeight()
* in AnObservableBMISpreadsheet.
* (b) propertyChange in ABMISpreadsheetView is called directly by
* addPropertyChangeListener() in AnObservableBMISpreadsheet.
*
* Step through for a while until you see what is going on.
*
* When the view becomes an observer of the model,
* (a) the widgets displaying all properties are refreshed.
* (b) the widgets displaying editable properties are refreshed.
* (c) the widgets displaying readonly properties are refreshed.
* (d) no widgets are refreshed.
*
* Next class: ABMISpreadsheetController
*
*/
@WebDocuments({"Lectures/MvcToolkit.pptx", "Lectures/MvcToolkit.pdf", "Videos/MvcToolkit.avi"})
public class ABMISpreadsheetView implements PropertyChangeListener {
JTextField heightField, weightField;
JSlider bmiSlider;
JProgressBar bmiProgressBar;
public ABMISpreadsheetView (JTextField theHeightField, JTextField theWeightField,
JSlider theBMISlider, JProgressBar theBMIProgressBar) {
heightField = theHeightField;
weightField = theWeightField;
bmiSlider = theBMISlider;
bmiProgressBar = theBMIProgressBar;
}
/*
* Method called on a PropertyChangeListener when a property event is fired.
* The ObjectEditor views implement this method.
* Here, one of our views is doing so.
*/
public void propertyChange(PropertyChangeEvent event) {
String propertyName = event.getPropertyName();
Double newValue = (Double) event.getNewValue();
/*
* Depending on which property was updated, change the appropriate widget
*/
if (propertyName.equalsIgnoreCase("height")) {
/*
* setText is just like println except that it updates existing text rather
* than displaying an additional value
*/
heightField.setText(newValue.toString());
} else if (propertyName.equalsIgnoreCase("weight")) {
weightField.setText(event.getNewValue().toString());
} else if (propertyName.equalsIgnoreCase("bmi")) {
double newBMI = newValue;
/*
* The slider and progress bar understand int values
*/
bmiSlider.setValue((int) newBMI);
bmiProgressBar.setValue((int) newBMI);
}
}
}