001: package com.xoetrope.swing.survey;
002:
003: import com.xoetrope.survey.Question;
004: import com.xoetrope.survey.QuestionGroup;
005: import com.xoetrope.survey.SurveyManager;
006: import com.xoetrope.survey.Survey;
007: import java.awt.Point;
008: import java.util.Enumeration;
009: import java.util.Vector;
010: import javax.swing.SwingUtilities;
011: import net.xoetrope.xui.XPage;
012: import net.xoetrope.xui.XProject;
013: import net.xoetrope.xui.XProjectManager;
014: import net.xoetrope.xui.XTarget;
015: import net.xoetrope.xui.data.XDataBinding;
016: import net.xoetrope.xui.data.XModel;
017:
018: /**
019: * XQuestionPage is a page class that provides support for questionaires by way
020: * of a QuestionManager.
021: *
022: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
023: * the GNU Public License (GPL), please see license.txt for more details. If
024: * you make commercial use of this software you must purchase a commercial
025: * license from Xoetrope.</p>
026: * <p> $Revision: 1.7 $</p>
027: */
028: public class XQuestionPage extends XPage {
029: protected SurveyManager surveyManager;
030: private boolean nextPageClicked;
031: protected int sleepTime = 3;
032:
033: /**
034: * Creates a new instance of XQuestionPage
035: */
036: public XQuestionPage() {
037: surveyManager = (SurveyManager) project
038: .getObject("SurveyManager");
039: if (surveyManager == null) {
040: surveyManager = new SurveyManager(project);
041: project.setObject("SurveyManager", surveyManager);
042: }
043: }
044:
045: /**
046: * Gets the name of the current survey.
047: * @return the current survey.
048: */
049: public String getCurrentSurvey() {
050: Survey currentSurvey = surveyManager.getCurrentSurvey();
051: return (currentSurvey != null ? currentSurvey.getName() : "");
052: }
053:
054: /**
055: * Shows the specified question page.
056: * @param questionPage the name of the question page
057: */
058: protected void reloadQuestionPage(String questionPage) {
059: pageMgr.unloadPage(questionPage);
060: pageMgr.showPage(questionPage, "content");
061: XPage page = (XPage) ((XTarget) pageMgr.getTarget("content"))
062: .getComponent(0);
063: page.updateBindings();
064: }
065:
066: /**
067: * Sets the time after which the survey
068: * will be retarted automatically
069: * @param time the time in seconds
070: */
071: public void setSleepTime(int time) {
072: sleepTime = time;
073: }
074:
075: /**
076: * Gets the time after which
077: * the survey will be restarted automatically, in case
078: * the "RestartSurvey" startup property is set to "true".
079: * @return time in seconds
080: */
081: public int getSleepTime() {
082: return sleepTime;
083: }
084:
085: /**
086: * Shows the previous page
087: */
088: public void prevPage() {
089: Survey currentSurvey = surveyManager.getCurrentSurvey();
090: if ((currentSurvey == null)
091: || (!currentSurvey.hasMoreQuestions()))
092: return;
093:
094: int pageNr = currentSurvey.getPageNrAsInt();
095: if (pageNr == 2)
096: return;
097: XPage target = (XPage) ((XTarget) pageMgr.getTarget("content"))
098: .getComponent(0);
099: String pageName = currentSurvey.setPrevPage();
100: if (pageName != null)
101: reloadQuestionPage(pageName);
102: }
103:
104: /**
105: * Shows the first page of the survey
106: */
107: public void firstPage() {
108: Survey currentSurvey = surveyManager.getCurrentSurvey();
109: if ((currentSurvey == null)
110: || (!currentSurvey.hasMoreQuestions()))
111: return;
112: XPage target = (XPage) ((XTarget) pageMgr.getTarget("content"))
113: .getComponent(0);
114: String pageName = currentSurvey.setFirstPage();
115: if (pageName != null)
116: reloadQuestionPage(pageName);
117: }
118:
119: /**
120: * Shows the next question page, if the current question page
121: * is the last one shows the finish page.
122: */
123: synchronized public void nextPage() {
124: nextPageClicked = true;
125: Survey currentSurvey = surveyManager.getCurrentSurvey();
126: if (currentSurvey == null)
127: currentSurvey = loadSelectedSurvey();
128:
129: if (!currentSurvey.hasMoreQuestions()) {
130: surveyManager.setCurrentSurvey(currentSurvey = null);
131: String startPage = surveyManager.getStartPage();
132: pageMgr.showPage(startPage, "content");
133: return;
134: }
135:
136: // show the next page
137: XPage target = (XPage) ((XTarget) pageMgr.getTarget("content"))
138: .getComponent(0);
139: String questionPage = (String) target.getAttribute(
140: "question_page", null);
141:
142: if (!showNextPage(questionPage)) {
143: saveResponses(currentSurvey.getUserResponses());
144: String finishPage = (String) target.getAttribute(
145: "finish_page", null);
146: if ((finishPage == null) || "".equals(finishPage))
147: finishPage = surveyManager.getFinishPage();
148: if ((finishPage != null) && !"".equals(finishPage)) {
149: showThankYouPage(finishPage);
150: if (surveyManager.restartSurvey())
151: restartSurvey();
152: } else {
153: surveyManager.setCurrentSurvey(currentSurvey = null);
154: String startPage = surveyManager.getStartPage();
155: pageMgr.showPage(startPage, "content");
156: }
157: }
158: }
159:
160: /**
161: * Waits for the "sleepTime" seconds and then
162: * restarts the current survey
163: */
164: private void restartSurvey() {
165: Thread t = (new Thread() {
166: public void run() {
167: try {
168: Thread.currentThread().sleep(sleepTime * 1000);
169: if (!nextPageClicked)
170: SwingUtilities.invokeLater(new Runnable() {
171: public void run() {
172: nextPage();
173: }
174: });
175: } catch (InterruptedException ex) {
176: ex.printStackTrace();
177: }
178:
179: }
180: });
181: nextPageClicked = false;
182: t.start();
183: }
184:
185: /**
186: * Reloads the current survey according
187: * to the selected language.
188: * @return the current survey
189: */
190: private Survey loadSelectedSurvey() {
191: try {
192: XModel langModel = (XModel) project.getModel().get(
193: "currentSurveyLanguage");
194: String langName = (String) langModel.get();
195: surveyManager.loadSurvey(langName);
196: } catch (Exception ex) {
197: ex.printStackTrace();
198: }
199: return surveyManager.getCurrentSurvey();
200: }
201:
202: /**
203: * Shows the next question page if the mouse was clicked
204: */
205: public void nextPageClick() {
206: if (wasMouseClicked())
207: nextPage();
208: }
209:
210: /**
211: * Shows the previous question page if the mouse was clicked.
212: */
213: public void prevPageClick() {
214: if (wasMouseClicked())
215: prevPage();
216: }
217:
218: /**
219: * Shows the first question page if the mouse was clicked
220: */
221: public void firstPageClick() {
222: if (wasMouseClicked())
223: firstPage();
224: }
225:
226: /**
227: * Saves the responses given by the user and displays
228: * the finish page.
229: * @param finishPage the name of the last page.
230: */
231: protected void showThankYouPage(String finishPage) {
232: Survey currentSurvey = surveyManager.getCurrentSurvey();
233: pageMgr.showPage(finishPage, "content");
234: }
235:
236: /**
237: * Saves the responses given by the user in this survey.
238: * @param Vector containing user's responses
239: */
240: protected void saveResponses(Vector responses) {
241: SurveyManager surveyManager = (SurveyManager) project
242: .getObject("SurveyManager");
243: surveyManager.saveUserResponses(responses);
244: }
245:
246: /**
247: * Stores the current question page in the survey history
248: * and shows the specified page.
249: * @param the name of the page to be shown
250: * @return false if there is no more question pages to show,
251: * false otherwise
252: */
253: protected boolean showNextPage(String questionPage) {
254: Survey currentSurvey = surveyManager.getCurrentSurvey();
255: String currentPageName = pageMgr.getCurrentPage("content")
256: .getName();
257: currentSurvey.saveInHistory(currentPageName);
258: boolean hasMoreQuestions = currentSurvey.shiftToNextPage();
259: if (hasMoreQuestions)
260: reloadQuestionPage(questionPage);
261: return hasMoreQuestions;
262: }
263:
264: /**
265: * Returns the default name of the page template for the
266: * current question type.
267: * @return the name of the page
268: */
269: public String getCurrentQuestionTemplate() {
270: Survey currentSurvey = surveyManager.getCurrentSurvey();
271: if (currentSurvey == null)
272: return null;
273: int questionType = currentSurvey.getCurrentQuestion()
274: .getQuestionType();
275: String fileName = null;
276: switch (questionType) {
277: case Question.MUTUALLY_EXCLUSIVE:
278: fileName = surveyManager.getMutuallyExclusiveTemplate();
279: break;
280: case Question.MULTIPLE_CHOICE:
281: fileName = surveyManager.getMultipleChoiceTemplate();
282: break;
283: case Question.FREE_TEXT:
284: fileName = surveyManager.getFreeTextTemplate();
285: break;
286: default:
287: fileName = surveyManager.getMutuallyExclusiveTemplate();
288: break;
289: }
290: return fileName;
291: }
292:
293: /**
294: * Sets the current question
295: * @param questionId the question id
296: * @return the caption of the question
297: */
298: public String setQuestion(int questionId) {
299: Survey currentSurvey = surveyManager.getCurrentSurvey();
300: return currentSurvey.setCurrentQuestion(questionId);
301: }
302:
303: /**
304: * Sets the current group of questions and the current question
305: * @param groupId the group id
306: * @param questionId the id of the question
307: * @return the caption of the question
308: */
309: public String setGroupQuestion(int groupId, int questionId) {
310: Survey currentSurvey = surveyManager.getCurrentSurvey();
311: currentSurvey.setCurrentGroup(groupId);
312: return currentSurvey.setCurrentQuestion(questionId);
313: }
314:
315: /**
316: * Gets the next question in the current survey.
317: * @return text of the next question
318: */
319: public String getNextQuestion() {
320: Survey currentSurvey = surveyManager.getCurrentSurvey();
321: return currentSurvey.getNextQuestionText();
322: }
323:
324: /**
325: * Gets the id of the current question.
326: * @return the current question id.
327: */
328: public String getCurrentQuestionId() {
329: Survey currentSurvey = surveyManager.getCurrentSurvey();
330: return currentSurvey.getCurrentQuestionId();
331: }
332:
333: /**
334: * Gets the current question in the current survey.
335: * @return text of the current question.
336: */
337: public String getCurrentQuestion() {
338: Survey currentSurvey = surveyManager.getCurrentSurvey();
339: return currentSurvey.getCurrentQuestionText();
340: }
341:
342: /**
343: * Gets the id of the current question group.
344: * @return the current group's id
345: */
346: public String getCurrentGroupId() {
347: Survey currentSurvey = surveyManager.getCurrentSurvey();
348: return currentSurvey.getCurrentGroupId();
349: }
350:
351: /**
352: * Gets the name of the current question group.
353: * @return the current group's name.
354: */
355: public String getCurrentGroupName() {
356: Survey currentSurvey = surveyManager.getCurrentSurvey();
357: return currentSurvey.getCurrentGroup().getName();
358: }
359:
360: /**
361: * Gets the number of the current page.
362: * @return current page's number.
363: */
364: public String getCurrentPageNr() {
365: Survey currentSurvey = surveyManager.getCurrentSurvey();
366: return String.valueOf(currentSurvey.getPageNrAsInt());
367: }
368:
369: /**
370: * Gets the name of the current survey.
371: * @return current survey's name.
372: */
373: public String getSurveyName() {
374: Survey currentSurvey = surveyManager.getCurrentSurvey();
375: return currentSurvey.getName();
376: }
377:
378: /**
379: * Indicates whether the iteration through
380: * the current group's questions has more elements
381: * @return true if the iteration has more elements,
382: * false otherwise
383: */
384: public boolean hasMoreQuestions() {
385: Survey currentSurvey = surveyManager.getCurrentSurvey();
386: if (currentSurvey == null) {
387: nextPage();
388: currentSurvey = surveyManager.getCurrentSurvey();
389: }
390: return ((currentSurvey != null) && (currentSurvey
391: .hasMoreQuestionsToShow()));
392: }
393:
394: /**
395: * Indicates whether the iteration through
396: * the options of the current question has more elements.
397: * @return true if the iteration has more elements,
398: * false otherwise
399: */
400: public boolean hasMoreOptions() {
401: Survey currentSurvey = surveyManager.getCurrentSurvey();
402: return currentSurvey.hasMoreOptions();
403: }
404:
405: /**
406: * Gets the id of the current option
407: * @return current option id
408: */
409: public String getCurrentOptionId() {
410: Survey currentSurvey = surveyManager.getCurrentSurvey();
411: return currentSurvey.getCurrentOptionId();
412: }
413:
414: /**
415: * Gets the unique name of the current option
416: * @return option's name
417: */
418: public String getCurrentOptionName() {
419: Survey currentSurvey = surveyManager.getCurrentSurvey();
420: String name = "";
421: name += currentSurvey.getCurrentPageNr() + ".";
422: name += currentSurvey.getCurrentGroup().getId() + ".";
423: name += currentSurvey.getCurrentQuestionId() + ".";
424: name += currentSurvey.getCurrentOptionId();
425: return name;
426: }
427:
428: /**
429: * Gets the next option of the currnent question
430: * @return the text of the next option
431: */
432: public String getNextOption() {
433: Survey currentSurvey = surveyManager.getCurrentSurvey();
434: return currentSurvey.getNextOptionText();
435: }
436:
437: /**
438: * Gets the current option of the current question.
439: * @param text of the current question.
440: */
441: public String getCurrentOption() {
442: Survey currentSurvey = surveyManager.getCurrentSurvey();
443: return currentSurvey.getCurrentOptionText();
444: }
445:
446: /**
447: * Gets the next option of the current question.
448: * @return the text of the next option.
449: */
450: public String getNextOptionId() {
451: Survey currentSurvey = surveyManager.getCurrentSurvey();
452: return currentSurvey.getNextOptionId();
453: }
454:
455: /**
456: * Gets the binding path of the current option. The
457: * type of the current question has to be "mutually exclusive"
458: * @return the binding path
459: */
460: public String getExclusiveOptionModelPath() {
461: Survey currentSurvey = surveyManager.getCurrentSurvey();
462: String path = "xui_state/currentSurvey/";
463: path += currentSurvey.getCurrentPageNr() + "/";
464: path += currentSurvey.getCurrentGroup().getId() + "/";
465: path += currentSurvey.getCurrentQuestionId();
466: return path;
467: }
468:
469: /**
470: * Gets the binding path of the current option. The type
471: * of the current question has to be "free text"
472: * @return the binding path
473: */
474: public String getFreeTextOptionModelPath() {
475: Survey currentSurvey = surveyManager.getCurrentSurvey();
476: String path = "xui_state/currentSurvey/";
477: path += currentSurvey.getCurrentPageNr() + "/";
478: path += currentSurvey.getCurrentGroup().getId() + "/";
479: path += currentSurvey.getCurrentQuestionId() + "/";
480: path += currentSurvey.getCurrentOptionId();
481: return path;
482: }
483:
484: /**
485: * Gets the binding path of the current option. The type
486: * of the current question has to be "multiple choice"
487: * @return the binding path
488: */
489: public String getMultiOptionModelPath() {
490: Survey currentSurvey = surveyManager.getCurrentSurvey();
491: String path = "xui_state/currentSurvey/";
492: path += currentSurvey.getCurrentPageNr() + "/";
493: path += currentSurvey.getCurrentGroup().getId() + "/";
494: path += currentSurvey.getCurrentQuestionId() + "/";
495: path += currentSurvey.getCurrentOptionId();
496: return path;
497: }
498:
499: public void handleFocus() {
500: saveBoundComponentValues();
501: }
502:
503: public void handleMouse() {
504: if (wasMouseClicked())
505: saveBoundComponentValues();
506: }
507:
508: }
|