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; } }