0001: package com.xoetrope.carousel.survey;
0002:
0003: import com.xoetrope.survey.Condition;
0004: import com.xoetrope.survey.Option;
0005: import com.xoetrope.survey.Question;
0006: import java.awt.Color;
0007: import java.awt.Dimension;
0008: import java.awt.Graphics;
0009: import java.awt.Graphics2D;
0010: import java.awt.Polygon;
0011: import java.awt.RenderingHints;
0012: import java.awt.Shape;
0013: import java.awt.event.ActionEvent;
0014: import java.awt.event.ActionListener;
0015: import java.awt.event.FocusEvent;
0016: import java.awt.event.FocusListener;
0017: import java.awt.event.MouseAdapter;
0018: import java.awt.event.MouseEvent;
0019: import java.awt.event.MouseListener;
0020: import java.awt.geom.Rectangle2D;
0021: import java.awt.geom.RoundRectangle2D;
0022: import java.util.Enumeration;
0023: import java.util.Vector;
0024: import javax.swing.ButtonGroup;
0025: import javax.swing.Icon;
0026: import javax.swing.JCheckBox;
0027: import javax.swing.JComponent;
0028: import java.awt.Font;
0029: import javax.swing.JLayeredPane;
0030: import javax.swing.JRadioButton;
0031: import javax.swing.JTextField;
0032: import javax.swing.SwingConstants;
0033:
0034: /**
0035: * A component visualizing condition answers.
0036: *
0037: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
0038: * the GNU Public License (GPL), please see license.txt for more details. If
0039: * you make commercial use of this software you must purchase a commercial
0040: * license from Xoetrope.</p>
0041: * <p> $Revision: 1.5 $</p>
0042: */
0043: public class XAnswersView extends JComponent implements MouseListener {
0044: public static int WIDTH = 160;
0045: public static int HEIGHT = 180;
0046: public static int TOP_GAP = 20;
0047: public static int BOTTOM_GAP = 20;
0048: public static int LEFT_GAP = 5;
0049: public static int RIGHT_GAP = 5;
0050: public static int ARC = 30;
0051: public static Color BACKGROUND_COLOR = new Color(226, 193, 156);
0052: public static Color BORDER_COLOR = Color.BLACK;
0053: public static Color COMPONENT_COLOR = new Color(245, 235, 222);
0054: public static String FONT_NAME = "Dialog";
0055: public static int FONT_SIZE = 12;
0056: public static int FONT_STYLE = 0;
0057: public static double ARROW_BUTTON_Y = 0.2;
0058: public static Color ARROW_BUTTON_BACKGROUND = new Color(165, 109,
0059: 48);
0060: public static Color ARROW_BUTTON_BORDER = Color.BLACK;
0061: public static int ARROW_BUTTON_WIDTH = 20;
0062: public static int ARROW_BUTTON_HEIGHT = 10;
0063: public static int ARROW_BUTTON_GAP = 3;
0064: public static int OPTION_HEIGHT = 18;
0065: public static int OPTION_GAP = 5;
0066:
0067: protected int width, height;
0068: protected int topGap, bottomGap;
0069: protected int leftGap, rightGap;
0070: protected int arc;
0071: protected int answerGap;
0072: protected int fontSize;
0073: protected Shape shape;
0074: protected XRulesEditorPane editorPane;
0075: protected XArrowButton arrowButtonUp, arrowButtonDown;
0076: protected int arrowButtonGap;
0077: protected XConditionView conditionView;
0078: protected Condition condition;
0079: protected Vector components;
0080: protected int startComp;
0081: protected int optionHeight, optionGap;
0082:
0083: /**
0084: * Gets the current scale.
0085: * @return the value of the current scale.
0086: */
0087: protected static double getScale() {
0088: return XRulesEditorPane.SCALE;
0089: }
0090:
0091: /**
0092: * Creates a new instnce of XAnswersView
0093: * @param ep the layer pane containing this view.
0094: */
0095: public XAnswersView(XRulesEditorPane ep) {
0096: super ();
0097: editorPane = ep;
0098: initVariables();
0099: createArrowButtons();
0100: setSizeAndShape();
0101: setVisible(false);
0102: editorPane.add(this , JLayeredPane.PALETTE_LAYER);
0103: }
0104:
0105: /*
0106: * Moves this component to the front of the owner pane.
0107: */
0108: public void moveToFront() {
0109: editorPane.moveToFront(this );
0110: editorPane.moveToFront(arrowButtonUp);
0111: editorPane.moveToFront(arrowButtonDown);
0112: Enumeration enumComponents = components.elements();
0113: while (enumComponents.hasMoreElements()) {
0114: JComponent component = (JComponent) enumComponents
0115: .nextElement();
0116: editorPane.moveToFront(component);
0117: }
0118: }
0119:
0120: /**
0121: * Creates the arrow buttons being used
0122: * to scroll the answers contained in this component.
0123: */
0124: protected void createArrowButtons() {
0125: double ys = ARROW_BUTTON_Y;
0126: Color bg = ARROW_BUTTON_BACKGROUND;
0127: Color br = ARROW_BUTTON_BORDER;
0128:
0129: int w = ARROW_BUTTON_WIDTH;
0130: int h = ARROW_BUTTON_HEIGHT;
0131: arrowButtonUp = new XArrowButton(w, h, ys, bg, br,
0132: XArrowButton.UP);
0133: arrowButtonDown = new XArrowButton(w, h, ys, bg, br,
0134: XArrowButton.DOWN);
0135: editorPane.add(arrowButtonUp, JLayeredPane.PALETTE_LAYER);
0136: editorPane.add(arrowButtonDown, JLayeredPane.PALETTE_LAYER);
0137:
0138: arrowButtonUp.addMouseListener(new MouseAdapter() {
0139: public void mousePressed(MouseEvent e) {
0140: scroll(-1);
0141: }
0142: });
0143: arrowButtonDown.addMouseListener(new MouseAdapter() {
0144: public void mousePressed(MouseEvent e) {
0145: scroll(1);
0146: }
0147: });
0148: }
0149:
0150: /**
0151: * Sets the size and shape of this component.
0152: */
0153: public void setSizeAndShape() {
0154: int w = getWidth(), h = getHeight();
0155: Dimension size = new Dimension(w, h);
0156: setSize(size);
0157: setPreferredSize(size);
0158: setMinimumSize(size);
0159: int arc = getArc();
0160: w--;
0161: h--;
0162: shape = new RoundRectangle2D.Double(0, 0, w, h, arc, arc);
0163: refreshArrowButtons();
0164: }
0165:
0166: /**
0167: * Repains the arrow buttons.
0168: */
0169: protected void refreshArrowButtons() {
0170: int aw, ah, x, y;
0171: int w = getWidth();
0172:
0173: arrowButtonUp.setSize();
0174: aw = arrowButtonUp.getWidth();
0175: ah = arrowButtonUp.getHeight();
0176: x = getLocation().x + (w - aw) / 2;
0177: y = getLocation().y + getTopGap();
0178: y -= getArrowButtonGap() + ah;
0179: arrowButtonUp.setLocation(x, y);
0180:
0181: arrowButtonDown.setSize();
0182: aw = arrowButtonDown.getWidth();
0183: ah = arrowButtonDown.getHeight();
0184: x = getLocation().x + (w - aw) / 2;
0185: y = getLocation().y + getHeight();
0186: y -= getBottomGap() - getArrowButtonGap();
0187: arrowButtonDown.setLocation(x, y);
0188: }
0189:
0190: /**
0191: * Shows or hides this component.
0192: * @param state if true shows this component,
0193: * if false hides it.
0194: */
0195: public void setVisible(boolean state) {
0196: super .setVisible(state);
0197: arrowButtonUp.setVisible(state);
0198: arrowButtonDown.setVisible(state);
0199:
0200: Enumeration enumComponents = components.elements();
0201: if (!state)
0202: while (enumComponents.hasMoreElements()) {
0203: JComponent component = (JComponent) enumComponents
0204: .nextElement();
0205: component.setVisible(state);
0206: }
0207: else
0208: refreshComponents();
0209: if (state)
0210: moveToFront();
0211: else
0212: saveToModel();
0213: }
0214:
0215: /**
0216: * Paints the condition views contained in this component.
0217: * @param g the graphics context to use for painting.
0218: */
0219: protected void paintCondition(Graphics2D g) {
0220: g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
0221: RenderingHints.VALUE_ANTIALIAS_ON);
0222: g.setColor(BACKGROUND_COLOR);
0223: g.fill(shape);
0224: g.setColor(BORDER_COLOR);
0225: g.draw(shape);
0226: }
0227:
0228: /**
0229: * Paints this component.
0230: * @param g the graphics context to use for painting.
0231: */
0232: public void paint(Graphics g) {
0233: Graphics2D g2d = (Graphics2D) g;
0234: paintCondition(g2d);
0235: }
0236:
0237: /**
0238: * Initializes the internal variables
0239: * defining this component.
0240: */
0241: protected void initVariables() {
0242: conditionView = null;
0243: startComp = 0;
0244: components = new Vector();
0245: setWidth(WIDTH);
0246: setHeight(HEIGHT);
0247: setTopGap(TOP_GAP);
0248: setBottomGap(BOTTOM_GAP);
0249: setLeftGap(LEFT_GAP);
0250: setRightGap(RIGHT_GAP);
0251: setArc(ARC);
0252: setFontSize(FONT_SIZE);
0253: setArrowButtonGap(ARROW_BUTTON_GAP);
0254: setOptionGap(OPTION_GAP);
0255: setComponentHeight(OPTION_HEIGHT);
0256: }
0257:
0258: /**
0259: * Gets the view of the current condition
0260: * @return the condtion view.
0261: */
0262: public XConditionView getConditionView() {
0263: return conditionView;
0264: }
0265:
0266: /**
0267: * Sets the new condition view.
0268: * @param cv the new conditon view.
0269: */
0270: public void setConditionView(XConditionView cv) {
0271: removeAllComponents();
0272: conditionView = cv;
0273: condition = (conditionView != null ? conditionView
0274: .getCondition() : null);
0275: if (condition != null) {
0276: switch (condition.getQuestion().getQuestionType()) {
0277: case Question.MUTUALLY_EXCLUSIVE:
0278: createOptionsViewsExclusive();
0279: refreshComponents();
0280: updateFromModelExclusive();
0281: break;
0282: case Question.MULTIPLE_CHOICE:
0283: createOptionsViewsMulti();
0284: refreshComponents();
0285: updateFromModelMulti();
0286: break;
0287: case Question.FREE_TEXT:
0288: createOptionsViewsFree();
0289: refreshComponents();
0290: updateFromModelFree();
0291: break;
0292: }
0293: }
0294: }
0295:
0296: /*
0297: * Recounts the position of this component
0298: * and repaints it.
0299: */
0300: protected void refreshComponents() {
0301: int optionHeight = getOptionHeight();
0302: int optionGap = getOptionGap();
0303: int numComps = getNumVisComponents();
0304: int y = getLocation().y + getTopGap();
0305: y -= startComp * (optionGap + optionHeight);
0306: int x = getLocation().x + getLeftGap();
0307:
0308: int m = 1;
0309: if (conditionView != null
0310: && conditionView.getCondition().getQuestion()
0311: .getQuestionType() == Question.FREE_TEXT)
0312: m = 2;
0313: int numComponents = getNumComponents();
0314: for (int i = 0; i < numComponents; i++) {
0315: JComponent component = (JComponent) components.get(m * i);
0316: boolean visible = (i >= startComp && i < startComp
0317: + numComps);
0318: component.setVisible(visible);
0319: component.setLocation(x, y);
0320: if (visible)
0321: component.repaint();
0322: if (conditionView != null
0323: && conditionView.getCondition().getQuestion()
0324: .getQuestionType() == Question.FREE_TEXT) {
0325: component = (JComponent) components.get(2 * i + 1);
0326: component.setVisible(visible);
0327: if (visible)
0328: component.repaint();
0329: component.setLocation(x, y + getComponentHeight());
0330: }
0331: y += optionHeight + optionGap;
0332: }
0333: refreshArrowButtonsState();
0334: }
0335:
0336: /**
0337: * Indicates whether it is possible to scroll up
0338: * the answer views contained in this component.
0339: * @return true if the answer views can be scrolled up,
0340: * false otherwise.
0341: */
0342: protected boolean hasComponentsUp() {
0343: return (startComp > 0);
0344: }
0345:
0346: /**
0347: * Indicates whether it is possible to scroll down
0348: * the answer views contained in this component.
0349: * @return ture if the answer views can be scrolled down,
0350: * false otherwise.
0351: */
0352: protected boolean hasComponentsDown() {
0353: return (startComp + getNumVisComponents() < getNumComponents());
0354: }
0355:
0356: /**
0357: * Gets the number of single answer views contained
0358: * in this component.
0359: * @return the number of answer views.
0360: */
0361: public int getNumComponents() {
0362: int n = 0;
0363: if (conditionView != null) {
0364: if (conditionView.getCondition().getQuestion()
0365: .getQuestionType() == Question.FREE_TEXT)
0366: n = components.size() / 2;
0367: else
0368: n = components.size();
0369: }
0370: return n;
0371: }
0372:
0373: /**
0374: * Refreshes the "visible" flag of the arrow buttons.
0375: */
0376: protected void refreshArrowButtonsState() {
0377: arrowButtonUp.setEnabled(hasComponentsUp());
0378: arrowButtonDown.setEnabled(hasComponentsDown());
0379: arrowButtonUp.repaint();
0380: arrowButtonDown.repaint();
0381: }
0382:
0383: /**
0384: * Scrolls the content of this component
0385: * by the specified number of units.
0386: * @param units the number of units
0387: */
0388: protected void scroll(int units) {
0389: startComp += units;
0390: if (startComp < 0)
0391: startComp = 0;
0392: if (startComp > getNumComponents() - getNumVisComponents())
0393: startComp = getNumComponents() - getNumVisComponents();
0394: refreshComponents();
0395: }
0396:
0397: /**
0398: * Updates this component with the model when
0399: * the question type is "exclusive".
0400: */
0401: protected void updateFromModelExclusive() {
0402: for (int i = 0; i < condition.getOptions().size(); i++) {
0403: Option option = (Option) condition.getOptions().get(i);
0404: int optionIdx = -1;
0405: Question question = condition.getQuestion();
0406: for (int j = 0; j < question.getOptions().size()
0407: && optionIdx == -1; j++) {
0408: Option o = (Option) question.getOptions().get(j);
0409: if (option.equals(o))
0410: optionIdx = j;
0411: }
0412: if (optionIdx >= 0) {
0413: JRadioButton radioButton = (JRadioButton) components
0414: .get(optionIdx);
0415: radioButton.setSelected(true);
0416: break;
0417: }
0418: }
0419: }
0420:
0421: /**
0422: * Creates the answer views when the question type
0423: * is "multi".
0424: */
0425: protected void createOptionsViewsMulti() {
0426: if (condition == null)
0427: return;
0428:
0429: int w = getWidth() - getLeftGap() - getRightGap();
0430: int h = getComponentHeight();
0431: Font font = getFont();
0432: Dimension optionSize = new Dimension(w, h);
0433: Enumeration enumOptions = condition.getQuestion().getOptions()
0434: .elements();
0435: int x = getLocation().x + getLeftGap();
0436: int y = getLocation().y + getTopGap();
0437: while (enumOptions.hasMoreElements()) {
0438: Option option = (Option) enumOptions.nextElement();
0439: JCheckBox checkBox = new JCheckBox(option.getText());
0440: checkBox.setBackground(COMPONENT_COLOR);
0441: checkBox.setFont(font);
0442: checkBox.setSize(optionSize);
0443: checkBox.setPreferredSize(optionSize);
0444: checkBox.setHorizontalAlignment(SwingConstants.LEADING);
0445: components.add(checkBox);
0446: editorPane.add(checkBox, JLayeredPane.PALETTE_LAYER);
0447: checkBox.setLocation(x, y);
0448: editorPane.moveToFront(checkBox);
0449: y += getComponentHeight() + getOptionGap();
0450: checkBox.addActionListener(multiSaver);
0451: }
0452: }
0453:
0454: /**
0455: * For receiving enabling/disabling the text components associated
0456: * with the checkboxes according to its state.
0457: */
0458: private class CheckBoxListener implements ActionListener {
0459: JTextField textField;
0460:
0461: /**
0462: * Creates a new instance of CheckBoxListener
0463: * @param t the text component associated with the
0464: * checkbox
0465: */
0466: public CheckBoxListener(JTextField tf) {
0467: textField = tf;
0468: }
0469:
0470: /**
0471: * Enabled or disables the text component
0472: * according to the checkbox state
0473: * @param e the ActionEvent object.
0474: */
0475: public void actionPerformed(ActionEvent e) {
0476: JCheckBox cb = (JCheckBox) (e.getSource());
0477: textField.setEnabled(cb.isSelected());
0478: if (cb.isSelected())
0479: saveToModelFreeText();
0480: }
0481: }
0482:
0483: /**
0484: * Create the answer views when the question type
0485: * is "free text"
0486: */
0487: protected void createOptionsViewsFree() {
0488: if (condition == null)
0489: return;
0490:
0491: int w = getWidth() - getLeftGap() - getRightGap();
0492: int h = getComponentHeight();
0493: Font font = getFont();
0494: Dimension optionSize = new Dimension(w, h);
0495: Enumeration enumOptions = condition.getQuestion().getOptions()
0496: .elements();
0497: int x = getLocation().x + getLeftGap();
0498: int y = getLocation().y + getTopGap();
0499: while (enumOptions.hasMoreElements()) {
0500: Option option = (Option) enumOptions.nextElement();
0501: JCheckBox checkBox = new JCheckBox(option.getText());
0502: checkBox.setSelected(false);
0503: checkBox.setBackground(COMPONENT_COLOR);
0504: checkBox.setFont(font);
0505: checkBox.setSize(optionSize);
0506: checkBox.setHorizontalAlignment(SwingConstants.LEADING);
0507: components.add(checkBox);
0508: editorPane.add(checkBox, JLayeredPane.PALETTE_LAYER);
0509: checkBox.setLocation(x, y);
0510: y += getComponentHeight();
0511: JTextField textField = new JTextField();
0512: textField.setEnabled(false);
0513: textField.setFont(font);
0514: textField.setSize(optionSize);
0515: components.add(textField);
0516: editorPane.add(textField, JLayeredPane.PALETTE_LAYER);
0517: textField.setLocation(x, y);
0518: y += getOptionGap() + getComponentHeight();
0519: editorPane.moveToFront(checkBox);
0520: editorPane.moveToFront(textField);
0521: checkBox.addActionListener(new CheckBoxListener(textField));
0522: textField.addFocusListener(freeTextSaver);
0523: }
0524: }
0525:
0526: /**
0527: * Creates the answer views when the question type is
0528: * "mutually exclusive"
0529: */
0530: protected void createOptionsViewsExclusive() {
0531: if (condition == null)
0532: return;
0533:
0534: ButtonGroup group = new ButtonGroup();
0535: int w = getWidth() - getLeftGap() - getRightGap();
0536: int h = getComponentHeight();
0537: Font font = getFont();
0538: Dimension optionSize = new Dimension(w, h);
0539: Enumeration enumOptions = condition.getQuestion().getOptions()
0540: .elements();
0541: int x = getLocation().x + getLeftGap();
0542: int y = getLocation().y + getTopGap();
0543: while (enumOptions.hasMoreElements()) {
0544: Option option = (Option) enumOptions.nextElement();
0545: JRadioButton radioButton = new JRadioButton(option
0546: .getText());
0547: radioButton.setBackground(COMPONENT_COLOR);
0548: radioButton.setFont(font);
0549: radioButton.setSize(optionSize);
0550: radioButton.setPreferredSize(optionSize);
0551: radioButton.setHorizontalAlignment(SwingConstants.LEADING);
0552: group.add(radioButton);
0553: components.add(radioButton);
0554: editorPane.add(radioButton, JLayeredPane.DRAG_LAYER);
0555: radioButton.setLocation(x, y);
0556: editorPane.moveToFront(radioButton);
0557: y += getComponentHeight() + getOptionGap();
0558: radioButton.addActionListener(exclusiveSaver);
0559: }
0560: }
0561:
0562: /**
0563: * Updates this component with the model
0564: * when the question type "mutli"
0565: */
0566: protected void updateFromModelMulti() {
0567: for (int i = 0; i < condition.getOptions().size(); i++) {
0568: Option option = (Option) condition.getOptions().get(i);
0569: int optionIdx = -1;
0570: Question question = condition.getQuestion();
0571: for (int j = 0; j < question.getOptions().size()
0572: && optionIdx == -1; j++) {
0573: Option o = (Option) question.getOptions().get(j);
0574: if (option.equals(o))
0575: optionIdx = j;
0576: }
0577: if (optionIdx >= 0) {
0578: JCheckBox checkBox = (JCheckBox) components
0579: .get(optionIdx);
0580: checkBox.setSelected(true);
0581: }
0582: }
0583: }
0584:
0585: /**
0586: * Updates this component with the model when the question
0587: * types is "free text".
0588: */
0589: protected void updateFromModelFree() {
0590: for (int i = 0; i < condition.getOptions().size(); i++) {
0591: Option option = (Option) condition.getOptions().get(i);
0592: String answer = (String) condition.getAnswers().get(i);
0593: int optionIdx = -1;
0594: Question question = condition.getQuestion();
0595: for (int j = 0; j < question.getOptions().size()
0596: && optionIdx == -1; j++) {
0597: Option o = (Option) question.getOptions().get(j);
0598: if (option.equals(o))
0599: optionIdx = j;
0600: }
0601: if (optionIdx >= 0) {
0602: JCheckBox checkBox = (JCheckBox) components
0603: .get(2 * optionIdx);
0604: JTextField textField = (JTextField) components
0605: .get(2 * optionIdx + 1);
0606: checkBox.setSelected(true);
0607: textField.setEnabled(true);
0608: textField.setText(answer);
0609: }
0610: }
0611: }
0612:
0613: /**
0614: * Used to save the text typed in the text components.
0615: */
0616: private FocusListener freeTextSaver = new FocusListener() {
0617: /**
0618: * Saves the text when the components losts its focus.
0619: * @param e the FocusEvent object.
0620: */
0621: public void focusLost(FocusEvent e) {
0622: saveToModelFreeText();
0623: }
0624:
0625: public void focusGained(FocusEvent e) {
0626: }
0627: };
0628:
0629: /**
0630: * Used to saved the state of checkboxes.
0631: */
0632: private ActionListener multiSaver = new ActionListener() {
0633: public void actionPerformed(ActionEvent e) {
0634: if (!(e.getSource() instanceof JCheckBox))
0635: return;
0636: JCheckBox checkBox = (JCheckBox) e.getSource();
0637: if (checkBox.isSelected())
0638: saveToModelMulti();
0639: }
0640: };
0641:
0642: /**
0643: * Used to save the state of radiobuttons.
0644: */
0645: private ActionListener exclusiveSaver = new ActionListener() {
0646: public void actionPerformed(ActionEvent e) {
0647: if (!(e.getSource() instanceof JRadioButton))
0648: return;
0649: JRadioButton radioButton = (JRadioButton) e.getSource();
0650: if (radioButton.isSelected())
0651: saveToModelExclusive();
0652: }
0653: };
0654:
0655: /**
0656: * Removes all answer views contained in this component.
0657: */
0658: protected void removeAllComponents() {
0659: Enumeration enumComponents = components.elements();
0660: while (enumComponents.hasMoreElements()) {
0661: JComponent component = (JComponent) enumComponents
0662: .nextElement();
0663: editorPane.remove(component);
0664: }
0665: components.removeAllElements();
0666: startComp = 0;
0667: }
0668:
0669: /**
0670: * Saves the answers given by the user
0671: * when the question type is "free text"
0672: */
0673: protected void saveToModelFreeText() {
0674: if (condition == null)
0675: return;
0676:
0677: condition.getOptions().removeAllElements();
0678: condition.getAnswers().removeAllElements();
0679:
0680: for (int i = 0; i < components.size() / 2; i++) {
0681: JCheckBox checkBox = (JCheckBox) components.get(2 * i);
0682: if (!checkBox.isSelected())
0683: continue;
0684: JTextField textField = (JTextField) components
0685: .get(2 * i + 1);
0686: Option option = (Option) condition.getQuestion()
0687: .getOptions().get(i);
0688: String answer = textField.getText();
0689: condition.addAnswer(option, answer);
0690: }
0691: }
0692:
0693: /**
0694: * Saves the answers given by the user when the question
0695: * type is "multi".
0696: */
0697: protected void saveToModelMulti() {
0698: if (condition == null)
0699: return;
0700:
0701: condition.getOptions().removeAllElements();
0702: condition.getAnswers().removeAllElements();
0703:
0704: for (int i = 0; i < components.size(); i++) {
0705: JCheckBox checkBox = (JCheckBox) components.get(i);
0706: if (!checkBox.isSelected())
0707: continue;
0708: Option option = (Option) condition.getQuestion()
0709: .getOptions().get(i);
0710: String answer = option.getText();
0711: condition.addAnswer(option, answer);
0712: }
0713: }
0714:
0715: /**
0716: * Saves the answers given by the user when the question
0717: * type is "mutually exclusive".
0718: */
0719: protected void saveToModelExclusive() {
0720: if (condition == null)
0721: return;
0722:
0723: condition.getOptions().removeAllElements();
0724: condition.getOptions().removeAllElements();
0725:
0726: for (int i = 0; i < components.size(); i++) {
0727: JRadioButton radioButton = (JRadioButton) components.get(i);
0728: if (!radioButton.isSelected())
0729: continue;
0730: Option option = (Option) condition.getQuestion()
0731: .getOptions().get(i);
0732: String answer = option.getText();
0733: condition.addAnswer(option, answer);
0734: break;
0735: }
0736: }
0737:
0738: /**
0739: * Saves the answers given by the user.
0740: */
0741: protected void saveToModel() {
0742: if (condition == null)
0743: return;
0744:
0745: switch (condition.getQuestion().getQuestionType()) {
0746: case Question.FREE_TEXT:
0747: saveToModelFreeText();
0748: break;
0749: case Question.MUTUALLY_EXCLUSIVE:
0750: saveToModelExclusive();
0751: break;
0752: case Question.MULTIPLE_CHOICE:
0753: saveToModelMulti();
0754: break;
0755: }
0756: }
0757:
0758: public void mouseClicked(MouseEvent e) {
0759: }
0760:
0761: public void mousePressed(MouseEvent e) {
0762: }
0763:
0764: public void mouseReleased(MouseEvent e) {
0765: }
0766:
0767: public void mouseEntered(MouseEvent e) {
0768: }
0769:
0770: public void mouseExited(MouseEvent e) {
0771: }
0772:
0773: /**
0774: * Gets the width of this component.
0775: * @return the width
0776: */
0777: public int getWidth() {
0778: return (int) (getScale() * width);
0779: }
0780:
0781: /**
0782: * Sets the width of this components.
0783: * @param w the new width.
0784: */
0785: public void setWidth(int w) {
0786: width = (int) ((double) w / getScale());
0787: }
0788:
0789: /**
0790: * Gets the height of this component.
0791: * @return the height
0792: */
0793: public int getHeight() {
0794: return (int) (getScale() * height);
0795: }
0796:
0797: /**
0798: * Sets the height of this component
0799: * @param h the new height.
0800: */
0801: public void setHeight(int h) {
0802: height = (int) ((double) h / getScale());
0803: }
0804:
0805: /**
0806: * Gets the height of the gap on the top
0807: * of this component.
0808: * @return the height of the gap.
0809: */
0810: public int getTopGap() {
0811: return (int) (getScale() * topGap);
0812: }
0813:
0814: /**
0815: * Sets the height of the gap on the top
0816: * of this component.
0817: * @param tg
0818: */
0819: public void setTopGap(int tg) {
0820: topGap = (int) ((double) tg / getScale());
0821: }
0822:
0823: /**
0824: * Gets the height of the gap on
0825: * the bottom of this component.
0826: * @return the height of the gap.
0827: */
0828: public int getBottomGap() {
0829: return (int) (getScale() * bottomGap);
0830: }
0831:
0832: /**
0833: * Sets the height of the gap on
0834: * the bottom of this component.
0835: * @param bg the new height of the gap
0836: */
0837: public void setBottomGap(int bg) {
0838: bottomGap = (int) ((double) bg / getScale());
0839: }
0840:
0841: /**
0842: * Gets the width of the gap on
0843: * the left side of this component
0844: * @return the width of the gap
0845: */
0846: public int getLeftGap() {
0847: return (int) (getScale() * leftGap);
0848: }
0849:
0850: /**
0851: * Sets the width of the gap on
0852: * the left side of this component
0853: * @param lg the new width of the gap.
0854: */
0855: public void setLeftGap(int lg) {
0856: leftGap = (int) ((double) lg / getScale());
0857: }
0858:
0859: /**
0860: * Gets the width of the gap on
0861: * the right side of this component
0862: * @return the width of the gap
0863: */
0864: public int getRightGap() {
0865: return (int) (getScale() * rightGap);
0866: }
0867:
0868: /**
0869: * Sets the width of the gap on
0870: * the left side of this component
0871: * @param rg the new width of the gap
0872: */
0873: public void setRightGap(int rg) {
0874: rightGap = (int) ((double) rg / getScale());
0875: }
0876:
0877: /**
0878: * Gets the value of the corner arc
0879: * @the value of the arc
0880: */
0881: public int getArc() {
0882: return (int) (getScale() * arc);
0883: }
0884:
0885: /**
0886: * Sets the value of the corner arc.
0887: * @param a the new value of the arc.
0888: */
0889: public void setArc(int a) {
0890: arc = (int) ((double) a / getScale());
0891: }
0892:
0893: /**
0894: * Gets the size of the font used to
0895: * render the answers.
0896: * @return the font size.
0897: */
0898: public int getFontSize() {
0899: return (int) (getScale() * fontSize);
0900: }
0901:
0902: /**
0903: * Sets the size of the font used to
0904: * render the answers.
0905: * @param fs the new font size
0906: */
0907: public void setFontSize(int fs) {
0908: fontSize = (int) ((double) fs / getScale());
0909: }
0910:
0911: /**
0912: * Gets the font used to render
0913: * the answers.
0914: * @return the Font object.
0915: */
0916: public Font getFont() {
0917: return (new Font(FONT_NAME, FONT_STYLE, getFontSize()));
0918: }
0919:
0920: /**
0921: * Getst the height of the gap between the
0922: * arrow button and this component's top/bottom edge.
0923: * @return the gap value
0924: */
0925: public int getArrowButtonGap() {
0926: return (int) (getScale() * arrowButtonGap);
0927: }
0928:
0929: /**
0930: * Sets the height of the gap between the
0931: * arrow button and this component's top/bottom edge.
0932: * @param ag the new height of the gap.
0933: */
0934: public void setArrowButtonGap(int ag) {
0935: arrowButtonGap = (int) ((double) ag / getScale());
0936: }
0937:
0938: /**
0939: * Sets the height of a single answer view.
0940: * @param op the new height
0941: */
0942: public void setComponentHeight(int op) {
0943: optionHeight = (int) ((double) op / getScale());
0944: }
0945:
0946: /**
0947: * Gets the height of a single answer view.
0948: * @return the height of an answer.
0949: */
0950: public int getComponentHeight() {
0951: return (int) (getScale() * optionHeight);
0952: }
0953:
0954: /**
0955: * Gets the height of the gap between answer views.
0956: * @return the height of the gap.
0957: */
0958: public int getOptionGap() {
0959: return (int) (getScale() * optionGap);
0960: }
0961:
0962: /**
0963: * Sets the height of the gap between answer views.
0964: * @param og the height of the gap.
0965: */
0966: public void setOptionGap(int og) {
0967: optionGap = (int) ((double) og / getScale());
0968: }
0969:
0970: /**
0971: * Gets the height of the content of this component
0972: * @return the heigh of the content.
0973: */
0974: public int getContentHeight() {
0975: return (getHeight() - getTopGap() - getBottomGap());
0976: }
0977:
0978: /**
0979: * Gets the height of an answer view.
0980: * @return the height of an answer view.
0981: */
0982: public int getOptionHeight() {
0983: int oh = 0;
0984: if (conditionView != null) {
0985: if (conditionView.getCondition().getQuestion()
0986: .getQuestionType() == Question.FREE_TEXT)
0987: oh = 2 * getComponentHeight();
0988: else
0989: oh = getComponentHeight();
0990: }
0991: return oh;
0992: }
0993:
0994: /**
0995: * Gets the number of answer views that are visible.
0996: * @return the number of answer views.
0997: */
0998: public int getNumVisComponents() {
0999: int oh = 0;
1000: return (int) ((double) getContentHeight() / (getOptionHeight() + getOptionGap()));
1001: }
1002:
1003: }
|