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