001 /* PAVLOV -- Multiple Choice Study System
002 * Copyright (C) 2000 - 2004 T.J. Willis
003 *
004 * This program is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU General Public License
006 * as published by the Free Software Foundation; either version 2
007 * of the License, or (at your option) any later version.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, write to the Free Software
016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
017 *
018 * $Header: /cvsroot/pavlov/net/sourceforge/pavlov/pluglets/feedback/random/RandomImage.java,v 1.9 2004/07/01 05:50:20 tj_willis Exp $
019 */
020 package net.sourceforge.pavlov.pluglets.feedback.random;
021
022
023 import javax.swing.*;
024 import java.awt.Dimension;
025 import java.awt.event.*;
026 import java.net.URL;
027
028 import net.sourceforge.pavlov.event.*;
029 import net.sourceforge.pavlov.randommedia.RandomImageFactory;
030 import net.sourceforge.pavlov.randommedia.ImageIconUtilities;
031 import net.sourceforge.pavlov.feedback.old.*;
032 //import net.sourceforge.pavlov.user.Bookmark;
033 import net.sourceforge.pavlov.user.User;
034 import net.sourceforge.pavlov.randommedia.CacheObject;
035 import net.sourceforge.pavlov.event.MediaRootChangedListener;
036 import net.sourceforge.pavlov.zipUtilities.DirectoryJarFileFilter;
037 import net.sourceforge.pavlov.swing.HashtableJRadioButtonMenu;
038 import org.apache.log4j.*;
039
040 /**
041 * <code>RandomImage</code> is a concrete example of a user feedback module.
042 * @author <a href="mailto:"></a>
043 * @version $Revision: 1.9 $
044 */
045 public class RandomImage extends AbstractFeedbackPanel
046 implements AnswerListener, ActionListener, MediaRootChangedListener {
047 //protected JLabel txt;
048 public static final String PLUGLET_FEEDBACK_IMAGE_RANDOM = "pluglet.feedback.image.random";
049 public static final String PLUGLET_FEEDBACK_IMAGE_RANDOM_DESCRIPTION = "pluglet.feedback.image.random.description";
050
051 /**
052 * Describe variable <code>size</code> here.
053 *
054 */
055 protected int size = -1;
056 /**
057 * Describe variable <code>logo</code> here.
058 *
059 */
060 protected Icon logo;
061 /**
062 * Describe variable <code>rights</code> here.
063 *
064 */
065 protected int rights = 0;
066 /**
067 * Describe variable <code>ifac</code> here.
068 *
069 */
070 protected RandomImageFactory ifac;
071 /**
072 * Describe variable <code>mode</code> here.
073 *
074 */
075 protected DefaultVisualFeedbackMode mode;
076 /**
077 * Describe variable <code>beginner</code> here.
078 *
079 */
080 protected BeginnerFeedbackMode beginner;
081 /**
082 * Describe variable <code>intermed</code> here.
083 *
084 */
085 protected IntermediateFeedbackMode intermed;
086 /**
087 * Describe variable <code>expert</code> here.
088 *
089 */
090 protected ExpertFeedbackMode expert;
091 /**
092 * Describe variable <code>cacheObject</code> here.
093 *
094 */
095 protected CacheObject cacheObject;
096 /**
097 * Describe variable <code>screenSize</code> here.
098 *
099 */
100 protected Dimension screenSize;
101 /**
102 * Describe variable <code>scroller</code> here.
103 *
104 */
105 protected JScrollPane scroller;
106 /**
107 * Describe variable <code>refreshItem</code> here.
108 *
109 */
110 protected JMenuItem refreshItem;
111 /**
112 * Describe variable <code>chooseItem</code> here.
113 *
114 */
115 protected JMenuItem chooseItem;
116 /**
117 * Describe variable <code>begin</code> here.
118 *
119 */
120 protected JMenuItem begin;
121 /**
122 * Describe variable <code>inter</code> here.
123 *
124 */
125 protected JMenuItem inter;
126 /**
127 * Describe variable <code>adv</code> here.
128 *
129 */
130 protected JMenuItem adv;
131 /**
132 * Describe variable <code>pix</code> here.
133 *
134 */
135 protected HashtableJRadioButtonMenu pix;
136 /**
137 * Describe variable <code>menu</code> here.
138 *
139 */
140 protected JMenuBar menu;
141 // FIXME: minimize access
142 ButtonGroup bg;
143
144 private Category cat
145 = Category.getInstance(RandomImage.class.getName());
146
147 // FIXME: I ported this class in a hurry and it's crap-tastic.
148 /**
149 * Describe <code>setFeedbackMode</code> method here.
150 *
151 * @param i an <code>int</code> value
152 * @deprecated
153 */
154 @Deprecated public void setFeedbackMode(int i) {
155 if (i == 1) mode = intermed;
156 else if (i == 2) mode = expert;
157 else mode = beginner;
158
159 makeTitle();
160
161 if (size != -1) mode.setSize(size);
162 else size = mode.getSize();
163 }
164
165 /**
166 * Describe <code>setFeedbackMode</code> method here.
167 *
168 * @param m a <code>DefaultVisualFeedbackMode</code> value
169 */
170 public void setFeedbackMode(DefaultVisualFeedbackMode m)
171 {
172 mode = m;
173 makeTitle();
174
175 if (size != -1) mode.setSize(size);
176 else size = mode.getSize();
177 }
178
179 /**
180 * Creates a new <code>RandomImage</code> instance.
181 *
182 */
183 public RandomImage() {
184 super();
185
186 beginner = new BeginnerFeedbackMode();
187 intermed = new IntermediateFeedbackMode();
188 expert = new ExpertFeedbackMode();
189 setFeedbackMode(0);
190
191 imageLabel.setHorizontalAlignment(SwingConstants.CENTER);
192 imageLabel.setVerticalAlignment(SwingConstants.CENTER);
193 //ImageIcon la = ImageIconUtilities.getNamedImageIcon("file:resources/visualFeedback.jpg");
194 //imageLabel.setIcon(la);
195
196 //enableEvents(java.awt.Event.WINDOW_DESTROY);
197
198 setBackground(java.awt.Color.white);
199 super.setImageSize(mode.getSize());
200 screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
201
202
203 menu = new JMenuBar();
204 setJMenuBar(menu);
205 makeModeMenu();
206
207 pack();
208 }
209
210 /**
211 * Describe <code>getName</code> method here.
212 *
213 * @return a <code>String</code> value
214 */
215
216 public String getName(){ return rb.getString(PLUGLET_FEEDBACK_IMAGE_RANDOM,"Random Images"); }
217 /**
218 * Describe <code>getDescription</code> method here.
219 *
220 * @return a <code>String</code> value
221 */
222 public String getDescription(){ return rb.getString(PLUGLET_FEEDBACK_IMAGE_RANDOM_DESCRIPTION,"Shows random pictures, which get bigger when you answer correctly"); }
223 /**
224 * Describe <code>getDirectoryName</code> method here.
225 *
226 * @return a <code>String</code> value
227 */
228 public String getDirectoryName() { return "/resources/images";}
229
230
231
232 /**
233 * Describe <code>start</code> method here.
234 *
235 */
236 public void start()
237 {
238 if(ifac==null)
239 {
240 ifac = new RandomImageFactory( getDirectoryName());
241 ifac.addMediaRootChangedListener(this);
242 }
243 setNumberOfActiveItems(ifac.getNumberOfEnabledItems());
244 if(pix==null) makeImageBaseMenu();
245 }
246
247 /**
248 * Describe <code>resetPicture</code> method here.
249 *
250 */
251 protected void resetPicture() {
252
253 if(!jCheckBox1.isSelected() || cacheObject==null)
254 cacheObject = ifac.getRandomCacheObject();
255
256 if(cacheObject==null) return;
257 ImageIcon tmp2 = (ImageIcon)cacheObject.object;
258 ImageIcon tmp = ImageIconUtilities.formatImage(tmp2, size);
259
260 if(tmp!=null)
261 {
262 imageLabel.setIcon(tmp);
263 makeTitle();
264 }
265 }
266
267 /**
268 * Sets the window title to "mode: filename"
269 *
270 */
271 protected void makeTitle() {
272 String x = null;
273 if(cacheObject!=null)
274 x = cacheObject.getFileShortName();
275
276 if (x != null)
277 super.setTitle(mode.getShortName() + " : " + x);
278 else
279 super.setTitle(mode.getShortName());
280 }
281
282 /**
283 * Describe <code>answerEvent</code> method here.
284 *
285 * @param e an <code>AnswerEvent</code> value
286 */
287 public void answerEvent(AnswerEvent e) {
288 if(!isVisible()) return;
289
290 if (e.isCorrect()) mode.rightEvent();
291 else mode.wrongEvent();
292 size = mode.getSize();
293
294 setImageSize(size);
295 resetPicture();
296
297 String msg = "<HTML>";
298 msg += mode.getMessage();
299 setMessage(msg);
300 if(cacheObject!=null)
301 {
302 setDirectoryName(cacheObject.getDirectoryName());
303 }
304 pack();
305 }
306
307 /**
308 * Describe <code>setMessage</code> method here.
309 *
310 * @param pre a <code>String</code> value
311 */
312 protected void setMessage(String pre)
313 {
314 String msg = "";
315 msg += pre;
316 if(cacheObject!=null)
317 msg += "From : " + cacheObject.getDirectoryName() +"<BR>\n";;
318
319 setImageSize(size);
320 }
321
322 /**
323 * Describe <code>actionPerformed</code> method here.
324 *
325 * @param e a <code>java.awt.event.ActionEvent</code> value
326 */
327 public void actionPerformed(java.awt.event.ActionEvent e) {
328 if (e.getSource().equals(refreshItem)) {
329 ifac.refresh();
330 } else if (e.getSource().equals(chooseItem)) {
331 JFileChooser chooser = new JFileChooser(ifac.getRootDirectory());
332 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
333 DirectoryJarFileFilter filt = new DirectoryJarFileFilter();
334 chooser.setFileFilter(filt);
335 int returnVal = chooser.showOpenDialog(this);
336 if(returnVal == JFileChooser.APPROVE_OPTION) {
337 ifac.setRootDirectory(chooser.getSelectedFile() );
338 makeImageBaseMenu();
339 }
340 ifac.refresh();
341 } else if (e.getSource().equals(begin)){
342 setFeedbackMode(0);
343 } else if (e.getSource().equals(inter)){
344 setFeedbackMode(1);
345 } else if (e.getSource().equals(adv)){
346 setFeedbackMode(2);
347 } else {
348 super.actionPerformed(e);
349 }
350 }
351
352 /**
353 * Called when user selects a new base directory/JAR for images.
354 *
355 */
356 public void mediaRootChanged()
357 {
358 cat.debug("rand: Got mediarootchanged event");
359 setNumberOfActiveItems(ifac.getNumberOfEnabledItems());
360 }
361
362 /**
363 * Creates the Beginner/Intermediate/Advanced mode Menu.
364 *
365 */
366 protected void makeModeMenu()
367 {
368 JMenu modes = new JMenu("Mode");
369 begin = new JRadioButtonMenuItem("Beginner",true);
370 inter = new JRadioButtonMenuItem("Intermediate");
371 adv = new JRadioButtonMenuItem("Advanced");
372 bg = new ButtonGroup();
373 bg.add(begin);
374 bg.add(inter);
375 bg.add(adv);
376 modes.add(begin);
377 modes.add(inter);
378 modes.add(adv);
379 begin.addActionListener(this);
380 inter.addActionListener(this);
381 adv.addActionListener(this);
382 menu.add(modes);
383 }
384
385 /**
386 * Creates a menu allowing the user to select or refresh the base directory * or JAR file for images.
387 *
388 */
389 protected void makeImageBaseMenu()
390 {
391 assert ifac!=null: "Image Factory is null";
392 if(menu!=null && pix!=null)
393 menu.remove(pix);
394
395 pix = new HashtableJRadioButtonMenu("Images",true);
396 refreshItem = new JMenuItem("Refresh ImageBase");
397 refreshItem.addActionListener(this);
398 pix.add(refreshItem);
399
400 chooseItem = new JMenuItem("Choose ImageBase...");
401 chooseItem.addActionListener(this);
402 pix.add(chooseItem);
403
404 pix.addSeparator();
405
406 String opts[] = ifac.getSubDirectoryNames();
407
408 pix.addAllAsJRadioButtonMenuItems(opts, ifac);
409
410 int sz = java.lang.reflect.Array.getLength(opts);
411
412 for (int i = 0; i < sz; i++) {
413 if (ifac.isDirectoryEnabled(opts[i])) pix.setSelected(opts[i], true);
414 }
415 menu.add(pix);
416 }
417
418
419 /**
420 * Describe <code>getResourcePath</code> method here.
421 *
422 * @param in a <code>String</code> value
423 * @return a <code>String</code> value
424 */
425 public String getResourcePath(String in)
426 {
427 Class cl = this.getClass();
428 URL tst = cl.getResource(in);
429 cat.debug("base resource dir is" + tst);
430 if(tst==null) return null;
431 return tst.getPath();
432 }
433
434 /**
435 * Describe <code>setSticky</code> method here.
436 *
437 * FIXME: broke sticky images in 1.0 push.
438 * @param s a <code>boolean</code> value
439 */
440 public void setSticky(boolean s) {
441 //sticky = s;
442 }
443 }
444
445
446
447
448
449
450
451
452
453
454
455