package nl.uva.polyql.view; import java.awt.Dimension; import java.security.InvalidParameterException; import java.util.Objects; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import nl.uva.polyql.ast.Question; import nl.uva.polyql.ast.values.BooleanValue; import nl.uva.polyql.ast.values.NumberValue; import nl.uva.polyql.ast.values.StringValue; import nl.uva.polyql.ast.values.Value; public abstract class QuestionView implements Question.ValueListener { private static final int PADDING = 10; private static final Dimension VIEW_SIZE = new Dimension(FormFrame.WIDTH - PADDING * 4, 30); private static final Dimension CONTENT_SIZE = new Dimension(FormFrame.WIDTH / 2 - PADDING * 2, 25); private final JPanel mPanel; private final Question mQuestion; private Value<?> mValue; public QuestionView(final Question question) { mQuestion = question; init(); setValue(mQuestion.getValue(), true); onEditableChanged(mQuestion.isEditable()); mPanel = new JPanel(); mPanel.setLayout(new BoxLayout(mPanel, BoxLayout.X_AXIS)); mPanel.setPreferredSize(VIEW_SIZE); // Add question label final JPanel labelContainer = new JPanel(); labelContainer.setPreferredSize(CONTENT_SIZE); final JLabel label = new JLabel(); label.setPreferredSize(CONTENT_SIZE); label.setText(mQuestion.getLabel()); labelContainer.add(label); mPanel.add(labelContainer); // Add question value final JPanel valueContainer = new JPanel(); valueContainer.setPreferredSize(CONTENT_SIZE); final JComponent valueComponent = getValueComponent(); valueComponent.setPreferredSize(CONTENT_SIZE); valueContainer.add(valueComponent); mPanel.add(valueContainer); } private void setValue(final Value<?> value, final boolean updateSelf) { mValue = value; onValidityChanged(value.isValid()); if (updateSelf && value.isValid()) { value.setViewValue(this); } } protected void onNewInput(final Value<?> value) { if (!Objects.equals(value, mValue)) { setValue(value, false); mQuestion.setValue(value); } } @Override public void onQuestionUpdate(final Question question) { setValue(mQuestion.getValue(), true); } protected abstract void init(); protected void onEditableChanged(final boolean enabled) {} protected void onValidityChanged(final boolean valid) {} public void setComponentValue(final BooleanValue value) { throw new InvalidParameterException("Booleans are invalid values for this view"); } public void setComponentValue(final NumberValue value) { throw new InvalidParameterException("Numbers are invalid values for this view"); } public void setComponentValue(final StringValue value) { throw new InvalidParameterException("Strings are invalid values for this view"); } protected abstract JComponent getValueComponent(); public JComponent getComponent() { return mPanel; } }