package variableEditorComponents;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import valueTypes.BooleanValue;
import variableEditorUI.VariableEditorUIUpdateThread;
import variables.Variable;
import expressionConsole.ExpressionConsoleModel;
/**
* A JCheckBox which is bound to a Variable. When the user checks or unchecks
* the box, the content of the Variable is updated. When the Variable is changed
* from another source, the state of the box is updated with the new contents of
* the Variable.
*
* @author Curran Kelleher
*
*/
public class VariableBoundCheckBox extends JCheckBox implements Observer,
ItemListener, VariableEditorComponent {
private static final long serialVersionUID = -7777499408692975081L;
/**
* The Variable to which this VariableBoundCheckBox is bound.
*/
Variable variable;
/**
* The Value that is currently being displayed. This is checked against the
* actual value of the Variable periodically to decide whether or not to
* update the display. This String is parseable into the actual value. It is
* generated by the method Value.toParseableString()
*/
String displayedValue = "";
/**
* set true to ignore self-generated checkbox events
*/
boolean ignoreUpdates = false;
/**
* Construct a VariableBoundCheckBox which is bound to the specified Variable.
*
* @param variable
* the variable to edit
*/
public VariableBoundCheckBox(Variable variable) {
super(variable.toString());
this.variable = variable;
// get notifications every second.
VariableEditorUIUpdateThread.getInstance().addObserver(this);
// initialize the check box
updateWithCurrentVariableValue();
// listen for slider movements
addItemListener(this);
}
/**
* Updates the content of the check box to reflect the current value of the
* variable.
*
*/
public void updateWithCurrentVariableValue() {
ignoreUpdates = true;
setSelected(BooleanValue.extractBooleanValue(variable.evaluate()));
displayedValue = variable.evaluate().toParseableString();
ignoreUpdates = false;
}
/**
* Get the update from the VariableEditorUIUpdateThread
*/
public void update(Observable o, Object arg) {
if (o == VariableEditorUIUpdateThread.getInstance())
// if this component is no longer usable, remove it as an Observer.
if (!isDisplayable())
VariableEditorUIUpdateThread.getInstance().deleteObserver(this);
else if (!variable.evaluate().toParseableString().equals(
displayedValue))
updateWithCurrentVariableValue();
}
/**
* Respond to check box changes
*/
public void itemStateChanged(ItemEvent e) {
if (!ignoreUpdates) {
variable.set(new BooleanValue(
e.getStateChange() == ItemEvent.SELECTED));
// log the change for correct replay
displayedValue = variable.evaluate().toParseableString();
ExpressionConsoleModel.getInstance().enterExpression(
variable.toString() + " = " + displayedValue);
}
}
/**
* Sets up a VariableEditorComponent such that
* updateWithCurrentVariableValue() will be called in it whenever the
* checkbox is checked or unchecked.
*
* @param componentToUpdate
* the VariableEditorComponent to update.
*/
public void bindToVariableEditorComponent(
VariableEditorComponent componentToUpdate) {
class ComponentChangeListener implements ChangeListener {
VariableEditorComponent componentToUpdate;
public ComponentChangeListener(
VariableEditorComponent componentToUpdate) {
this.componentToUpdate = componentToUpdate;
}
public void stateChanged(ChangeEvent e) {
componentToUpdate.updateWithCurrentVariableValue();
}
}
addChangeListener(new ComponentChangeListener(componentToUpdate));
}
}