Source Code Cross Referenced for XQuestion.java in  » XML-UI » xui32 » com » xoetrope » swing » survey » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML UI » xui32 » com.xoetrope.swing.survey 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.xoetrope.swing.survey;
002:
003:        import com.xoetrope.survey.Option;
004:        import com.xoetrope.survey.Survey;
005:        import com.xoetrope.survey.SurveyManager;
006:        import java.awt.Color;
007:        import java.awt.Component;
008:        import java.awt.Dimension;
009:        import java.awt.Font;
010:        import java.awt.FontMetrics;
011:        import java.awt.Graphics;
012:        import java.awt.Image;
013:        import java.awt.Point;
014:        import java.awt.event.FocusEvent;
015:        import java.awt.event.FocusListener;
016:        import java.util.Hashtable;
017:        import javax.swing.JComponent;
018:
019:        import com.xoetrope.event.XClickListener;
020:        import com.xoetrope.event.XStateListener;
021:        import com.xoetrope.survey.Question;
022:        import com.xoetrope.survey.QuestionManager;
023:        import com.xoetrope.survey.XSurveyManager;
024:        import net.xoetrope.swing.XEdit;
025:        import net.xoetrope.xui.XAttributedComponent;
026:        import net.xoetrope.xui.XTextHolder;
027:        import net.xoetrope.xui.data.XDataBinding;
028:        import net.xoetrope.xui.data.XModel;
029:        import net.xoetrope.xui.style.XStyle;
030:        import net.xoetrope.xui.style.XStyleFactory;
031:        import net.xoetrope.xui.style.XStyleManager;
032:        import net.xoetrope.xml.XmlElement;
033:        import net.xoetrope.xui.XProject;
034:        import net.xoetrope.xui.XProjectManager;
035:
036:        /**
037:         * <p>Title: XQuestion</p>
038:         * <p>Description: A component for rendering a question and a set of mutually
039:         * exclusive answers. The possible answers are rendered as a set of check marks</p>
040:         *
041:         * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
042:         * the GNU Public License (GPL), please see license.txt for more details. If
043:         * you make commercial use of this software you must purchase a commercial
044:         * license from Xoetrope.</p>
045:         * <p> $Revision: 1.12 $</p>
046:         */
047:        public class XQuestion extends JComponent implements  XStateListener,
048:                XTextHolder, XAttributedComponent {
049:            // gap between question text and the responses
050:            protected int headerHeight = 10;
051:
052:            // the stripe at the top of this componenet
053:            protected int topBandHeight = 10;
054:
055:            // gaps on the left and on the right side
056:            protected int woffset = 40;
057:
058:            // value of the arc used for rendering radiobuttons
059:            protected int radioArc = 5;
060:
061:            // radiobuttons and checkboxes size
062:            protected int checkSize = 10;
063:
064:            // width of "free text" component
065:            protected int editWidth = 60;
066:
067:            // height of "free text" component
068:            protected int editHeight = 18;
069:
070:            // radiobuttons and checkboxes height
071:            protected int checkHeight = 10;
072:
073:            // the gap between the responses comonent (like radiobutton)
074:            // and the reponsse text
075:            protected int responseTextGap = 9;
076:
077:            // the gap between the question text and responses
078:            protected int responseVGap = 13;
079:
080:            // the gap between the left side of the main frame
081:            // and the firs response
082:            protected int responseHGap = 60;
083:
084:            // size of the frame which is painted when the component is active
085:            protected int frameSize = 2;
086:
087:            // the minim scale defining gaps between responses
088:            protected int minScale = 5;
089:
090:            // question being rendered by this component
091:            protected Question question;
092:
093:            // how many responses will fit in this component
094:            protected int scale;
095:
096:            // the width of a single response (in pixels)
097:            protected int xScale;
098:
099:            // handles the mouse actions
100:            protected XClickListener clickListener;
101:
102:            // the name of the cue image file
103:            private String cueImage;
104:
105:            // stores the responses, according to this value
106:            // the responses are rendered
107:            protected int responseState = 0;
108:
109:            /** Style settings */
110:            protected static XStyleManager styleManager;
111:            // top stripe
112:            protected static Color cueColor;
113:            // background of a "cue" image
114:            protected static Color cueBkColor;
115:            // responses (options) text
116:            protected static Color responseTextColor;
117:            // "shade" style of the responses checkboxes and radiobuttons
118:            protected static Color responseTextBkColor;
119:            // this component's background
120:            protected static Color questionBkColor;
121:            // question's text
122:            protected static Color questionTextColor;
123:            // filling of responses checkboxes and radiobuttons
124:            protected static Color checkBkColor;
125:            // frames of the checkboxes and radiobuttons
126:            protected static Color checkColor;
127:
128:            protected static Color shadowColor;
129:
130:            protected static Color selectedColor;
131:
132:            protected static Color shadeColor;
133:
134:            // table containging edit edit field used to render responses
135:            // in case the question type is "free text"
136:            protected XEdit[] editTable;
137:
138:            // the data to be rendered by this component are obtained from here
139:            protected SurveyManager surveyManager;
140:
141:            protected XProject currentProject;
142:
143:            protected boolean printing;
144:
145:            // if this question is the last one on this page, 
146:            // the last one is rendered with a stripe at the bottom
147:            protected boolean isLastQuestion;
148:
149:            // for use in the paint method
150:            protected int hh;
151:            protected FontMetrics fm;
152:
153:            // indicates whether the scale has been specified explicitly  
154:            protected boolean scaleSpecified = false;
155:
156:            // model node where the responses to this question will be stored
157:            protected XModel responseModel;
158:
159:            /**
160:             * Create a new question component
161:             */
162:            public XQuestion() {
163:                currentProject = XProjectManager.getCurrentProject();
164:                surveyManager = (SurveyManager) currentProject
165:                        .getObject("SurveyManager");
166:                setStyles();
167:            }
168:
169:            /**
170:             * Sets the styles   
171:             */
172:            private void setStyles() {
173:                if (questionTextColor == null) {
174:                    styleManager = currentProject.getStyleManager();
175:                    XStyle questionStyle = styleManager
176:                            .getStyle("base/Question");
177:                    XStyle responseStyle = styleManager
178:                            .getStyle("base/Question/Response");
179:                    XStyle checkStyle = styleManager
180:                            .getStyle("base/Question/Check");
181:                    XStyle cueStyle = styleManager
182:                            .getStyle("base/Question/Cue");
183:                    XStyle shadeStyle = styleManager
184:                            .getStyle("base/Question/Shade");
185:                    XStyle threeDStyle = styleManager
186:                            .getStyle("base/Question/ThreeD");
187:
188:                    questionTextColor = questionStyle
189:                            .getStyleAsColor(XStyle.COLOR_FORE);
190:                    questionBkColor = questionStyle
191:                            .getStyleAsColor(XStyle.COLOR_BACK);
192:                    cueBkColor = cueStyle.getStyleAsColor(XStyle.COLOR_BACK);
193:                    cueColor = cueStyle.getStyleAsColor(XStyle.COLOR_FORE);
194:                    responseTextColor = responseStyle
195:                            .getStyleAsColor(XStyle.COLOR_FORE);
196:                    responseTextBkColor = responseStyle
197:                            .getStyleAsColor(XStyle.COLOR_BACK);
198:                    checkBkColor = checkStyle
199:                            .getStyleAsColor(XStyle.COLOR_BACK);
200:                    checkColor = checkStyle.getStyleAsColor(XStyle.COLOR_FORE);
201:                    shadowColor = threeDStyle
202:                            .getStyleAsColor(XStyle.COLOR_BACK);
203:                    selectedColor = threeDStyle
204:                            .getStyleAsColor(XStyle.COLOR_FORE);
205:                    shadeColor = shadeStyle.getStyleAsColor(XStyle.COLOR_BACK);
206:                }
207:            }
208:
209:            /**
210:             * Gets the preferred size of the component.
211:             * @return the size as a Dimension
212:             */
213:            public Dimension getPreferredSize() {
214:                return getSize();
215:            }
216:
217:            /**
218:             * Sets the size and location of the component and rescales the content to match
219:             * @param x
220:             * @param y
221:             * @param w
222:             * @param h
223:             */
224:            public void setBounds(int x, int y, int w, int h) {
225:                super .setBounds(x, y, w, h);
226:                setScale(scale);
227:            }
228:
229:            /**
230:             * Sets the scale. The scale controls the horizontal division of the question
231:             * area. Normally this would be set to the maximum number of responses in a
232:             * survey. For example if most questions have 5 possible answers then the scale
233:             * would be set to 5
234:             * @param newScale
235:             */
236:            public void setScale(int newScale) {
237:                scale = (newScale >= minScale ? newScale : minScale);
238:                xScale = (getSize().width - woffset * 2) / scale;
239:            }
240:
241:            /**
242:             * Adds a new response option
243:             * @param value the value of the response
244:             * @param caption the text
245:             */
246:            public void addResponse(int value, String caption) {
247:                question.addOption(value, caption);
248:            }
249:
250:            /**
251:             * Refresh the display
252:             * @param g the graphics context
253:             */
254:            public void update(Graphics g) {
255:                paint(g);
256:            }
257:
258:            /**
259:             * Print the page
260:             * @param g the printer graphics context
261:             */
262:            public void print(Graphics g) {
263:                printing = true;
264:                paint(g);
265:                printing = false;
266:            }
267:
268:            protected void paintTopBand(Graphics g) {
269:                Dimension d = getSize();
270:                g.setColor(cueColor);
271:                g.fillRect(0, 0, d.width, topBandHeight);
272:                g.setColor(questionBkColor);
273:                g.fillRect(0, topBandHeight + 1, d.width, d.height);
274:            }
275:
276:            protected void paintQuestionText(Graphics g) {
277:                int xOffset = woffset;
278:                //    XStyle questionStyle = styleManager.getStyle( "base/Question/Cue" );
279:                XStyle questionStyle = styleManager.getStyle("base/Question");
280:                Font f = styleManager.getFont(questionStyle);
281:                if (f == null)
282:                    f = new Font("Dialog", 0, 10);
283:                g.setFont(f);
284:                fm = g.getFontMetrics(f);
285:                hh = fm.getHeight() + headerHeight + topBandHeight;
286:
287:                String qText = question.getText();
288:                if (qText != null) {
289:                    g.setColor(questionTextColor);
290:                    g.drawString(question.getText(), xOffset, fm.getAscent()
291:                            + topBandHeight + 10);
292:                }
293:            }
294:
295:            protected void paintCueImage(Graphics g) {
296:                int xOffset = woffset;
297:                if (cueImage != null) {
298:                    Image img = currentProject.getImage(cueImage);
299:                    if (img != null)
300:                        g.drawImage(img, xOffset, hh + 2, cueBkColor, this );
301:                }
302:            }
303:
304:            protected void paintCheckBox(int x, int y, Graphics g) {
305:                g.setColor(checkBkColor);
306:                g.fillRect(x + 1, y, checkSize, checkSize - 2);
307:                g.setColor(shadowColor);
308:                g.drawRect(x + 1, y, checkSize, checkSize);
309:                g.setColor(checkColor);
310:                g.drawRect(x, y - 1, checkSize, checkSize);
311:            }
312:
313:            protected void paintRadioButton(int x, int y, Graphics g) {
314:                g.setColor(checkBkColor);
315:                g.fillRoundRect(x + 1, y, checkSize, checkSize - 2, radioArc,
316:                        radioArc);
317:                g.setColor(shadowColor);
318:                g.drawRoundRect(x + 1, y, checkSize, checkSize, radioArc,
319:                        radioArc);
320:                g.setColor(checkColor);
321:                g.drawRoundRect(x, y - 1, checkSize, checkSize, radioArc,
322:                        radioArc);
323:            }
324:
325:            protected void paintResponses(Graphics g) {
326:                Dimension d = getSize();
327:                XStyle questionStyle = styleManager
328:                        .getStyle("base/Question/Cue");
329:                Font f = styleManager.getFont(questionStyle);
330:                XStyle responseStyle = styleManager
331:                        .getStyle("base/Question/Response");
332:                Font f2 = styleManager.getFont(responseStyle);
333:                if (f2 == null)
334:                    f2 = f;
335:                g.setFont(f2);
336:                fm = g.getFontMetrics(f2);
337:
338:                hh = Math.min(hh, d.height - fm.getAscent() - 11);
339:
340:                int xOffset = responseHGap;
341:                int numResponses = (question != null ? question.getNumOptions()
342:                        : 0);
343:
344:                for (int i = 0; i < numResponses; i++) {
345:                    String responseText = question.getOptionText(i);
346:                    if (responseText != null) {
347:                        // multiple choice, rendered with checkboxes
348:                        if (question.getQuestionType() == Question.MULTIPLE_CHOICE) {
349:                            paintCheckBox(xOffset, hh + responseVGap, g);
350:                            g.setColor(responseTextColor);
351:                            g.drawString(responseText, xOffset + checkSize
352:                                    + responseTextGap, hh + fm.getAscent()
353:                                    + responseVGap - 3);
354:                        }
355:                        // mutually exclusive, rendered with radio buttons
356:                        else if (question.getQuestionType() == Question.MUTUALLY_EXCLUSIVE) {
357:                            g.setColor(checkBkColor);
358:                            paintRadioButton(xOffset, hh + responseVGap, g);
359:                            g.setColor(responseTextColor);
360:                            g.drawString(responseText, xOffset + checkSize
361:                                    + responseTextGap, hh + fm.getAscent()
362:                                    + responseVGap - 3);
363:                        }
364:                        // free text, rednered with edit fields
365:                        else if (question.getQuestionType() == Question.FREE_TEXT) {
366:                            g.setColor(responseTextColor);
367:                            g.drawString(responseText, xOffset + 2, hh
368:                                    + fm.getAscent() + responseVGap - 3);
369:                            int w = (int) fm.getStringBounds(responseText, g)
370:                                    .getWidth();
371:                            editTable[i].setLocation(xOffset + w + 6, hh
372:                                    + responseVGap - 3);
373:                        }
374:                    }
375:                    xOffset += xScale;
376:                }
377:            }
378:
379:            protected void paintHighlightFrame(Graphics g) {
380:                if ((clickListener != null) && (clickListener.getIsEntered())) {
381:                    Dimension d = getSize();
382:                    g.setColor(checkColor);
383:                    int m = (isLastQuestion ? 2 : 1);
384:                    for (int i = 0; i < frameSize; i++)
385:                        g.drawRect(i, topBandHeight + i, d.width - 1 - 2 * i,
386:                                d.height - m * topBandHeight - 1 - 2 * i);
387:                }
388:            }
389:
390:            protected void paintActiveCheckBox(int x, int y, Graphics g) {
391:                g.setColor(shadowColor);
392:                g.fillRect(x + 1, y + 1, checkSize - 1, checkSize - 1);
393:            }
394:
395:            protected void paintActiveRadioButton(int x, int y, Graphics g) {
396:                g.setColor(shadowColor);
397:                int w = checkSize;
398:                int h = checkSize;
399:                int arc = radioArc;
400:                g.fillRoundRect(x, y, w, h, arc, arc);
401:                g.setColor(checkColor);
402:                g.drawRoundRect(x, y, w, h, arc, arc);
403:            }
404:
405:            protected void paintActiveResponses(Graphics g) {
406:                // the filling of an active responses (in case of checkboxes and radiobuttons)
407:                int questionType = question.getQuestionType();
408:                if ((questionType != Question.FREE_TEXT)
409:                        && (clickListener != null)
410:                        && (clickListener.getIsEntered())) {
411:                    int activeResponse = clickListener.getActiveResponse();
412:                    if (activeResponse >= 0) {
413:                        int xOffset = responseHGap;
414:
415:                        if (questionType == Question.MULTIPLE_CHOICE) {
416:                            int x = xOffset + activeResponse * xScale;
417:                            int y = hh + responseVGap - 1;
418:                            paintActiveCheckBox(x, y, g);
419:                        } else if (questionType == Question.MUTUALLY_EXCLUSIVE) {
420:                            int x = xOffset + activeResponse * xScale;
421:                            int y = hh + responseVGap - 1;
422:                            paintActiveRadioButton(x, y, g);
423:                        }
424:                    }
425:
426:                }
427:            }
428:
429:            protected void paintSelectedResponses(Graphics g) {
430:                if (question.getQuestionType() == Question.FREE_TEXT)
431:                    return;
432:                g.setColor(checkColor);
433:                int xOffset = responseHGap;
434:                int resState = responseState;
435:                while (resState > 0) {
436:                    if ((resState & 0x1) == 1) {
437:                        int x = xOffset + 3;
438:                        int y = hh + responseVGap + 2;
439:                        int w = checkSize - 5;
440:                        int h = checkSize - 5;
441:                        g.fillRect(x, y, w, h);
442:                    }
443:
444:                    resState >>= 1;
445:                    xOffset += xScale;
446:                }
447:            }
448:
449:            protected void paintBottomBand(Graphics g) {
450:                Dimension d = getSize();
451:                g.setColor(cueColor);
452:                g.fillRect(0, d.height - topBandHeight, d.width, topBandHeight);
453:            }
454:
455:            /**
456:             * Render the question. A header is drawn containing the question text, then
457:             * the body of the question is filled. Within the body the cue image is drawn
458:             * followed by each response spaced equally and left aligned
459:             * @param sg the graphics context
460:             */
461:            public void paint(Graphics sg) {
462:                // initialize
463:                Image offscreen;
464:                Graphics g;
465:                if (!printing) {
466:                    offscreen = createImage(getSize().width, getSize().height);
467:                    g = offscreen.getGraphics();
468:                } else {
469:                    offscreen = null;
470:                    g = sg;
471:                }
472:
473:                Dimension d = getSize();
474:                g.setClip(0, 0, d.width, d.height);
475:                //////////
476:
477:                paintTopBand(g);
478:                paintQuestionText(g);
479:                paintCueImage(g);
480:                paintResponses(g);
481:
482:                // paint the edit fields that has been added
483:                super .paint(g);
484:                paintHighlightFrame(g);
485:                paintActiveResponses(g);
486:                paintSelectedResponses(g);
487:
488:                if (isLastQuestion)
489:                    paintBottomBand(g);
490:
491:                if (!printing) {
492:                    sg.drawImage(offscreen, 0, 0, getSize().width,
493:                            getSize().height, null);
494:                    g.dispose();
495:                    offscreen = null;
496:                }
497:
498:            }
499:
500:            // to be invoked by sublclasses
501:            protected void super Paint(Graphics g) {
502:                super .paint(g);
503:            }
504:
505:            /**
506:             * Gets the question's id
507:             * @return The ID
508:             */
509:            public int getId() {
510:                return question.getId();
511:            }
512:
513:            /**
514:             * Gets the selected response
515:             * @return the response value
516:             */
517:            public String getResponse() {
518:                if (clickListener == null)
519:                    return null;
520:
521:                if (clickListener.getSelectedResponse() < 0)
522:                    return "0";
523:
524:                if (question.getQuestionType() == Question.MULTIPLE_CHOICE) {
525:                    int responses = question.getNumOptions();
526:                    String response = new String();
527:                    for (int i = 0; i < responses; i++) {
528:                        if (response.length() > 0)
529:                            response += QuestionManager.tokenSeparator;
530:                        if (isOptionSelected(i))
531:                            response += new Integer(question.getOptionId(i))
532:                                    .toString();
533:                        else
534:                            response += "-";
535:                    }
536:                    return response;
537:                }
538:
539:                return new Integer(question.getOptionId(clickListener
540:                        .getSelectedResponse())).toString();
541:            }
542:
543:            /**
544:             * Checks to see if a praticular option is selected
545:             * @param idx the index of the option
546:             * @return true if the option is selected
547:             */
548:            public boolean isOptionSelected(int idx) {
549:                int response = 1;
550:                response <<= idx;
551:                return (responseState & response) > 0;
552:            }
553:
554:            /**
555:             * Find a response state based on the coordinates of the mouse click
556:             * @param x the x coordinate of the mouse click
557:             * @param y the y coordinate of the mouse click
558:             * @param defResponse the default response
559:             * @return true if a response was found
560:             */
561:            public boolean setState(int x, int y, int defResponse) {
562:                int activeResponse = findCurrentResponse(x, y);
563:                if (activeResponse == Integer.MIN_VALUE)
564:                    activeResponse = defResponse;
565:
566:                if (clickListener != null)
567:                    clickListener.setActiveResponse(activeResponse);
568:                return (defResponse != activeResponse);
569:            }
570:
571:            /**
572:             * Find a response state based on the coordinates of the mouse click
573:             * @param x the x coordinate of the mouse click
574:             * @param y the y coordinate of the mouse click
575:             * @return the response id or Integer.MIN_VALUE if a response was not selected
576:             */
577:            public int findCurrentResponse(int x, int y) {
578:                int numResponses = question.getNumOptions();
579:                int activeResponse = x / xScale;
580:                if ((activeResponse == 0) && (x < 0))
581:                    activeResponse = Integer.MIN_VALUE;
582:                else if (activeResponse >= numResponses)
583:                    activeResponse = Integer.MIN_VALUE;
584:
585:                return activeResponse;
586:            }
587:
588:            /**
589:             * Called by XClickListener to check if a response event should be sent to the
590:             * parent form. The control can also use this event to do post click processing
591:             * @return true if the parent is to be notified
592:             */
593:            public boolean fireActionEvent() {
594:                return true;
595:            }
596:
597:            /**
598:             * Repaints the responses so that the current response is shown
599:             */
600:            public void paintStates() {
601:                repaint();
602:            }
603:
604:            /**
605:             * Updates the state of the options
606:             */
607:            public void updateSelectedState() {
608:                int selectedResponse = -1;
609:                if (clickListener != null)
610:                    selectedResponse = clickListener.getSelectedResponse();
611:                if (selectedResponse >= 0) {
612:                    int response = 1;
613:                    response <<= selectedResponse;
614:                    if (question.getQuestionType() == question.MULTIPLE_CHOICE)
615:                        responseState ^= response; // toggle the response
616:                    else
617:                        responseState = response;
618:                    storeResponses();
619:                }
620:            }
621:
622:            protected void retrieveResponses() {
623:                responseState = 0;
624:                int questionType = question.getQuestionType();
625:                // multiple choice
626:                if (questionType == Question.MULTIPLE_CHOICE) {
627:                    int numOptions = question.getNumOptions();
628:                    for (int i = 0; i < numOptions; i++) {
629:                        String optionId = String.valueOf(question.getOption(i)
630:                                .getId());
631:                        XModel optionModel = (XModel) responseModel
632:                                .get(optionId);
633:
634:                        Object o = optionModel.get();
635:                        if ((optionModel == null) || (o == null)
636:                                || (o.toString().equals("0")))
637:                            continue;
638:                        // mark the response
639:                        responseState |= (1 << i);
640:                    }
641:                }
642:                // mutually exclusive
643:                else if (questionType == Question.MUTUALLY_EXCLUSIVE) {
644:                    String option = responseModel.getAttribValueAsString(0);
645:                    if ((option != null) && (!"".equals(option))) {
646:                        int optionId = question.getOptionIdByText(option);
647:                        int idx = question.getOptionIdx(optionId);
648:                        responseState |= (1 << idx);
649:                    }
650:                }
651:                // free text
652:                else if (questionType == Question.FREE_TEXT) {
653:                    int numOptions = question.getNumOptions();
654:                    for (int i = 0; i < numOptions; i++) {
655:                        String optionId = String.valueOf(question.getOption(i)
656:                                .getId());
657:                        XModel optionModel = (XModel) responseModel
658:                                .get(optionId);
659:                        String text = optionModel.getAttribValueAsString(i);
660:                        if (text != null)
661:                            editTable[i].setText(text);
662:                    }
663:                }
664:            }
665:
666:            protected void storeFreeTextResponses() {
667:                int numOptions = question.getNumOptions();
668:                for (int i = 0; i < numOptions; i++) {
669:                    String text = editTable[i].getText();
670:                    String optionId = String.valueOf(question.getOption(i)
671:                            .getId());
672:                    XModel optionModel = (XModel) responseModel.get(optionId);
673:                    optionModel.setAttribValue(0, text);
674:                }
675:            }
676:
677:            protected void storeResponses() {
678:                int state = responseState;
679:                int questionType = question.getQuestionType();
680:
681:                // mutliple choice
682:                if (questionType == Question.MULTIPLE_CHOICE) {
683:                    int numOptions = question.getNumOptions();
684:                    for (int i = 0; i < numOptions; i++) {
685:                        String optionId = String.valueOf(question.getOption(i)
686:                                .getId());
687:                        XModel optionModel = (XModel) responseModel
688:                                .get(optionId);
689:                        optionModel.set(((state & 0x1) == 1) ? "1" : "0");
690:                        state >>= 1;
691:                    }
692:
693:                }
694:                // mutually exclusive
695:                else if (questionType == Question.MUTUALLY_EXCLUSIVE) {
696:                    int selResponse = -1;
697:                    int numOptions = question.getNumOptions();
698:                    for (int i = 0; i < numOptions; i++) {
699:                        if ((state & 0x1) == 1) {
700:                            selResponse = i;
701:                            break;
702:                        }
703:                        state >>= 1;
704:                    }
705:                    if (selResponse >= 0) {
706:                        Option option = question.getOption(selResponse);
707:                        String optionText = option.getText();
708:                        responseModel.setAttribValue(0, optionText);
709:                    }
710:
711:                }
712:                // free text
713:                else if (questionType == Question.FREE_TEXT) {
714:                    storeFreeTextResponses();
715:                }
716:            }
717:
718:            /**
719:             * Unchecks all responses
720:             */
721:            public void clear() {
722:                if (clickListener != null)
723:                    clickListener.setSelectedResponse(-1);
724:                repaint();
725:            }
726:
727:            /**
728:             * Sets the control's text. Used to localize the control. In the case of this
729:             * control the method does nothing since the questions are localized as part
730:             * of an entire questionaire.
731:             *
732:             * @param s The new text to display.
733:             */
734:            public void setText(String s) {
735:                if (question != null)
736:                    question.setText(s);
737:            }
738:
739:            /**
740:             * Gets the questions text
741:             * @return The question text
742:             */
743:            public String getText() {
744:                return question.getText();
745:            }
746:
747:            /**
748:             * Gets the question id.
749:             * @return the Question ID
750:             */
751:            public int getQuestionId() {
752:                return question.getId();
753:            }
754:
755:            /**
756:             * Gets the question.
757:             * @return the question or null if none isreferenced
758:             */
759:            public Question getQuestion() {
760:                return question;
761:            }
762:
763:            /**
764:             * Gets the question type.
765:             * @return The question type
766:             */
767:            public int getQuestionType() {
768:                return question.getQuestionType();
769:            }
770:
771:            /**
772:             * Set one or more attributes of the component. Currently this handles the
773:             * attributes
774:             * <OL>
775:             * <LI>cue, value=Cue image filename</LI>
776:             * </OL>
777:             * @return 0 for success, non zero otherwise
778:             */
779:            public int setAttribute(String attribName, Object attribValue) {
780:                String attribNameLwr = attribName.toLowerCase();
781:                String attribValueStr = (String) attribValue;
782:                if (attribNameLwr.equals("cue"))
783:                    cueImage = attribValueStr;
784:                else if (attribNameLwr.equals("scale")) {
785:                    scaleSpecified = true;
786:                    setScale(new Integer(attribValueStr).intValue());
787:                } else if (attribNameLwr.equals("id"))
788:                    question.setId(new Integer(attribValueStr).intValue());
789:                else if (attribNameLwr.equals("ref")) {
790:                    Survey survey = surveyManager.getCurrentSurvey();
791:                    question = survey.getNextQuestion();
792:                    responseModel = getResponsesModel(survey);
793:                    isLastQuestion = !survey.hasMoreQuestionsToShow();
794:                    if (!scaleSpecified) {
795:                        int numResponses = question.getNumOptions();
796:                        setScale(numResponses);
797:                    }
798:                    if (question.getQuestionType() != Question.FREE_TEXT) {
799:                        clickListener = new XClickListener(this , woffset);
800:                        addMouseListener(clickListener);
801:                        addMouseMotionListener(clickListener);
802:                    } else {
803:                        createEditFields();
804:                        clickListener = new XClickListener(this , woffset);
805:                        addMouseMotionListener(clickListener);
806:                        addMouseListener(clickListener);
807:                    }
808:                    retrieveResponses();
809:                }
810:
811:                if (isVisible())
812:                    repaint(100);
813:
814:                return 0;
815:            }
816:
817:            /**
818:             * Returns the XModel node that will store the user's given
819:             * responsese to this question
820:             * @param survey the currenty survey
821:             * @return responses model node
822:             */
823:            protected XModel getResponsesModel(Survey survey) {
824:                String path = "/xui_state/currentSurvey/";
825:                path += survey.getCurrentPageNr() + "/";
826:                path += survey.getCurrentGroup().getId() + "/";
827:                path += survey.getCurrentQuestionId();
828:                XModel model = (XModel) currentProject.getModel().get(path);
829:                return model;
830:            }
831:
832:            /**
833:             * In case the question type is "free text" creates
834:             * and adds the XEdit components to render the question's
835:             * answers.
836:             */
837:            private void createEditFields() {
838:                Dimension dim = new Dimension(editWidth, editHeight);
839:                XStyleFactory styleFactory = new XStyleFactory(currentProject,
840:                        "net.xoetrope.swing");
841:                XStyle responseStyle = currentProject.getStyleManager()
842:                        .getStyle("base/Question/Response");
843:
844:                int numResponses = question.getNumOptions();
845:                editTable = new XEdit[numResponses];
846:                for (int i = 0; i < numResponses; i++) {
847:                    XEdit edit = editTable[i] = new XEdit();
848:
849:                    edit.addFocusListener(new FocusListener() {
850:                        public void focusGained(FocusEvent e) {
851:                            storeFreeTextResponses();
852:                        }
853:
854:                        public void focusLost(FocusEvent e) {
855:                            storeFreeTextResponses();
856:                        }
857:                    });
858:
859:                    edit.setSize(dim);
860:                    edit.setPreferredSize(dim);
861:                    styleFactory.applyStyle(edit, responseStyle);
862:                    edit.setLocation(20, 20);
863:                    add(edit);
864:                }
865:            }
866:
867:            /**
868:             * Get the model path
869:             */
870:            public String getSourcePath() {
871:                return "currentSurvey/question/"
872:                        + new Integer(question.getId()).toString();
873:            }
874:
875:            /**
876:             * Get the output/save path
877:             */
878:            public String getOutputPath() {
879:                return "currentSurvey/question/"
880:                        + new Integer(question.getId()).toString();
881:            }
882:
883:            /**
884:             * Set the model path for the source data
885:             */
886:            public void setSourcePath(String newPath) {
887:            }
888:
889:            /**
890:             * Set the model path for the output/state data
891:             */
892:            public void setOutputPath(String newPath) {
893:            }
894:
895:            /**
896:             * Update the model node used in the binding. Note that this method does not
897:             * modify the path values stored by this node.
898:             * @param newNode the new model for the data source
899:             */
900:            public void setSource(XModel newNode) {
901:            }
902:
903:            /**
904:             * Update the path values stored by this node. The output path is used to
905:             * store selection data and state.
906:             * @param newModel the new model for saving the output data
907:             */
908:            public void setOutput(XModel newModel, String outputPath) {
909:            }
910:
911:            /**
912:             * Used for custom components with an argumentless constructor. Constructs the
913:             * binding from the model path argument and the XML argument that defines
914:             * the binding.
915:             * This object does not implement this method and throws an UnsupportedOperationException.
916:             * @param c the component to bind
917:             * @param dataElement the path to the data source
918:             * @param ele the XML element which contains the binding configuration
919:             */
920:            public void setup(Component c, String dataElement, XmlElement ele) {
921:                throw new UnsupportedOperationException();
922:            }
923:
924:            /**
925:             * Get the component to which this binding is attached
926:             */
927:            public Object getComponent() {
928:                return this ;
929:            }
930:
931:            /**
932:             * Get the file name of the cue image
933:             * @return the file name
934:             */
935:            public String getCueFileName() {
936:                return cueImage;
937:            }
938:
939:            /**
940:             * Gets the scale being used by this question for its layout
941:             * @return the scale
942:             */
943:            public int getScale() {
944:                return scale;
945:            }
946:
947:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.