package net.iplantevin.ql.gui.formcomponents; import net.iplantevin.ql.evaluation.UndefinedVal; import net.iplantevin.ql.gui.main.FormFrame; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import java.awt.*; import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4; /** * Contains a label and a widget. Implements the necessary value change event * related actions. * * @author Ivan */ public abstract class AbstractWidgetContainer extends AbstractFormComponent { private JLabel questionLabel; private String identifier; private JComponent widget; private int preferredLabelWidth; private Dimension preferredWidgetSize; public AbstractWidgetContainer(String identifier, String labelText, FormFrame frame) { super(frame); setupWidgetContainer(identifier, labelText, frame); } private void setupWidgetContainer(String identifier, String labelText, FormFrame frame) { preferredLabelWidth = frame.getPreferredLabelWidth(); preferredWidgetSize = frame.getPreferredWidgetSize(); this.identifier = identifier; makeLabel(labelText); } public void setWidget(JComponent widget) { this.widget = widget; } public JComponent getWidget() { return widget; } /** * Creates a label that can span multiple lines by using html with a fixed * width. Escapes the string for html characters. * * @param labelText the Question or Computation for which to create a label. */ private void makeLabel(String labelText) { String text = String.format("<html><div style=\"width:%dpx;\">%s</div></html>", preferredLabelWidth, escapeHtml4(labelText)); questionLabel = new JLabel(text); } /** * Applies a BoxLayout on itself adding the label and widget to it. */ public void initUI() { setAlignmentX(LEFT_ALIGNMENT); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); add(questionLabel); add(Box.createHorizontalGlue()); add(widget); Border rowBorder = BorderFactory.createCompoundBorder( new MatteBorder(0, 0, 1, 0, Color.black), new EmptyBorder(3, 3, 3, 3) ); setBorder(rowBorder); } /** * Initialize value in FormFrame. */ @Override public void initValue() { getFormFrame().storeValue(identifier, getValue()); } /** * Handles toggling of active state. * * @param active whether the AbstractWidgetContainer should be active or not. */ @Override protected void setActive(boolean active) { super.setActive(active); if (active) { // The AbstractWidgetContainer was inactive, set default values on (re)activation. ((IWidget) widget).setDefaultValue(this); reEvaluate(); } else { // Value is considered undefined if element is inactive, propagate // this change. UndefinedVal undefined = new UndefinedVal(); setValue(undefined); getFormFrame().registerValueChange(this, undefined); } } protected Dimension getPreferredWidgetSize() { return preferredWidgetSize; } public String getIdentifier() { return identifier; } }