View Javadoc

1   /***
2    * 
3    */
4   package org.telscenter.pas.steps;
5   
6   import info.clearthought.layout.TableLayout;
7   
8   import java.awt.BorderLayout;
9   import java.awt.Component;
10  import java.awt.Dimension;
11  import java.awt.event.ActionEvent;
12  import java.awt.event.ActionListener;
13  import java.awt.event.ComponentEvent;
14  import java.awt.event.ComponentListener;
15  import java.io.InputStream;
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.Iterator;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  import java.util.logging.Logger;
23  
24  import javax.swing.AbstractAction;
25  import javax.swing.BorderFactory;
26  import javax.swing.Box;
27  import javax.swing.BoxLayout;
28  import javax.swing.ButtonGroup;
29  import javax.swing.ImageIcon;
30  import javax.swing.JButton;
31  import javax.swing.JComponent;
32  import javax.swing.JLabel;
33  import javax.swing.JPanel;
34  import javax.swing.JRadioButton;
35  import javax.swing.JScrollPane;
36  import javax.swing.JTabbedPane;
37  import javax.swing.JTextArea;
38  import javax.swing.ScrollPaneConstants;
39  import javax.swing.event.DocumentEvent;
40  import javax.swing.event.DocumentListener;
41  import javax.swing.text.BadLocationException;
42  import javax.swing.text.Document;
43  
44  import org.apache.commons.io.IOUtils;
45  import org.apache.commons.lang.StringUtils;
46  import org.telscenter.pas.common.ui.CommonUI;
47  import org.telscenter.pas.common.ui.panel.CardPanel;
48  import org.telscenter.pas.steps.domain.BlockInteraction;
49  import org.telscenter.pas.steps.domain.ChoiceInteraction;
50  import org.telscenter.pas.steps.domain.ExtendedTextInteraction;
51  import org.telscenter.pas.steps.domain.SimpleChoice;
52  import org.telscenter.pas.ui.icons.PasCommonIconProvider;
53  import org.telscenter.pas.util.QTIUtils;
54  import org.xhtmlrenderer.simple.XHTMLPanel;
55  
56  /***
57   * @author aperritano
58   * 
59   */
60  public abstract class AssessmentUI extends JPanel implements IQtiStepUI {
61  
62  	protected static final Logger logger = Logger.getLogger(AssessmentUI.class
63  			.getName());
64  
65  	private static final long serialVersionUID = 1L;
66  
67  	public static final ImageIcon greenCheck = new ImageIcon(
68  				PasCommonIconProvider.getImage("guessCorrect.gif"));
69  	
70  	public static final ImageIcon redX = new ImageIcon(PasCommonIconProvider.getImage("guessWrong.gif"));
71  
72  	protected String RESPONSE_ID = "RESPONSE_ID"; //$NON-NLS-1$
73  
74  	protected transient Map<ChoiceInteraction<String>, List<JRadioButton>> choiceInteractionToChoiceButtonLists = new HashMap<ChoiceInteraction<String>, List<JRadioButton>>();
75  
76  	protected CardPanel cardPanel = new CardPanel();
77  
78  	protected JPanel mainPanel;
79  
80  	protected JButton previousTabButton;
81  
82  	protected JButton nextTabButton;
83  
84  	protected JTabbedPane tabbedPane;
85  
86  	protected Map<JButton, ExtendedTextInteraction> placeholderButtonsToTextInteractions = new HashMap<JButton, ExtendedTextInteraction>();
87  
88  	protected Map<ExtendedTextInteraction, JTextArea> textInteractionsToTextareas = new HashMap<ExtendedTextInteraction, JTextArea>();
89  
90  	protected ImageIcon checkIcon = new ImageIcon(PasCommonIconProvider
91  			.getImage("accept.png"));
92  
93  	protected boolean showTabButtons;
94  
95  	protected boolean showGetStartedPanel;
96  	
97  	protected boolean showPlaceHolderPanel = true;
98  	
99  	protected Map<BlockInteraction, Integer> interactionsToTabindex = new HashMap<BlockInteraction, Integer>();
100 
101 	protected Assessment assessment;
102 
103 	protected static String ITEM_COMPLETED = "ITEM_COMPLETED";
104 
105 	private static int PROMPT_PANEL_WIDTH = 300;
106 	
107 	private static int PROMPT_PANEL_HEIGHT = 300;
108 	
109 	/***
110 	 * 
111 	 */
112 	
113 	public AssessmentUI(){
114 		//dummy constructor
115 		//initUI();
116 	}
117 	
118 	public AssessmentUI(Assessment assessment) {
119 		this.assessment = assessment;
120 		initUI();
121 	}
122 
123 	protected abstract void initUI();
124 
125 	class NextTabAction extends AbstractAction {
126 
127 		public NextTabAction(String title, ImageIcon icon) {
128 			super(title, icon);
129 		}
130 
131 		public void actionPerformed(ActionEvent e) {
132 			tabbedPane.setSelectedIndex(tabbedPane.getSelectedIndex() + 1);
133 			checkTab();
134 		}
135 	}
136 
137 	class PreviousTabAction extends AbstractAction {
138 
139 		public PreviousTabAction(String title, ImageIcon icon) {
140 			super(title, icon);
141 		}
142 
143 		public void actionPerformed(ActionEvent e) {
144 			tabbedPane.setSelectedIndex(tabbedPane.getSelectedIndex() - 1);
145 			checkTab();
146 		}
147 	}
148 
149 	class GetStartedAction extends AbstractAction {
150 
151 		/***
152 		 * 
153 		 */
154 		public GetStartedAction(String title) {
155 			super(title);
156 			// TODO Auto-generated constructor stub
157 		}
158 
159 		public void actionPerformed(ActionEvent e) {
160 			JButton button = (JButton) e.getSource();
161 
162 			ExtendedTextInteraction et = placeholderButtonsToTextInteractions
163 					.get(button);
164 
165 			JTextArea area = textInteractionsToTextareas.get(et);
166 
167 			String textInArea = area.getText();
168 
169 			String placeholderText = et.getPlaceholderText();
170 			StringBuffer buff;
171 			if (placeholderText != null)
172 				buff = new StringBuffer(placeholderText);
173 			else
174 				buff = new StringBuffer();
175 
176 			buff.append(" ").append(textInArea); //$NON-NLS-1$
177 
178 			area.setText(""); //$NON-NLS-1$
179 			area.setText(buff.toString());
180 			button.setEnabled(false);
181 
182 		}// actionPerformed
183 
184 	}
185 
186 	protected void showTabChecked(int selectedTab) {
187 		tabbedPane.setIconAt(selectedTab, checkIcon);
188 		((JComponent) tabbedPane.getComponentAt(selectedTab))
189 				.putClientProperty(ITEM_COMPLETED, new Boolean(true));
190 	}
191 
192 	protected void showTabUnChecked(int selectedTab) {
193 		tabbedPane.setIconAt(selectedTab, null);
194 		((JComponent) tabbedPane.getComponentAt(selectedTab))
195 				.putClientProperty(ITEM_COMPLETED, new Boolean(false));
196 	}
197 
198 	class AssDocumentAdapter implements DocumentListener {
199 
200 		protected ExtendedTextInteraction eti;
201 
202 		public AssDocumentAdapter(ExtendedTextInteraction eti) {
203 			this.eti = eti;
204 		}
205 
206 		public void insertUpdate(DocumentEvent e) {
207 			//this is necessary for a tabbed interface
208 			if(assessment.getTabbed() ) {
209 				showTabChecked(tabbedPane.getSelectedIndex());
210 			}
211 			insertReponses(e);
212 
213 		}
214 
215 		public void removeUpdate(DocumentEvent e) {
216 
217 			Document document = e.getDocument();
218 			if (document.getLength() == 0) {
219 
220 				// find the button and disable it
221 				Set<JButton> keySet = placeholderButtonsToTextInteractions.keySet();
222 
223 				for (Iterator<JButton> iter = keySet.iterator(); iter.hasNext();) {
224 					JButton button = iter.next();
225 					ExtendedTextInteraction newEti = placeholderButtonsToTextInteractions
226 							.get(button);
227 					// we found the button
228 					if (this.eti.equals(newEti)) {
229 
230 						if (eti.getPlaceholderText() != null)
231 							button.setEnabled(true);
232 
233 					}// if
234 
235 				}// for
236 
237 				// Set text color for the new tab
238 				if( assessment.getTabbed() ) {
239 					showTabUnChecked(tabbedPane.getSelectedIndex());
240 				}
241 				// insertReponses(e);
242 			}// if
243 			insertReponses(e);
244 		}
245 
246 		public void changedUpdate(DocumentEvent e) {
247 			// TODO Auto-generated method stub
248 
249 		}
250 
251 		/***
252 		 * @param e
253 		 */
254 		private void insertReponses(DocumentEvent e) {
255 			Document document = e.getDocument();
256 			String responseID = (String) document.getProperty(RESPONSE_ID);
257 			if (responseID == null)
258 				throw new NullPointerException();
259 
260 			String responseText = null;
261 			try {
262 				responseText = document.getText(0, document.getLength());
263 			} catch (BadLocationException e1) {
264 				e1.printStackTrace();
265 			}
266 			assessment.getResponses().put(responseID, responseText);
267 			//don't logg request of aaron
268 			//logger.info(Messages.getString("Note.3") + assessment.getResponses().get(responseID) + Messages.getString("Note.2")); //$NON-NLS-1$ //$NON-NLS-2$
269 		}
270 
271 	}
272 
273 	public boolean isCompleted() {
274 		
275 		if( tabbedPane == null )
276 			return true;
277 		
278 		if( tabbedPane.getComponents() == null)
279 			return true;
280 		
281 		Component[] components = tabbedPane.getComponents();
282 
283 		
284 		
285 		for (int i = 0; i < components.length; i++) {
286 			JComponent component = (JComponent) components[i];
287 			Boolean clientProperty = (Boolean) component
288 					.getClientProperty(ITEM_COMPLETED);
289 			if (clientProperty != null) {
290 				if (clientProperty.booleanValue() == false)
291 					return false;
292 			}// if
293 		}// for
294 
295 		return true;
296 
297 	}
298 
299 	protected void checkTab() {
300 		if(tabbedPane != null){
301 			int numOfTabs = tabbedPane.getTabCount();
302 			int selectedTabIndex = tabbedPane.getSelectedIndex();
303 		
304 			nextTabButton.setToolTipText("Flip to the next tab");
305 			nextTabButton.setEnabled(false);
306 			previousTabButton.setEnabled(false);
307 			previousTabButton.setToolTipText("Flip to the previous tab");
308 
309 			// next button
310 			if ((numOfTabs > 1) && (selectedTabIndex != (numOfTabs - 1))) {
311 				nextTabButton.setEnabled(true);
312 			} else {
313 				nextTabButton.setEnabled(false);
314 			}
315 
316 			// previous button
317 			if ((numOfTabs > 1) && (selectedTabIndex != 0)) {
318 				previousTabButton.setEnabled(true);
319 			} else {
320 				previousTabButton.setEnabled(false);
321 			}// if
322 		}
323 	}
324 
325 	/***
326 	 * @param interaction
327 	 * @param itemIndex
328 	 * @return
329 	 */
330 	protected JPanel createAssessmentItemPanel(
331 			final BlockInteraction interaction) {
332 		if (interaction instanceof ExtendedTextInteraction) {
333 			final ExtendedTextInteraction textInteraction = (ExtendedTextInteraction) interaction;
334 			return createTextInteractionPanel(textInteraction);
335 		} else if (interaction instanceof ChoiceInteraction) {
336 			final ChoiceInteraction<String> choiceInteraction = (ChoiceInteraction<String>) interaction;
337 			return createChoiceInteractionPanel(choiceInteraction);
338 		} else {
339 			throw new IllegalArgumentException("normal BlockeInteraction not supported yet?");
340 		}
341 	}
342 
343 	protected JPanel createChoiceInteractionPanel(
344 			final ChoiceInteraction<String> choiceInteraction) {
345 		JPanel formPanel = new JPanel();
346 
347 		double pref = TableLayout.PREFERRED;
348 		double fill = TableLayout.FILL;
349 		double vSpace = 5;
350 		double hSpace = 6;
351 		double size[][] = { { fill // rt
352 				},
353 
354 				{ pref, vSpace, pref, vSpace, pref }
355 
356 		};
357 		formPanel.setLayout(new TableLayout(size));
358 		formPanel.setOpaque(false);
359 
360 		JComponent promptPanel = createPromptPanel(choiceInteraction);
361 
362 		promptPanel.setBorder(BorderFactory.createEmptyBorder());
363 
364 		formPanel.add(promptPanel, "0,0"); //$NON-NLS-1$
365 
366 		JPanel choiceAreaPanel = createChoiceAreaPanel(choiceInteraction);
367 		choiceAreaPanel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
368 		formPanel.add(choiceAreaPanel, "0,2, l, t");
369 
370 		return formPanel;
371 	}
372 
373 	/***
374 	 * @param choiceInteraction
375 	 * @return
376 	 */
377 	protected JPanel createChoiceAreaPanel(
378 			final ChoiceInteraction<String> choiceInteraction) {
379 
380 		List<JRadioButton> choiceButtonList = new ArrayList<JRadioButton>();
381 		List<SimpleChoice<String>> simpleChoices = choiceInteraction.getSimpleChoices();
382 		ButtonGroup group = new ButtonGroup();
383 		JPanel buttonPanel = new JPanel();
384 		// buttonPanel
385 		// .setBackground(PasColors.noteChoiceInteractionButtonPanelBackgroundColor);
386 		buttonPanel.setOpaque(false);
387 		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
388 		String studentAnswer = Assessment.getStudentAnswer(assessment,
389 				choiceInteraction);
390 		for (SimpleChoice<String> sc : simpleChoices) {
391 			JRadioButton scButton = new JRadioButton();
392 			// if student chose this choice before, mark as selected
393 
394 			if (studentAnswer != null
395 					&& studentAnswer.equals(sc.getIdentifier())) {
396 				scButton.setSelected(true);
397 			} else {
398 				scButton.setSelected(false);
399 			}
400 			scButton.setOpaque(false);
401 			scButton.putClientProperty(QTIUtils.SIMPLE_CHOICE, sc);
402 			scButton.putClientProperty(RESPONSE_ID, choiceInteraction
403 					.getResponseIdentifier());
404 			scButton.addActionListener(new ActionListener() {
405 
406 				public void actionPerformed(ActionEvent e) {
407 					JRadioButton radioButton = (JRadioButton) e.getSource();
408 
409 					if (radioButton.isSelected()) {
410 						SimpleChoice<String> sc = ((SimpleChoice<String>) radioButton
411 								.getClientProperty(QTIUtils.SIMPLE_CHOICE));
412 
413 						assessment.getResponses().put(
414 								(String) radioButton
415 										.getClientProperty(RESPONSE_ID),
416 								sc.getIdentifier());
417 
418 						System.out.println("responses: "
419 								+ assessment.getResponses().toString());
420 						if(tabbedPane != null)
421 							showTabChecked(tabbedPane.getSelectedIndex());
422 					}
423 				}
424 			});
425 			scButton.setText((String) sc.getContent());
426 
427 			// choicebutton
428 			choiceButtonList.add(scButton);
429 			buttonPanel.add(scButton);
430 
431 			group.add(scButton);
432 		}// for
433 		buttonPanel.add(Box.createVerticalStrut(10));
434 		choiceInteractionToChoiceButtonLists.put(choiceInteraction,
435 				choiceButtonList);
436 		
437 		
438 		
439 		
440 		return buttonPanel;
441 
442 	}
443 
444 	/***
445 	 * @param textInteraction
446 	 * @return
447 	 */
448 	private JPanel createTextInteractionPanel(
449 			final ExtendedTextInteraction textInteraction) {
450 
451 		JPanel formPanel = new JPanel();
452 		formPanel.setBorder(BorderFactory.createEmptyBorder());
453 		double pref = TableLayout.PREFERRED;
454 		double fill = TableLayout.FILL;
455 		double vSpace = 5;
456 		double hSpace = 6;
457 		double size[][] = { { fill // rt
458 				},
459 
460 				{ pref, vSpace, pref, vSpace, fill }
461 
462 		};
463 
464 		JComponent promptPanel = createPromptPanel(textInteraction);
465 
466 		promptPanel.setBorder(BorderFactory.createEmptyBorder());
467 
468 		// JPanel s = new JPanel(new BorderLayout(0,0));
469 		//		
470 		// s.add(promptPanel,BorderLayout.NORTH);
471 		// return s;
472 		//		
473 		String placeholderText = textInteraction.getPlaceholderText();
474 
475 		JComponent textAreaPanel = createTextAreaPanel(textInteraction);
476 		textAreaPanel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
477 
478 		formPanel.setLayout(new TableLayout(size));
479 		formPanel.setOpaque(false);
480 
481 		formPanel.add(promptPanel, "0,0"); //$NON-NLS-1$
482 
483 		
484 		if( showPlaceHolderPanel ) {
485 		
486 			if (placeholderText != null
487 					|| StringUtils.trimToNull(placeholderText) != null) {
488 				if( assessment.isInjectPrompt()  ) {
489 					formPanel.add(textAreaPanel, "0,2");
490 				} else {
491 					JPanel getStartedButtonPanel = createGetStartedButtonPanel(textInteraction);
492 					getStartedButtonPanel.setBorder(BorderFactory.createEmptyBorder(0,
493 							4, 0, 0));
494 					formPanel.add(getStartedButtonPanel, "0,2"); //$NON-NLS-1$
495 					formPanel.add(textAreaPanel, "0,4");
496 				}
497 	//			JTextArea answerArea = getAnswerArea(textInteraction);
498 	//			answerArea.setText(placeholderText);
499 	//			answerArea.revalidate();
500 			} else {
501 				formPanel.add(textAreaPanel, "0,2");
502 			}// if
503 		} else {
504 			//these are for student assessments
505 			formPanel.add(textAreaPanel, "0,2");
506 		}
507 		JPanel t = new JPanel(new BorderLayout(0, 0));
508 		t.add(formPanel, BorderLayout.NORTH);
509 
510 		return t;
511 
512 	}
513 
514 	/***
515 	 * @param textInteraction
516 	 * @param itemIndex
517 	 * @return
518 	 */
519 	private JComponent createTextAreaPanel(
520 			ExtendedTextInteraction textInteraction) {
521 
522 		JTextArea answerArea = getAnswerArea(textInteraction);
523 
524 		String studentAnswer = Assessment.getStudentAnswer(assessment,
525 				textInteraction);
526 
527 		String placeholderText = textInteraction.getPlaceholderText();
528 		
529 		if (studentAnswer != null) {
530 			answerArea.setText(studentAnswer);
531 		} else {
532 			if (placeholderText != null || StringUtils.trimToNull(placeholderText) != null) {
533 				if( assessment.isInjectPrompt() ) {
534 					answerArea.setText(placeholderText);
535 				}// if
536 			}
537 		}
538 		// ds
539 		textInteractionsToTextareas.put(textInteraction, answerArea);
540 
541 		int expectedLines = textInteraction.getExpectedLines();
542 
543 		if (expectedLines == 0) {
544 			answerArea.setRows(10);
545 		} else {
546 			answerArea.setRows(expectedLines);
547 		}// if
548 
549 		answerArea.setColumns(35);
550 
551 		answerArea.getDocument().putProperty(RESPONSE_ID,
552 				answerArea.getClientProperty(RESPONSE_ID));
553 
554 		answerArea.getDocument().addDocumentListener(
555 				new AssDocumentAdapter(textInteraction));
556 
557 		JScrollPane spane = getScrollPane(answerArea);
558 
559 		return spane;
560 	}
561 
562 	/***
563 	 * @param answerArea
564 	 * @return
565 	 */
566 	private JScrollPane getScrollPane(JTextArea answerArea) {
567 		JScrollPane spane = new JScrollPane(answerArea);
568 		spane.setOpaque(false);
569 		spane
570 				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
571 		spane
572 				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
573 		spane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
574 		spane.getVerticalScrollBar().getModel().setValue(
575 				spane.getVerticalScrollBar().getModel().getMinimum());
576 		spane.setPreferredSize(new Dimension(answerArea
577 				.getPreferredScrollableViewportSize().width, answerArea
578 				.getPreferredScrollableViewportSize().height + 5));
579 		// spane.setViewportView(answerArea);
580 
581 		spane.requestFocusInWindow();
582 		// spane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
583 		return spane;
584 	}
585 
586 	/***
587 	 * @param textInteraction
588 	 * @return
589 	 */
590 	private JTextArea getAnswerArea(ExtendedTextInteraction textInteraction) {
591 		JTextArea answerArea = new JTextArea();
592 		answerArea.setName(textInteraction.getResponseIdentifier());
593 		// answerArea.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
594 		answerArea.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
595 
596 		// CommonUI.makeMultilineLabel(answerArea);
597 
598 		answerArea.putClientProperty(RESPONSE_ID, textInteraction
599 				.getResponseIdentifier());
600 		answerArea.setFocusable(true);
601 		answerArea.requestFocusInWindow();
602 		answerArea.setEditable(true);
603 		answerArea.setBorder(CommonUI.createEtchedBorder());
604 		answerArea.setOpaque(true);
605 		answerArea.setWrapStyleWord(true);
606 		answerArea.setLineWrap(true);
607 		answerArea.setFocusCycleRoot(true);
608 		return answerArea;
609 	}
610 
611 	/***
612 	 * @param textInteraction
613 	 * @return
614 	 */
615 	private JPanel createGetStartedButtonPanel(
616 			ExtendedTextInteraction textInteraction) {
617 		JPanel startedPanel = new JPanel(new BorderLayout(0, 0));
618 		startedPanel.setOpaque(false);
619 		
620 		JButton showPlaceholderButton = new JButton(new GetStartedAction(Messages.getString("Note.GET_STARTED"))); //$NON-NLS-1$;
621 		
622 		CommonUI.makeButtonTransparent(showPlaceholderButton);
623 		CommonUI.makeLink(showPlaceholderButton);
624 
625 	
626 		startedPanel.add(showPlaceholderButton, BorderLayout.WEST);
627 		placeholderButtonsToTextInteractions.put(showPlaceholderButton,
628 				textInteraction);
629 
630 		return startedPanel;
631 	}
632 
633 	/***
634 	 * @param formPanel
635 	 * @param textI
636 	 * @return
637 	 * @return
638 	 */
639 	public static JComponent createPromptPanel(BlockInteraction blockInteraction) {
640 
641 		if (blockInteraction == null)
642 			return new JLabel("There was an error creating this prompt.");
643 
644 		final XHTMLPanel panel = new XHTMLPanel();
645 		panel.setName("promptPanel");
646 	//	panel.setAntiAliased(true);
647 		//panel.setFontScalingFactor(3f);
648 		panel.setOpaque(false);
649 		panel.addComponentListener(new ComponentListener() {
650 
651 			public void componentHidden(ComponentEvent e) {
652 				// TODO Auto-generated method stub
653 
654 			}
655 
656 			public void componentMoved(ComponentEvent e) {
657 				// TODO Auto-generated method stub
658 
659 			}
660 
661 			public void componentResized(ComponentEvent e) {
662 				//panel.relayout();
663 
664 			}
665 
666 			public void componentShown(ComponentEvent e) {
667 				// TODO Auto-generated method stub
668 
669 			}
670 		});
671 
672 		// System.out.println("HTML TO PRINT: " + blockInteraction.getPrompt());
673 
674 		InputStream stream = null;
675 		try {
676 			stream = IOUtils.toInputStream(blockInteraction.getPrompt());
677 			panel.setDocument(stream, null);
678 		} catch (NullPointerException e) {
679 			e.printStackTrace();
680 		} catch (Exception e) {
681 			e.printStackTrace();
682 		} finally {
683 			IOUtils.closeQuietly(stream);
684 		}
685 
686 //		panel.setPreferredSize(new Dimension(PROMPT_PANEL_WIDTH, PROMPT_PANEL_HEIGHT));
687 //		panel.setMaximumSize(panel.getPreferredSize());
688 		return panel;
689 
690 	}
691 
692 	public static JComponent createIntroTextPanel(String introText) {
693 
694 		if (introText == null)
695 			return new JLabel("There is no introductory text.");
696 
697 		final XHTMLPanel panel = new XHTMLPanel();
698 		panel.setName("introPanel");
699 		//panel.setAntiAliased(true);
700 		//panel.setFontScalingFactor(3f);
701 		panel.setOpaque(false);
702 		panel.addComponentListener(new ComponentListener() {
703 
704 			public void componentHidden(ComponentEvent e) {
705 				// TODO Auto-generated method stub
706 
707 			}
708 
709 			public void componentMoved(ComponentEvent e) {
710 				// TODO Auto-generated method stub
711 
712 			}
713 
714 			public void componentResized(ComponentEvent e) {
715 				//panel.relayout();
716 
717 			}
718 
719 			public void componentShown(ComponentEvent e) {
720 				// TODO Auto-generated method stub
721 
722 			}
723 		});
724 
725 		// System.out.println("HTML TO PRINT: " + blockInteraction.getPrompt());
726 
727 		InputStream stream = null;
728 		try {
729 			stream = IOUtils.toInputStream(introText);
730 			panel.setDocument(stream, null);
731 		} catch (NullPointerException e) {
732 			e.printStackTrace();
733 		} catch (Exception e) {
734 			e.printStackTrace();
735 		} finally {
736 			IOUtils.closeQuietly(stream);
737 		}
738 
739 //		panel.setPreferredSize(new Dimension(PROMPT_PANEL_WIDTH, PROMPT_PANEL_HEIGHT));
740 //		panel.setMaximumSize(panel.getPreferredSize());
741 		return panel;
742 
743 	}
744 
745 
746 	/***
747 	 * @return the tabbedPane
748 	 */
749 	public JTabbedPane getTabbedPane() {
750 		return tabbedPane;
751 	}
752 
753 	/***
754 	 * @param tabbedPane
755 	 *            the tabbedPane to set
756 	 */
757 	public void setTabbedPane(JTabbedPane tabbedPane) {
758 		this.tabbedPane = tabbedPane;
759 	}
760 
761 }