package variableEditorComponents;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JComponent;
import javax.swing.border.TitledBorder;
import variableEditorUI.VariableEditorUIUpdateThread;
import variables.Variable;
/**
* A TitledBorder which is bound to a Variable. When the Variable is changed,
* the content of the title of the border is updated with the new contents of
* the Variable.
*
* @author Curran Kelleher
*
*/
public class VariableBoundTitledBorder extends TitledBorder implements
Observer, VariableEditorComponent {
private static final long serialVersionUID = -2182294459528860891L;
/**
* The Variable to which this VariableBoundTitledBorder is bound.
*/
Variable variable;
/**
* The component which uses this border. The displayability of this
* component is checked with every update from the update thread, and if it
* is not displayable, this border is removed as an Observer from the update
* thread, hopefully allowing it to be garbage collected.
*/
JComponent parent = null;
/**
* 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 text with the current value of the Variable. This String is
* parseable into the actual value. It is generated by the method
* Value.toParseableString()
*/
String displayedValue = "";
/**
* whether or not to display the value of the variable along with it's name
* in the title of the border.
*/
private boolean displayVariableValueInTitle = true;
/**
* Construct a VariableBoundTitledBorder which is bound to the specified
* Variable.
*
* @param variable
* the variable to edit
* @param parent
* The component which uses this border. The displayability of
* this component is checked with every update from the update
* thread, and if it is not displayable, this border is removed
* as an Observer from the update thread, hopefully allowing it
* to be garbage collected. If this is null, no updates will
* occur.
*/
public VariableBoundTitledBorder(Variable variable, JComponent parent) {
super("");
this.variable = variable;
this.parent = parent;
VariableEditorUIUpdateThread.getInstance().addObserver(this);
updateWithCurrentVariableValue();
}
/**
* Construct a VariableBoundTitledBorder which is bound to the specified
* Variable.
*
* @param variable
* the variable to edit
* @param parent
* The component which uses this border. The displayability of
* this component is checked with every update from the update
* thread, and if it is not displayable, this border is removed
* as an Observer from the update thread, hopefully allowing it
* to be garbage collected. If this is null, no updates will
* occur.
* @param displayVariableValueInTitle
* whether or not to display the value of the variable along with
* it's name in the title of the border.
*/
public VariableBoundTitledBorder(Variable variable, JComponent parent,
boolean displayVariableValueInTitle) {
this(variable, parent);
this.displayVariableValueInTitle = displayVariableValueInTitle;
updateWithCurrentVariableValue();
}
/**
* Updates the content of the title to reflect the current value of the
* variable.
*
*/
public void updateWithCurrentVariableValue() {
String valueString = variable.evaluate().toParseableString();
setTitle(variable.toString().replace('_', ' ')
+ (displayVariableValueInTitle ? (" : " + valueString) : ""));
displayedValue = valueString;
if (parent != null)
parent.repaint();
}
/**
* 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 (parent != null) {
if (!parent.isDisplayable())
VariableEditorUIUpdateThread.getInstance().deleteObserver(
this);
else if (!variable.evaluate().toParseableString().equals(
displayedValue))
updateWithCurrentVariableValue();
} else
// if (parent == null)
VariableEditorUIUpdateThread.getInstance().deleteObserver(this);
}
/**
* This method does nothing, since the border never changes the value of the
* variable, it only displays it.
*/
public void bindToVariableEditorComponent(
VariableEditorComponent componentToUpdate) {
}
/**
*
* Sets whether or not to display the value of the variable along with it's
* name in the title of the border.
*/
public void setDisplayValue(boolean displayVariableValueInTitle) {
this.displayVariableValueInTitle = displayVariableValueInTitle;
}
}