[sword-cvs] r24 - in trunk/app/src/org/crosswire: common common/swing flashcards

Apache apache at crosswire.org
Wed Sep 15 06:46:53 MST 2004


Author: 
Date: 2004-09-15 06:46:53 -0700 (Wed, 15 Sep 2004)
New Revision: 24

Added:
   trunk/app/src/org/crosswire/common/swing/
   trunk/app/src/org/crosswire/common/swing/FixedSplitPane.java
   trunk/app/src/org/crosswire/flashcards/SetupPane.java
Modified:
   trunk/app/src/org/crosswire/flashcards/Editor.java
   trunk/app/src/org/crosswire/flashcards/EditorFrame.java
   trunk/app/src/org/crosswire/flashcards/FlashCard.java
   trunk/app/src/org/crosswire/flashcards/Lesson.java
   trunk/app/src/org/crosswire/flashcards/LessonManager.java
   trunk/app/src/org/crosswire/flashcards/LessonSet.java
   trunk/app/src/org/crosswire/flashcards/MainFrame.java
   trunk/app/src/org/crosswire/flashcards/MainMenu.java
   trunk/app/src/org/crosswire/flashcards/Quiz.java
Log:
Made use of new lesson classes added flip option

Added: trunk/app/src/org/crosswire/common/swing/FixedSplitPane.java
===================================================================
--- trunk/app/src/org/crosswire/common/swing/FixedSplitPane.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/common/swing/FixedSplitPane.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -0,0 +1,197 @@
+package org.crosswire.common.swing;
+
+import java.awt.Component;
+import java.awt.Dimension;
+
+import javax.swing.JComponent;
+import javax.swing.JSplitPane;
+
+/**
+ * This is a hack to fix the setDividerLocation problem and other layout problems.
+ * <p>
+ * See Bug Parade 4101306, 4485465 for a description of the WIDE divider problem.
+ * <p>
+ * Bug Reports on JSplitpane setDividerLocation<br>
+ * 4101306, 4125713, 4148530
+ *<p>
+ * From the javadoc for setDividerLocation(double):
+ * -------------------------------------------<br>
+ * <p>This method is implemented in terms of setDividerLocation(int).
+ * This method immediately changes the size of the receiver based on
+ * its current size. If the receiver is not correctly realized and on
+ * screen, this method will have no effect (new divider location will
+ * become (current size * proportionalLocation) which is 0).<br>
+ * -------------------------------------------<br>
+ * So, as you can see the JSplitPane MUST be visible invoking this method
+ * otherwise it will not have the desired effect.
+ * <p>
+ * Another, Bug Report 4786896 notes that if the preferred sizes of the
+ * two components plus the divider of the split pane adds up to more than
+ * the preferred size of the JSplitPane, then JSplitPane will use the
+ * minimum size of the components.
+ * <p>
+ * Since the preferred way of managing the sizes of containers is not with
+ * pixel counts, the solution here is to set the preferred size to zero.
+ * 
+ * <p><table border='1' cellPadding='3' cellSpacing='0'>
+ * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
+ *
+ * Distribution Licence:<br />
+ * JSword is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.<br />
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.<br />
+ * The License is available on the internet
+ * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA<br />
+ * The copyright to this program is held by it's authors.
+ * </font></td></tr></table>
+ * @see gnu.gpl.Licence
+ * @author Joe Walker [joe at eireneh dot com]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ * @version $Id: FixedSplitPane.java,v 1.3 2004/09/08 19:54:24 dmsmith Exp $
+ */
+public class FixedSplitPane extends JSplitPane
+{
+    /**
+     * Constructor for FixedSplitPane
+     */
+    public FixedSplitPane()
+    {
+        super();
+    }
+
+    /**
+     * Constructor for FixedSplitPane
+     */
+    public FixedSplitPane(int arg0)
+    {
+        super(arg0);
+    }
+
+    /**
+     * Constructor for FixedSplitPane
+     */
+    public FixedSplitPane(int arg0, boolean arg1)
+    {
+        super(arg0, arg1);
+    }
+
+    /**
+     * Constructor for FixedSplitPane
+     */
+    public FixedSplitPane(int arg0, Component arg1, Component arg2)
+    {
+        super(arg0, arg1, arg2);
+    }
+
+    /**
+     * Constructor for FixedSplitPane
+     */
+    public FixedSplitPane(int arg0, boolean arg1, Component arg2, Component arg3)
+    {
+        super(arg0, arg1, arg2, arg3);
+    }
+
+    /* (non-Javadoc)
+     * @see java.awt.Container#addImpl(java.awt.Component, java.lang.Object, int)
+     */
+    protected void addImpl(Component comp, Object constraints, int index)
+    {
+        if (comp instanceof JComponent)
+        {
+            ((JComponent) comp).setPreferredSize(DOT);
+        }
+        super.addImpl(comp, constraints, index);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.swing.JSplitPane#setBottomComponent(java.awt.Component)
+     */
+    public void setBottomComponent(Component comp)
+    {
+        if (comp instanceof JComponent)
+        {
+            ((JComponent) comp).setPreferredSize(DOT);
+        }
+        super.setBottomComponent(comp);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.swing.JSplitPane#setLeftComponent(java.awt.Component)
+     */
+    public void setLeftComponent(Component comp)
+    {
+        if (comp instanceof JComponent)
+        {
+            ((JComponent) comp).setPreferredSize(DOT);
+        }
+        super.setLeftComponent(comp);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.swing.JSplitPane#setRightComponent(java.awt.Component)
+     */
+    public void setRightComponent(Component comp)
+    {
+        if (comp instanceof JComponent)
+        {
+            ((JComponent) comp).setPreferredSize(DOT);
+        }
+        super.setRightComponent(comp);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.swing.JSplitPane#setTopComponent(java.awt.Component)
+     */
+    public void setTopComponent(Component comp)
+    {
+        if (comp instanceof JComponent)
+        {
+            ((JComponent) comp).setPreferredSize(DOT);
+        }
+        super.setTopComponent(comp);
+    }
+
+    /**
+     * Validates this container and all of its subcomponents. The first time
+     * this method is called, the initial divider position is set.
+     */
+    public void validate()
+    {
+        if (firstValidate)
+        {
+            firstValidate = false;
+            if (hasProportionalLocation)
+            {
+                setDividerLocation(proportionalLocation);
+            }
+        }
+        super.validate();
+    }
+
+    /**
+     * Sets the divider location as a percentage of the JSplitPane's size.
+     */
+    public void setDividerLocation(double newProportionalLocation)
+    {
+        if (!firstValidate)
+        {
+            hasProportionalLocation = true;
+            proportionalLocation = newProportionalLocation;
+        }
+        else
+        {
+            super.setDividerLocation(newProportionalLocation);
+        }
+    }
+
+    private static final Dimension DOT = new Dimension(0, 0);
+    private boolean firstValidate = true;
+    private boolean hasProportionalLocation;
+    private double proportionalLocation;
+}

Modified: trunk/app/src/org/crosswire/flashcards/Editor.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Editor.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/Editor.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -48,9 +48,9 @@
     //
 
     // ---------------
-    public Editor( boolean standAlone ) {
+    public Editor(LessonManager lessonManager, boolean standAlone ) {
 
-        EditorFrame frame = new EditorFrame( standAlone );
+        EditorFrame frame = new EditorFrame(lessonManager, standAlone );
 
         //Validate frames that have preset sizes
         //Pack frames that have useful preferred size info, e.g. from their layout
@@ -108,7 +108,7 @@
 
         }
 
-        new Editor( true );
+        new Editor(new LessonManager(), true );
 
     }
 

Modified: trunk/app/src/org/crosswire/flashcards/EditorFrame.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/EditorFrame.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/EditorFrame.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -65,6 +65,7 @@
 
 public class EditorFrame extends JFrame {
 
+    private LessonManager lessonManager;
     //
     // Attributes
     //
@@ -120,8 +121,8 @@
     //
 
     // ---------------
-    public EditorFrame( boolean standAlone ) {
-
+    public EditorFrame(LessonManager lessonManager, boolean standAlone ) {
+        this.lessonManager = lessonManager;
         this.standAlone = standAlone;
         enableEvents( AWTEvent.WINDOW_EVENT_MASK );
 

Modified: trunk/app/src/org/crosswire/flashcards/FlashCard.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/FlashCard.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/FlashCard.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -52,6 +52,21 @@
     }
 
     /**
+     * Get a particular side of this FlashCard.
+     * This is useful to flip the cards.
+     * @param front
+     * @return the requested side
+     */
+    public String getSide(boolean front)
+    {
+        if (front)
+        {
+            return getFront();
+        }
+        return getBack();
+    }
+
+    /**
      * @return Returns the back.
      */
     public String getBack()

Modified: trunk/app/src/org/crosswire/flashcards/Lesson.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Lesson.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/Lesson.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -127,9 +127,17 @@
     public int compareTo(Object obj)
     {
         Lesson lesson = (Lesson) obj;
-        return description.compareTo(lesson.description);
+        return filename.compareTo(lesson.filename);
     }
 
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return description;
+    }
+
     /**
      * Load this lesson from persistent store named by the lesson's <code>filename</code>.
      */

Modified: trunk/app/src/org/crosswire/flashcards/LessonManager.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/LessonManager.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/LessonManager.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -21,25 +21,20 @@
 package org.crosswire.flashcards;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.JarURLConnection;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
-import javax.swing.JCheckBox;
-
 import org.crosswire.common.CWClassLoader;
-import org.crosswire.common.ResourceUtil;
 
 /**
  * The <code>LessonManager</code> provides the management of <code>LessonSet</code>s.
@@ -49,10 +44,20 @@
  */
 public class LessonManager implements Comparable
 {
-    public LessonManager(String dirname)
+    public LessonManager()
     {
-        this.dirname = dirname;
-        lessonSets = new ArrayList();
+        lessonSets = new TreeSet();
+        try
+        {
+            String path = System.getProperty("user.home") + File.separator + DIR_PROJECT; //$NON-NLS-1$
+            URL home = new URL(FILE_PROTOCOL, null, path);
+            CWClassLoader.setHome(home);
+        }
+        catch (MalformedURLException e1)
+        {
+            assert false;
+        }
+        load();
     }
 
     /**
@@ -66,21 +71,6 @@
     }
 
     /**
-     * Removes the <code>LessonSet</code> at the specified position in this list.
-     * Shifts any subsequent FlashCards to the left (subtracts one from their
-     * indices).
-     *
-     * @param index the index of the Lesson to removed.
-     * @return the Lesson that was removed from the list.
-     * @throws    IndexOutOfBoundsException if index out of range <tt>(index
-     * 		  &lt; 0 || index &gt;= size())</tt>.
-     */
-    public LessonSet remove(int index)
-    {
-        return (LessonSet) lessonSets.remove(index);
-    }
-
-    /**
      * @return Returns the description.
      */
     public String getDescription()
@@ -96,22 +86,6 @@
         description = newDescription;
     }
 
-    /**
-     * @return Returns the dirname.
-     */
-    public String getDirname()
-    {
-        return dirname;
-    }
-
-    /**
-     * @param dirname The dirname to set.
-     */
-    public void setDirname(String newFilename)
-    {
-        dirname = newFilename;
-    }
-
     /* (non-Javadoc)
      * @see java.lang.Comparable#compareTo(java.lang.Object)
      */
@@ -122,7 +96,7 @@
     }
 
     /**
-     * Load this lesson from persistent store named by the lesson's <code>dirname</code>.
+     * Load this lesson from persistent store named by the lesson's <code>LESSON_ROOT</code>.
      */
     public void load()
     {
@@ -137,7 +111,7 @@
     {
 
         // Dig into the jar for lessonSets
-        URL lessonsURL = this.getClass().getResource('/' + dirname);
+        URL lessonsURL = this.getClass().getResource('/' + LESSON_ROOT);
         if (lessonsURL == null)
         {
             return;
@@ -172,7 +146,7 @@
                     String entryName = jarEntry.getName();
                     // remove trailing '/'
                     entryName = entryName.substring(0, entryName.length() - 1);
-                    if (entryName.startsWith(dirname) && ! entryName.equals(dirname))
+                    if (entryName.startsWith(LESSON_ROOT) && ! entryName.equals(LESSON_ROOT))
                     {
                         // let the description be just the directory name and not the path
                         add(new LessonSet(entryName, entryName.substring(entryName.indexOf('/') + 1)));
@@ -189,7 +163,7 @@
     {
         try
         {
-            URL dirURL = CWClassLoader.getHomeResource(dirname);
+            URL dirURL = CWClassLoader.getHomeResource(LESSON_ROOT);
             File directory = new File(dirURL.getFile());
             File[] files = directory.listFiles();
             if (files == null)
@@ -214,7 +188,7 @@
     }
     
     /**
-     * Save all the modified lesson sets to persistent store named by the lesson's <code>dirname</code>.
+     * Save all the modified lesson sets to persistent store named by the lesson's <code>LESSON_ROOT</code>.
      */
     public void store()
     {
@@ -229,11 +203,15 @@
         }
     }
 
-    /**
-     * The <code>dirname</code> of the lesson
-     */
-    private String dirname;
+    public Iterator iterator()
+    {
+        return lessonSets.iterator();
+    }
 
+    public static final String LESSON_ROOT = "lessons";
+    private static final String DIR_PROJECT = ".flashcards";
+    private static final String FILE_PROTOCOL = "file";
+
     /**
      * A <code>description</code> of the lesson to be displayed to the user.
      */
@@ -242,5 +220,5 @@
     /**
      * An ordered list of <code>lessonSets</code>
      */
-    private List lessonSets;
+    private Set lessonSets;
 }
\ No newline at end of file

Modified: trunk/app/src/org/crosswire/flashcards/LessonSet.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/LessonSet.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/LessonSet.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -109,6 +109,13 @@
         return description.compareTo(lesson.description);
     }
 
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return description;
+    }
     /**
      * Load this lesson set from persistent store named by the lesson set's <code>dirname</code>.
      * This is the union of lessons in the Jar and in the user's flashcard home directory.
@@ -117,13 +124,6 @@
     {
         loadJarLessons();
         loadHomeLessons();
-        Iterator iter = lessons.iterator();
-        while (iter.hasNext())
-        {
-            String lessonPath = (String) iter.next();
-            String lessonDescription = getLessonDescription(lessonPath);
-            add(new Lesson(lessonPath, lessonDescription));
-        }
     }
 
     /**
@@ -169,10 +169,11 @@
             while (entries.hasMoreElements())
             {
                 JarEntry jarEntry = (JarEntry) entries.nextElement();
-                String entryName = jarEntry.getName();
-                if (entryName.startsWith(dirname) && ! jarEntry.isDirectory())
+                String lessonPath = jarEntry.getName();
+                if (lessonPath.startsWith(dirname) && ! jarEntry.isDirectory())
                 {
-                    lessons.add(entryName);
+                    String lessonDescription = getLessonDescription(lessonPath);
+                    add(new Lesson(lessonPath, lessonDescription));
                 }
             }
         }
@@ -204,7 +205,8 @@
                 lessonPath = lessonPath.replace('\\', '/');
                 int offset = lessonPath.indexOf(dirname);
                 lessonPath = lessonPath.substring(offset, lessonPath.length());
-                lessons.add(lessonPath);
+                String lessonDescription = getLessonDescription(lessonPath);
+                add(new Lesson(lessonPath, lessonDescription));
             }
         }
         catch (Exception e)
@@ -270,6 +272,11 @@
         }
         return false;
     }
+    
+    public Iterator iterator()
+    {
+        return lessons.iterator();
+    }
 
     /**
      * The <code>dirname</code> of the lesson

Modified: trunk/app/src/org/crosswire/flashcards/MainFrame.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/MainFrame.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/MainFrame.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -6,7 +6,7 @@
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * 
+ *
  * See the GNU General Public License for more details.
  * The License is available on the internet at:
  *     http://www.gnu.org/copyleft/gpl.html,
@@ -14,7 +14,7 @@
  *     Free Software Foundation, Inc.
  *     59 Temple Place - Suite 330
  *     Boston, MA 02111-1307, USA
- * 
+ *
  * The copyright to this program is held by it's authors
  * Copyright: 2004
  */
@@ -22,6 +22,7 @@
 
 import java.awt.AWTEvent;
 import java.awt.BorderLayout;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.GridLayout;
@@ -29,46 +30,33 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ItemEvent;
 import java.awt.event.WindowEvent;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.JarURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
 import java.util.Vector;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
 
 import javax.swing.BorderFactory;
+import javax.swing.DefaultListModel;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JComponent;
-import javax.swing.JFileChooser;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
+import javax.swing.JList;
 import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
 import javax.swing.JTabbedPane;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
 import javax.swing.SwingConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
 
-import org.crosswire.common.CWClassLoader;
-import org.crosswire.common.ResourceUtil;
 
 public class MainFrame extends JFrame {
+  LessonManager lessonManager;
   JPanel contentPane;
   JLabel statusBar = new JLabel();
   BorderLayout borderLayout1 = new BorderLayout();
@@ -77,66 +65,66 @@
   BorderLayout borderLayout2 = new BorderLayout();
   JPanel choicesPanel = new JPanel();
   JTabbedPane jTabbedPane1 = new JTabbedPane();
-  JPanel jPanel4 = new JPanel();
+  JPanel testPanel = new JPanel();
   BorderLayout borderLayout3 = new BorderLayout();
-  JPanel setupPanel = new JPanel();
-  JPanel jPanel6 = new JPanel();
-  BorderLayout borderLayout4 = new BorderLayout();
-  JLabel jLabel2 = new JLabel();
-  JLabel lessonDirectory = new JLabel();
-  JButton jButton2 = new JButton();
-  BorderLayout borderLayout5 = new BorderLayout();
-  JPanel lessonPanel = new JPanel();
-  JButton jButton1 = new JButton();
+  JButton startLessonButton = new JButton();
   Vector words = new Vector();
   Vector notLearned = new Vector();
   WordEntry currentWord = null;
   int wrong = 0;
   int totalAsked = 0;
   int totalWrong = 0;
-  JButton jButton3 = new JButton();
+  JButton showAnswerButton = new JButton();
   BorderLayout borderLayout6 = new BorderLayout();
   boolean shownAnswer = false;
   JLabel wordText = new JLabel();
-  Hashtable lessons = new Hashtable();
   GridLayout gridLayout1 = new GridLayout();
-  GridLayout gridLayout2 = new GridLayout();
   JPanel jPanel3 = new JPanel();
   BorderLayout borderLayout7 = new BorderLayout();
   JLabel wCount = new JLabel();
-  Map lessonSets = new LinkedHashMap();
-  private static final String LESSON_ROOT = "lessons";
-  private static final String DIR_PROJECT = ".flashcards";
-  private static final String FILE_PROTOCOL = "file";
   private MainMenu mainMenu;
+  private SetupPane setupPane;
+  private JCheckBox flipSideCheckBox = new JCheckBox("Flip Flash Cards");
 
-  static class WordEntry {
-    public WordEntry(String word) { this.word = word; }
-    public WordEntry(String word, String answers) { this(word); this.answers = answers; }
-    public String word;
-    public String answers;
-    public int attempts = 0;
-    public String toString() {
-      return word;
-    }
-  }
+  	static class WordEntry
+    {
+        public WordEntry(FlashCard flashCard)
+        {
+            this.flashCard = flashCard;
+        }
 
+        public void incrementFailures(int failures)
+        {
+            attempts += failures;
+        }
 
-    //Construct the frame
-    public MainFrame()
-    {
-        try
+        public int getFailures()
         {
-            String path = System.getProperty("user.home") + File.separator + DIR_PROJECT; //$NON-NLS-1$
-            URL home = new URL(FILE_PROTOCOL, null, path);
-            CWClassLoader.setHome(home);
+            return attempts;
         }
-        catch (MalformedURLException e1)
+
+        public String getSide(boolean front)
         {
-            assert false;
+            return flashCard.getSide(front);
         }
 
+        public String toString()
+        {
+            return flashCard.getFront();
+        }
+        private FlashCard flashCard;
+        private int attempts;
+    }
+
+
+    //Construct the frame
+    public MainFrame(LessonManager lessonManager)
+    {
+        this.lessonManager = lessonManager;
         enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+        mainMenu = new MainMenu(lessonManager, this );
+        setJMenuBar( mainMenu );
+        setupPane = new SetupPane(lessonManager);
         try
         {
             jbInit();
@@ -145,9 +133,8 @@
         {
             e.printStackTrace();
         }
-        mainMenu = new MainMenu( this );
-        setJMenuBar( mainMenu );
     }
+
   //Component initialization
   private void jbInit() throws Exception  {
     contentPane = (JPanel) this.getContentPane();
@@ -157,24 +144,14 @@
     statusBar.setBorder(BorderFactory.createEtchedBorder());
     statusBar.setText(" ");
     jPanel2.setLayout(borderLayout2);
-    jPanel4.setLayout(borderLayout3);
-    setupPanel.setLayout(borderLayout4);
-    jLabel2.setMaximumSize(new Dimension(140, 14));
-    jLabel2.setMinimumSize(new Dimension(140, 14));
-    jLabel2.setPreferredSize(new Dimension(140, 14));
-    jLabel2.setText("Lesson Directory");
-    jButton2.setText("...");
-    jButton2.addActionListener(new MainFrame_jButton2_actionAdapter(this));
-    jPanel6.setLayout(borderLayout5);
-    lessonDirectory.setText("");
-    lessonPanel.setLayout(gridLayout2);
+    testPanel.setLayout(borderLayout3);
     choicesPanel.setLayout(gridLayout1);
-    jButton1.setText("Start");
-    jButton1.addActionListener(new MainFrame_jButton1_actionAdapter(this));
-    jButton3.setFocusPainted(true);
-    jButton3.setMnemonic('A');
-    jButton3.setText("Show Answer");
-    jButton3.addActionListener(new MainFrame_jButton3_actionAdapter(this));
+    startLessonButton.setText("Start");
+    startLessonButton.addActionListener(new MainFrame_jButton1_actionAdapter(this));
+    showAnswerButton.setFocusPainted(true);
+    showAnswerButton.setMnemonic('A');
+    showAnswerButton.setText("Show Answer");
+    showAnswerButton.addActionListener(new MainFrame_jButton3_actionAdapter(this));
     jPanel1.setLayout(borderLayout6);
     wordText.setBackground(SystemColor.text);
     wordText.setFont(new java.awt.Font("Dialog", 0, 30));
@@ -185,35 +162,26 @@
     wordText.setHorizontalTextPosition(SwingConstants.CENTER);
     gridLayout1.setColumns(3);
     gridLayout1.setRows(0);
-    gridLayout2.setColumns(2);
-    gridLayout2.setRows(0);
     jPanel3.setLayout(borderLayout7);
     wCount.setBorder(BorderFactory.createEtchedBorder());
     contentPane.add(jTabbedPane1,  BorderLayout.CENTER);
-    jTabbedPane1.add(jPanel4,  "Test");
-    jPanel4.add(jPanel2, BorderLayout.CENTER);
-    jPanel4.add(jPanel1,  BorderLayout.NORTH);
-    jPanel4.add(jPanel3,  BorderLayout.SOUTH);
+    jTabbedPane1.addTab("Test", testPanel);
+    testPanel.add(jPanel2, BorderLayout.CENTER);
+    testPanel.add(jPanel1,  BorderLayout.NORTH);
+    testPanel.add(jPanel3,  BorderLayout.SOUTH);
     jPanel3.add(statusBar, BorderLayout.CENTER);
     jPanel3.add(wCount,  BorderLayout.EAST);
-    jTabbedPane1.add(setupPanel,  "Setup");
-    setupPanel.add(jPanel6, BorderLayout.NORTH);
-    jPanel6.add(jLabel2, BorderLayout.WEST);
-    jPanel6.add(lessonDirectory, BorderLayout.CENTER);
-    jPanel6.add(jButton2, BorderLayout.EAST);
-    setupPanel.add(lessonPanel, BorderLayout.CENTER);
+    jTabbedPane1.addTab("Setup", setupPane);
+
     jPanel2.add(choicesPanel,  BorderLayout.CENTER);
     jPanel2.add(wordText,  BorderLayout.NORTH);
-    jPanel1.add(jButton1, BorderLayout.WEST);
-    jPanel1.add(jButton3,  BorderLayout.EAST);
+    jPanel1.add(startLessonButton, BorderLayout.WEST);
+    jPanel1.add(flipSideCheckBox,  BorderLayout.CENTER);
+    jPanel1.add(showAnswerButton,  BorderLayout.EAST);
 
-
-    loadLessons(LESSON_ROOT);
-    jTabbedPane1.setSelectedComponent(setupPanel);
+    jTabbedPane1.setSelectedIndex(1);
   }
 
-
-
   //Overridden so we can exit when window is closed
   protected void processWindowEvent(WindowEvent e) {
     super.processWindowEvent(e);
@@ -222,259 +190,66 @@
     }
   }
 
-
   public void deleteChildren(JComponent c) {
     while (c.getComponentCount() > 0)
       c.remove(c.getComponent(0));
   }
 
-  public void loadLessons(String directoryPath) {
-      deleteChildren(lessonPanel);
-      lessonSets.clear();
-      loadJarLessons(directoryPath);
-      loadHomeLessons(directoryPath);
-      loadWidgets();
-  }
-  
-  private void loadJarLessons(String directoryPath)
-  {
-
-      // Dig into the jar for lessons
-      URL lessonsURL = this.getClass().getResource('/' + directoryPath);
-      URLConnection connection = null;
-      try
+  public void loadTest() {
+//    boolean loadedFont = false;
+    words = new Vector();
+    Iterator lessonIter = setupPane.iterator();
+    while (lessonIter.hasNext())
+    {
+      Lesson lesson = (Lesson) lessonIter.next();
+      Iterator cardIter = lesson.iterator();
+      while (cardIter.hasNext())
       {
-          connection = lessonsURL.openConnection();
+          words.add(new WordEntry((FlashCard)cardIter.next()));
       }
-      catch (Exception e1)
-      {
-          assert false;
-      }
-      if (connection instanceof JarURLConnection)
-      {
-          JarURLConnection jarConnection = (JarURLConnection) connection;
-          JarFile jarFile = null;
-          try
-          {
-              jarFile = jarConnection.getJarFile();
-          }
-          catch (IOException e2)
-          {
-              assert false;
-          }
-          Enumeration entries = jarFile.entries();
-          Set lessonSet = null;
-          while (entries.hasMoreElements())
-          {
-              JarEntry jarEntry = (JarEntry) entries.nextElement();
-              String entryName = jarEntry.getName();
-              if (entryName.startsWith(directoryPath))
-              {
-                  if (jarEntry.isDirectory())
-                  {
-                      lessonSet = new TreeSet();
-                      // remove trailing '/'
-                      lessonSets.put(entryName.substring(0, entryName.length() - 1), lessonSet);
-                  }
-                  else
-                  {
-                      lessonSet.add(entryName);
-                  }
-              }
-          }
-      }
-  }
-  
-  private void loadHomeLessons(String directoryPath)
-  {
-    try {
-      List files = new ArrayList();
-      File childFile = new File(directoryPath);
-      directoryPath = childFile.getParent();
-      getFileListing(new File(directoryPath), files);
-      Collections.sort(files);
-      Iterator iter = files.iterator();
-      Set lessonSet = null;
-      while (iter.hasNext())
-      {
-          File file = (File) iter.next();
-          File parent = file.getParentFile();
-          String parentPath = parent.getPath().replace('\\', '/');
-          if (lessonSets.containsKey(parentPath))
-          {
-              lessonSet = (Set) lessonSets.get(parentPath);
-          }
-          else
-          {
-              lessonSet = new TreeSet();
-          }
-          String filePath = file.getPath().replace('\\', '/');
-          lessonSet.add(filePath);
-      }
-    }
-    catch (Exception e) {
-	// that's fine.  We just failed to load local files.
-    }
-  }
-
-  private void loadWidgets()
-  {
-      lessons = new Hashtable();
-      Iterator iter = lessonSets.values().iterator();
-      while (iter.hasNext())
-      {
-          Set lessonSet = (Set) iter.next();
-          Iterator lessonIterator = lessonSet.iterator();
-          while (lessonIterator.hasNext())
-          {
-            String lessonName = (String) lessonIterator.next();
-            URL lessonURL = ResourceUtil.getResource(lessonName);
-            Properties p = new Properties();
-            try {
-                p.load(lessonURL.openConnection().getInputStream());
-            }
-            catch (IOException ex) {
-            }
-          JCheckBox ck = new JCheckBox(p.getProperty("lessonTitle"), false);
-          lessonPanel.add(ck, null);
-          lessons.put(ck, lessonURL);
-          }
-      }
-/*
- * This code (or something like it) is for the future and shows how to use ResourceBundles.
- * The extension on the files needs to be changed from .flash to .properties
- * and the name given to getBundle is not to contain .properties.
- */
-//      Locale defaultLocale = Locale.getDefault();
-//      while (iter.hasNext())
-//      {
-//          lessonSet = (Set) iter.next();
-//          Iterator lessonIterator = lessonSet.iterator();
-//          while (lessonIterator.hasNext())
-//          {
-//              String lessonName = (String) lessonIterator.next();
-//              try
-//              {
-//                  ResourceBundle resources = ResourceBundle.getBundle(lessonName, defaultLocale, new CWClassLoader());
-//                  JCheckBox ck = new JCheckBox(resources.getString("lessonTitle"), false);
-//                  lessonPanel.add(ck, null);
-//                  lessons.put(ck, resources);
-//              }
-//              catch (MissingResourceException ex)
-//              {
-//                  System.err.println("Cannot get resource " + lessonName + ":lessonTitle"); //$NON-NLS-1$ //$NON-NLS-2$
-//              }
+//      if (!loadedFont) {
+//        String font = lesson.getFont();
+//        if (font.length() > 1) {
+//          try {
+//            loadFont(new FileInputStream(font));
+//            loadedFont = true;
 //          }
+//          catch (FileNotFoundException ex) {
+//          }
+//        }
 //      }
-      this.pack();
-  }
-  /**
-   * Recursively walk a directory tree and return a List of all
-   * Files found; the List is sorted using File.compareTo.
-   *
-   * @param aStartingDir is a valid directory, which can be read.
-   */
-  public void getFileListing(File aStartingDir, List result) {
-       // look for files that are either directories or end with .flash
-      File[] filesAndDirs = aStartingDir.listFiles(new FilenameFilter() {
-          public boolean accept(File dir, String name) {
-              if (name.endsWith(".flash"))
-              {
-                  return true;
-              }
-              File testFile = new File(dir.getName() + File.separator + name);
-              return testFile.isDirectory();
-          }
-      });
-      if (filesAndDirs == null)
-      {
-          return;
-      }
-      for (int i = 0; i < filesAndDirs.length; i++)
-      {
-          File file = filesAndDirs[i];
-          if (file.isDirectory()) {
-              // dig deeper
-              getFileListing(file, result);
-          } else {
-              // Add only files
-              result.add(file);
-          }
-      }
-  }
 
-  void jButton2_actionPerformed(ActionEvent e) {
-    JFileChooser dialog = new JFileChooser();
-    dialog.setCurrentDirectory(new File("./"));
-    if (dialog.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
-      lessonDirectory.setText(dialog.getSelectedFile().getParentFile().getAbsolutePath());
-      loadLessons(lessonDirectory.getText());
     }
   }
 
-  public void loadLessons() {
-    boolean loadedFont = false;
-    words = new Vector();
-    for (int l = 0; l < lessonPanel.getComponentCount(); l++) {
-      Properties lesson = new Properties();
-      JCheckBox ck = (JCheckBox)lessonPanel.getComponent(l);
-      if (!ck.isSelected())
-        continue;
-      try {
-        URL lessonURL = (URL)lessons.get(ck);
-        lesson.load(lessonURL.openConnection().getInputStream());
-      }
-      catch (Exception e1) {
-        e1.printStackTrace();
-      }
-      int wordCount = Integer.parseInt(lesson.getProperty("wordCount"));
-      for (int i = 0; i < wordCount; i++) {
-        words.add(new WordEntry(lesson.getProperty("word" + Integer.toString(i)),
-                                lesson.getProperty("answers" +
-            Integer.toString(i))));
-      }
-      if (!loadedFont) {
-        String font = lesson.getProperty("font", "");
-        if (font.length() > 1) {
-          try {
-            loadFont(new FileInputStream(font));
-            loadedFont = true;
-          }
-          catch (FileNotFoundException ex) {
-          }
-        }
-      }
+//  public void loadFont(InputStream is) {
+//    try {
+//        statusBar.setText("Loading font...");
+//        statusBar.paintImmediately(statusBar.getVisibleRect());
+//        Font font = Font.createFont(Font.TRUETYPE_FONT, is);
+//        Font newFont = font.deriveFont((float)18.0);
+//        wordText.setFont(newFont);
+//        is.close();
+//        statusBar.setText("New Font Loaded.");
+//    }
+//    catch (Exception ex) { ex.printStackTrace(); }
+//  }
 
-    }
-  }
-
-
-  public void loadFont(InputStream is) {
-    try {
-        statusBar.setText("Loading font...");
-        statusBar.paintImmediately(statusBar.getVisibleRect());
-        Font font = Font.createFont(Font.TRUETYPE_FONT, is);
-        Font newFont = font.deriveFont((float)18.0);
-        wordText.setFont(newFont);
-        is.close();
-        statusBar.setText("New Font Loaded.");
-    }
-    catch (Exception ex) { ex.printStackTrace(); }
-  }
-
-
-
-
   void jButton1_actionPerformed(ActionEvent e) {
-    loadLessons();
+    loadTest();
     notLearned = (Vector)words.clone();
     totalAsked = 0;
     totalWrong = 0;
     showRandomWord(currentWord);
   }
 
-
   public void showRandomWord(WordEntry last) {
+    deleteChildren(choicesPanel);
+    int numToLearn = notLearned.size();
+    if (numToLearn == 0)
+    {
+        return;
+    }
     while (currentWord == last) {
       int wordNum = (int) (Math.random() * notLearned.size());
       currentWord = (WordEntry) notLearned.get(wordNum);
@@ -485,15 +260,15 @@
 
   public void showWord(WordEntry w) {
     currentWord = w;
-    wordText.setText(w.word);
+    wordText.setText(w.getSide(!flipSideCheckBox.isSelected()));
     Vector choices = (Vector)words.clone();
     choices.remove(w);
-    deleteChildren(choicesPanel);
+//    deleteChildren(choicesPanel);
     int size = choices.size();
     for (int i = 0; ((i < 9) && (size > 0)); i++) {
       int c = (int)(Math.random() * size);
       WordEntry wc = (WordEntry)choices.get(c);
-      JCheckBox ck = new JCheckBox(wc.answers, false);
+      JCheckBox ck = new JCheckBox(wc.getSide(flipSideCheckBox.isSelected()), false);
       choicesPanel.add(ck, null);
       ck.addItemListener(new MainFrame_answer_itemAdapter(this));
       choices.remove(wc);
@@ -501,11 +276,11 @@
     }
     int correct = (int)(Math.random() * choicesPanel.getComponentCount());
     JCheckBox ck = (JCheckBox)choicesPanel.getComponent(correct);
-    ck.setText(w.answers);
+    ck.setText(w.getSide(flipSideCheckBox.isSelected()));
     wrong = 0;
     shownAnswer = false;
     updateStats();
-    this.pack();
+//    this.pack();
     choicesPanel.repaint();
   }
 
@@ -523,7 +298,7 @@
     JCheckBox ck = (JCheckBox)e.getItem();
     if (ck.isSelected()) {
       totalAsked++;
-      if (ck.getText().compareTo(currentWord.answers) != 0) {
+      if (ck.getText().compareTo(currentWord.getSide(flipSideCheckBox.isSelected())) != 0) {
         statusBar.setText(ck.getText() + " is not correct.  Please try again.");
         wrong++;
         totalWrong++;
@@ -533,10 +308,10 @@
         if (notLearned.size() > 1) {
           statusBar.setText("Correct.  Try this next word");
           if (wrong > 0) {
-            currentWord.attempts += wrong;
+              currentWord.incrementFailures(wrong);
           }
-          else currentWord.attempts--;
-          if (currentWord.attempts < 0) {
+          else currentWord.incrementFailures(-1);
+          if (currentWord.getFailures() < 0) {
             notLearned.remove(currentWord);
           }
           showRandomWord(currentWord);
@@ -557,7 +332,7 @@
   public void showAnswer() {
     for (int i = 0; i < choicesPanel.getComponentCount(); i++) {
       JCheckBox ck = (JCheckBox)choicesPanel.getComponent(i);
-      if (ck.getText() == currentWord.answers) {
+      if (ck.getText() == currentWord.getSide(flipSideCheckBox.isSelected())) {
         ck.setFont(new Font(ck.getFont().getName(), Font.BOLD|Font.ITALIC, ck.getFont().getSize()));
         break;
       }
@@ -571,25 +346,17 @@
       return;
     }
     int next = notLearned.indexOf(currentWord) + 1;
+    if (next == 0)
+    {
+        return;
+    }
     if (next >= notLearned.size())
       next = 0;
+    deleteChildren(choicesPanel);
     showWord((WordEntry)notLearned.get(next));
     showAnswer();
   }
-}
 
-
-
-
-class MainFrame_jButton2_actionAdapter implements java.awt.event.ActionListener {
-  MainFrame adaptee;
-
-  MainFrame_jButton2_actionAdapter(MainFrame adaptee) {
-    this.adaptee = adaptee;
-  }
-  public void actionPerformed(ActionEvent e) {
-    adaptee.jButton2_actionPerformed(e);
-  }
 }
 
 class MainFrame_jButton1_actionAdapter implements java.awt.event.ActionListener {

Modified: trunk/app/src/org/crosswire/flashcards/MainMenu.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/MainMenu.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/MainMenu.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -43,6 +43,7 @@
 
 class MainMenu extends JMenuBar {
 
+    private LessonManager lessonManager;
     //
     // Attributes
     //
@@ -55,8 +56,8 @@
     //
 
     // ---------------
-    MainMenu( JFrame frame ) {
-
+    MainMenu(LessonManager lessonManager, JFrame frame ) {
+        this.lessonManager = lessonManager;
         this.frame = frame;
 
         JMenu menu1, menu2;
@@ -131,7 +132,7 @@
         public void actionPerformed( ActionEvent event ) {
 
             Debug.trace( this.toString( ), "Beginning\n" );
-            new Editor( false );
+            new Editor( lessonManager, false );
             Debug.trace( this.toString( ), "Ending\n" );
 
         }

Modified: trunk/app/src/org/crosswire/flashcards/Quiz.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Quiz.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/Quiz.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -49,13 +49,14 @@
 
     // ---------------
     public Quiz( ) {
+        
+        LessonManager lm = new LessonManager();
 
-        MainFrame frame = new MainFrame();
+        MainFrame frame = new MainFrame(lm);
 
         // Validate frames that have preset sizes
         // Pack frames that have useful preferred size info,
         // e.g. from their layout
-
         if( packFrame ) { frame.pack( ); }
         else { frame.validate( ); }
 

Added: trunk/app/src/org/crosswire/flashcards/SetupPane.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/SetupPane.java	2004-09-14 20:36:02 UTC (rev 23)
+++ trunk/app/src/org/crosswire/flashcards/SetupPane.java	2004-09-15 13:46:53 UTC (rev 24)
@@ -0,0 +1,211 @@
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * The copyright to this program is held by it's authors
+ * Copyright: 2004
+ */
+package org.crosswire.flashcards;
+
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.util.Iterator;
+
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListModel;
+import javax.swing.JCheckBox;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.crosswire.common.swing.FixedSplitPane;
+
+
+public class SetupPane extends JPanel
+{
+    private LessonManager lessonManager;
+    private JList lessonSetList = new JList(new DefaultListModel());
+    private JList lessonList = new JList(new DefaultListModel());
+
+    //Construct the frame
+    public SetupPane(LessonManager lessonManager)
+    {
+        this.lessonManager = lessonManager;
+        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+        try
+        {
+            jbInit();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public Iterator iterator()
+    {
+        return new SelectedLessonIterator(lessonList);
+    }
+
+    private void jbInit() throws Exception
+    {
+        setLayout(new BorderLayout());
+        JPanel lessonPanel = new JPanel(new BorderLayout());
+        lessonPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "Lessons: "));
+        lessonPanel.add(new JScrollPane(lessonList));
+//        lessonList.setCellRenderer(new CheckBoxListCellRenderer());
+        lessonSetList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        lessonSetList.addListSelectionListener(new LessonSetSelectionListener(lessonList));
+
+        JPanel lessonSetPanel = new JPanel(new BorderLayout());
+        lessonSetPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "Lesson Sets: "));
+        lessonSetPanel.add(new JScrollPane(lessonSetList), BorderLayout.CENTER);
+
+        JSplitPane splitPane = new FixedSplitPane();
+        splitPane.setResizeWeight(0.3D);
+        splitPane.setDividerLocation(0.3D);
+        splitPane.setRightComponent(lessonPanel);
+        splitPane.setLeftComponent(lessonSetPanel);
+
+        add(splitPane);
+
+        loadLessonSets();
+    }
+
+    private void loadLessonSets()
+    {
+        Iterator lessonSetIterator = lessonManager.iterator();
+        while (lessonSetIterator.hasNext())
+        {
+            LessonSet lessonSet = (LessonSet) lessonSetIterator.next();
+            DefaultListModel model = (DefaultListModel) lessonSetList.getModel();
+            model.addElement(lessonSet);
+        }
+    }
+
+    /**
+     * Iterator over the selections in a JList
+     */
+    private static class SelectedLessonIterator implements Iterator
+    {
+
+        public SelectedLessonIterator(JList list)
+        {
+            model = (DefaultListModel) list.getModel();
+            selectedIndexes = list.getSelectedIndices();
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#remove()
+         */
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#hasNext()
+         */
+        public boolean hasNext()
+        {
+            return currentIndex < selectedIndexes.length;
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#next()
+         */
+        public Object next()
+        {
+            return model.get(currentIndex++);
+        }
+
+        private int[] selectedIndexes;
+        private DefaultListModel model;
+        private int currentIndex;
+    }
+    /**
+     * When a <code>LessonSet</code> is loaded this listener will populate the lessonList
+     * with the <code>Lesson</code>s.
+     */
+    private static class LessonSetSelectionListener implements ListSelectionListener
+    {
+
+        /**
+         * Create a listener that populates the lessonList with lessons.
+         * @param lessonList the list to populate
+         */
+        public LessonSetSelectionListener(JList lessonList)
+        {
+            this.lessonList = lessonList;
+        }
+
+        /* (non-Javadoc)
+         * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
+         */
+        public void valueChanged(ListSelectionEvent e)
+        {
+            if (e.getValueIsAdjusting())
+            {
+                return;
+            }
+            JList list = (JList) e.getSource();
+            LessonSet lessonSet = (LessonSet) list.getSelectedValue();
+            DefaultListModel model = (DefaultListModel) lessonList.getModel();
+            model.clear();
+            if (lessonSet != null)
+            {
+                Iterator lessonIterator = lessonSet.iterator();
+                while (lessonIterator.hasNext())
+                {
+                    Lesson lesson = (Lesson) lessonIterator.next();
+                    model.addElement(lesson);
+                }
+            }
+        }
+        private JList lessonList;
+    }
+
+    /**
+     * This renderer shows selection with a check box instead of shading the row.
+     */
+    private static class CheckBoxListCellRenderer extends JCheckBox implements ListCellRenderer
+    {
+        public CheckBoxListCellRenderer()
+        {
+            // So it looks like it is a row in a list, we need to show the background of the list
+            // and not the checkbox.
+            setOpaque(false);
+        }
+
+        /* (non-Javadoc)
+         * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean)
+         */
+        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
+        {
+            setSelected(isSelected);
+            setText(value.toString());
+            setFocusPainted(cellHasFocus);
+            return this;
+        }
+
+    }
+}
\ No newline at end of file



More information about the sword-cvs mailing list