Newer
Older
marking / src / ui / CriterionPanel.java
package ui;

import java.awt.Dimension;
import java.awt.Font;
import model.CriterionEditor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import model.Criterion;

/**
 *
 * @author mark
 */
public class CriterionPanel extends JPanel implements CriterionEditor {

	private final RadioGroup radioGroup;
	private final JTextArea txtComment;
	private final Criterion criterion;
	private final JButton clearBtn;

	private static Dimension selectedSize;

	public CriterionPanel(Criterion criterion) {
		this.criterion = criterion;

		this.setLayout(new GridBagLayout());

		// label is left aligned and full width
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.gridwidth = 3;
		gbc.weightx = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0, 0, 5, 0);

		this.add(new JLabel(criterion.getDescription()), gbc);

		// clear mark buttonleft aligned, but doesn't grow
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 1;
		clearBtn = new JButton("X");

		this.add(clearBtn, gbc);

		// radio group is left aligned, but doesn't grow
		gbc = new GridBagConstraints();
		gbc.gridx = 1;
		gbc.gridy = 1;
		radioGroup = new RadioGroup(criterion.getMin(), criterion.getMax());

		this.add(radioGroup, gbc);

		// text area is right aligned, but grows in both directions
		gbc = new GridBagConstraints();
		gbc.gridx = 2;
		gbc.gridy = 1;
		gbc.weightx = 1;
		gbc.weighty = 1;
		gbc.fill = GridBagConstraints.BOTH;

		txtComment = new JTextArea();
		txtComment.setWrapStyleWord(true);
		txtComment.setLineWrap(true);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setViewportView(txtComment);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

		// Dimensions are necessary to prevent the semi-famous "text area grows infinitely" bug.
		// Unfortunately this also means we can't let the layout manager figure out the correct
		// size dynamically...
		txtComment.setMinimumSize(new Dimension(10, 20));
		txtComment.setPreferredSize(new Dimension(10, 100));  // need to hardcode height which is annoying...
		scrollPane.setPreferredSize(new Dimension(10, 20));

		txtComment.addFocusListener(new FocusAdapter() {

			@Override
			public void focusGained(FocusEvent fe) {
				super.focusGained(fe);
				CriterionPanel selectedPanel = CriterionPanel.this;
				MarkingFrame frame = (MarkingFrame) SwingUtilities.getWindowAncestor(selectedPanel);
				if (frame.getExpandable()) {
					selectedPanel.setPreferredSize(new Dimension(10, 150));
					selectedPanel.invalidate();
					SwingUtilities.getWindowAncestor(selectedPanel).pack();
				}
			}

			@Override
			public void focusLost(FocusEvent fe) {
				super.focusLost(fe);
				CriterionPanel selectedPanel = CriterionPanel.this;
				selectedPanel.setPreferredSize(selectedSize);
				selectedPanel.invalidate();
				SwingUtilities.getWindowAncestor(selectedPanel).pack();
			}

		});

		clearBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ae) {
				radioGroup.clearSelection();
			}
		});

		Font font = txtComment.getFont();
		Font biggerFont = font.deriveFont(14f);
		txtComment.setFont(biggerFont);

		this.add(scrollPane, gbc);
	}

	@Override
	public String getComment() {
		return txtComment.getText().trim();
	}

	@Override
	public Double getResult() {
		Integer result = radioGroup.getSelected();
		return result != null ? new Double(result) : null;
	}

	@Override
	public boolean isComplete() {
		return getResult() != null;
	}

	@Override
	public void setComment(String comment) {
		txtComment.setText(comment);
	}

	@Override
	public void setResult(Double result) {
		radioGroup.setSelected(result.intValue());
	}

	public void setZero() {
		setResult(0.0);
	}

	public void setMax() {
		setResult(new Double(criterion.getMax()));
	}

	public Criterion getCriterion() {
		return criterion;
	}

}