[sword-devel] Flashcards and vocab word conversion

Troy A. Griffitts scribe at crosswire.org
Tue Sep 14 21:31:36 MST 2004

Hey DM,
	Thanks so much for your work.  You're not a good example for me.  I 
find the more I procrastinate, the more work gets done!  The web 
installer has been a great benefit!

	Just started third semester Greek, and first semester Hebrew.  The 
flashcards app is really a blessing to me.  I have a bunch of vocab 
words for Hebrew that I need to try to convert for use with flashcards. 
  They are in some strange font (maybe BHebrew encoding), that I need to 
try to convert.

	If anyone is up for an attempt, the files are at:


	Any other flash lessons, like Mounce's Greek textbook would also be 
very useful for other students, I'm sure!

	You guys all rock!  Thank you for contributing your time to the Kingdom!



DM Smith wrote:
> Troy, I added 4 new classes that may prove useful:
> FlashCard.java - The individual test.
> Lesson.java - A named set of FlashCards
> LessonSet.java - A named set of Lessons.
> LessonManager.java - a manager of LessonSets.
> These are not hooked into anything.
> They are thrown together fairly quickly, and may have bugs, but I have 
> done some of testing.
> How it works:
> Create a LessonMgr and then call load() to get all the lessons into 
> core. Call store() and it will write all modified lessons to a home 
> account.
> Thebasic  idea is to create a LessonMgr in Quiz.java and in Editor.java 
> and pass it to MainFrame.java and to EditorFrame.java. When 
> MainFrame.java creates an EditorFrame, it will pass its LessonMgr to it.
> I have also added a copyright notice to the top of every file. I used 
> the copyright from JSword and changed JSword to FlashCards. If this is 
> not correct, it can be changed.
> DM Smith wrote:
>> Sorry for the delay in answering. Just got back from a weekend holiday.
>> Troy, I am going to be fairly complete. Probably much of this you have 
>> figured out by now or already knew. My goal in doing this is that 
>> FlashCards is your baby and I want you to have full knowledge of what 
>> I have done. So that you will feel fairly comfortable with the changes.
>> The CWClassLoader finds resources using a fairly sophisticated lookup 
>> mechanism so that you will not have to create your own.
>> Here is the basic history, design and implementation of CWClassLoader 
>> and ResourceUtil: (This should help to answer your question)
>> Java's basis mechanism for lookup is either explicit (i.e. I know 
>> where the file is so I construct a path name from what is known.) or 
>> implicit (i.e. use the class path to look for the file.) The latter 
>> mechanism was that if you called classObj.getResource(xyz), it had one 
>> of two behaviors. If the name began with a '/' the resource would be 
>> sought for along the classpath. If it did not it was looked for in the 
>> same directory as the definition of the class object.
>> Since the program could be installed anywhere, we initially supplied a 
>> shell script (bat file) that would start up the program. Relative to 
>> that directory, we had a resource directory where all resources were 
>> kept. The path of the resource directory was passed into the program 
>> and it was put on the classpath. With this we could either use 
>> explicit lookup or call getResource using '/'.
>> For JSword, the resources were initially being kept in files that had 
>> dotted names like files in packages:
>> E.g. org.crosswire.jsword.book.BibleInfo.properties
>> The purpose of this was to allow a developer to easily change the 
>> properties. It was also the place where the program maintained 
>> persistent performance data that was used for the progress meters.
>> When we went to WebStart, a couple of things happened. First, we could 
>> not write to the resource directory. So we had to have a different 
>> location. Second, since webstart requires all resources to be held in 
>> signed jars, the developer could not modify the resources. Third, we 
>> had no idea where WebStart would store the program, so we could not 
>> pass in the installation location. Fourth, we no longer had control 
>> over the classpath that was created and could not add an arbitrary 
>> directory location.
>> We had worked out a way that we could use getResource to find a 
>> resource, but now needed to also explicitly look for it in the file 
>> system as well. So we wrote code that first looked in ~/.jsword and 
>> then in the jars. This was all well and good, but when we went to 
>> internationalize the program, we had to treat the property files as 
>> ResourceBundles. And ResourceBundles always use a class loader to find 
>> resources. So we had to migrate the lookup to a ClassLoader and use it.
>> So, in a nutshell here is how it works. Lets say that you have a 
>> resource called lessonA.flash that is used by 
>> org.crosswire.flashcards.Reader. If CWClassLoader is used to find 
>> lessons/black/lessonA.flash via ResourceUtil.getResource(). It will 
>> look for the file in the following places with the following names:
>> First look for it relative to the package:
>> 1) org.crosswire.flashcards.lessons.black.lessonA.flash in ~/.flashcards
>> 2) org.crosswire.flashcards.lessons.black.lessonA.flash in a jar
>> Then look for it relative to the root of the classpath:
>> 3) lessons.black.lessonA.flash in ~/.flashcards
>> 4) lessons.black.lessonsA.flash in the a jar
>> Finally look for it as a file:
>> 5)  lessons/black/lessonA.flash in ~/.flashcards
>> 6) lessons/black/lessonA.flash in the jar
>> That is, it manages the lookup for you.
>> To have it look in ~/.flashcards the program needs to do the 
>> following: (Assume DIR_PROJECT is .flashcards)
>>            String path = System.getProperty("user.home") + 
>> File.separator + DIR_PROJECT; //$NON-NLS-1$
>>            URL home = new URL(FILE_PROTOCOL, null, path);
>>            CWClassLoader.setHome(home);
>> If two different programs (Quiz and Editor) work on the same location, 
>> then both programs need to have these three lines.
>> The twist that FlashCards has that is not present in JSword, it that 
>> JSword merely looks up a known resource, but FlashCards discovers what 
>> resources it has available. FlashCards then has the additional step of 
>> creating a map of discovered resources. When it discovers the resource 
>> it does not remember whether it was found in the filesystem or in the 
>> jar. It lets the ResourceUtil.getResource figure that out at that time.
>> So in looking at the code you will find that it looks for lessons thusly
>> It first digs into the jar to get lessons with getJarLessons. Since 
>> these are not located in org.crosswire.flashcards, a '/' is prefixed.
>> Then it looks in the file system with getHomeLessons.
>> As it gets the lessons, they are stored by their path. Then by their 
>> URL with the widget.
>> Now if one of these lessons is loaded into the Editor, it may have 
>> come from the jar or it may have come from the filesystem. It really 
>> does not matter. ResourceUtil.getResource will sort it out. When the 
>> file is written out, it will need to be saved in the filesystem. Any 
>> URLs that are remembered for the resource will have to be updated. 
>> (Right now each checkbox remembers the URL. If this were to change to 
>> being the path, then no place would need to be adjusted.)
>> So here are the changes I see that the program needs to have done to 
>> make it work with what it has:
>> 1) Add CWClassLoader.setHome to EditorFrame so it will work in stand 
>> alone mode.
>> 2) change the JFileChoosers to look in CWClassLoader.getHome() (i.e. 
>> line 213 in MainFrame, 45 and 62 in EditorFrame)
>> 3) Store the path on the widget (i.e. a String and not an URL) and do 
>> the lookup for the URL when the lesson is loaded.
>> At this time, the program assumes that the lessons are in a 
>> subdirectory of a "lessons" directory. So some thought may want to be 
>> put into whether this is a good restriction or not. If so, the user 
>> really does not need to open a JFileChooser, they could either pick an 
>> existing lesson to edit or create one from scratch by naming the 
>> lesson set (e.g. black) and the lesson (e.g. lesson01vocab). The 
>> program would be responsible for converting this to a path and writing 
>> it to the file system.
>> If the user can write to any location then CWClassLoader would need to 
>> change setHome to setHomePath and each location would need to be 
>> stored in a persistent location so it could be remembered the next run.
>> I would also suggest a change to the setup screen, where the name of 
>> the lesson set is pickable (JComboBox or JList would do). When it is 
>> picked, then a list of lessons is populated. I suggest having a 
>> scrollable JList of the checkboxes.
>> The trick would be to have the JComboBox listen for the creation of 
>> new lesson sets and the lesson listing to update when they are added, 
>> deleted or renamed or reordered. I suggest the Observer pattern using 
>> a LessonEditEvent and a LessonEditEventListener.
>> As I "broke" the editing function, I would be willing to help in 
>> whatever way you wish.
>> Hope this helps,
>>    DM
>> Troy A. Griffitts wrote:
>>> Hey DM,
>>>     Been working on re-adding support for editing files into 
>>> flashcards and am trying to understand how things work.  Help me 
>>> learn about the need for the classloader extension.
>>>     Here is what I think the path might be for loading the lesson 
>>> groups.
>>>     1. look on the resource path (basically, the flashcards.jar file) 
>>> for "lessons/<lesson_group>/*.flash
>>>     2. CWD "file:lessons/<lesson_group>/*.flash
>>>     3. CWD "jar:file:lessons/*.jar!/lessons/<lesson_group>/*.flash
>>>     4. HOME "file:${user.home}/.flashcards/lessons/ 
>>> <lesson_group>/*.flash
>>>     5. HOME "jar:file:${user.home}/.flashcards/lessons/ 
>>> *.jar!/lessons/<lesson_group>/*.flash
>>>     I was going to attempt to write this today with 2 functions which 
>>> could be called from the quizzer and the editor could use at least 
>>> the first when the path is chosen:
>>>     // called for each <lesson_group> found
>>>     public static void addLessonGroup(Map lessonGroups, URL url);
>>>     // called 5 times with above logic
>>>     public static Vector discoverLessonGroups(URL lessonsPath);
>>>     ...but thought it best to ask you for direction, as I still don't 
>>> understand the function of the class loader.
>>>     Thanks for your efforts and in advance for your guidance!
>>>         -Troy.
>>> DM Smith wrote:
>>>> For those that were following this thread. Troy, John and I took it 
>>>> the conversation offline to figure out the problem.
>>>> We have fixed the problem (which was that the jar did not have the 
>>>> image files needed for the editor).
>>>> The program is available via webstart at www.crosswire.org/flashcards.
>>>> John's addition to the program is the ability to run the editor from 
>>>> inside of the quizzer.
>>>> Troy A. Griffitts wrote:
>>>>> OK John,
>>>>>     Here's my latest discoveries.
>>>>>     If I build on the server with ant and jdk 1.5.0, I have the 
>>>>> null editor window, running on XP jdk 1.4.1.
>>>>>     If I build on the server with ant and jdk 1.4.2, I have the 
>>>>> null editor window, running on XP jdk 1.4.1.
>>>>>     If I build on the server with your build script and jdk 1.5.0, 
>>>>> I get 1.5.0 compile errors which have been fixed and committed, and 
>>>>> then I get:
>>>>> Exception in thread "main" java.lang.UnsupportedClassVersionError: 
>>>>> org/crosswire /flashcards/Quiz (Unsupported major.minor version 49.0)
>>>>>     which is probably expected from XP and jdk 1.4.1
>>>>>     If I build on the server with your build script and jdk 1.4.2 
>>>>> everything works on XP jdk 1.4.1.
>>>>>     Hope we can track this down.
>>>>>         -Troy.
>>>>> get On Thu, 9 Sep 2004, John Jacques wrote:
>>>>>> Troy,
>>>>>> I don't get anything when I try to run the editor from the MainMenu
>>>>>> using webstart (Quiz does work).  All works well when I run from the
>>>>>> command line (on Linux):
>>>>>>     $ java -jar flashcards.jar
>>>>>> The Editor is the correct size etc.
>>>>>> I almost have my local web server set up to allow me to use webstart.
>>>>>> The last remaining obsticle is signing the jar file!  I am trying as
>>>>>> recommended
>>>>>> (http://java.sun.com/j2se/1.4.2/docs/guide/jws/developersguide/development.html#signing) 
>>>>>> but haven't been able to obtain 'unrestricted access'...
>>>>>> On Thu, 2004-09-09 at 12:20, Troy A. Griffitts wrote:
>>>>>>> John,
>>>>>>>      We could try setting a size.  It's not necessarily a webstart
>>>>>>> issue.  I got that error I reported to you by running the 
>>>>>>> produced jar
>>>>>>> file on an XP box.  If you click on the webstart link from this 
>>>>>>> page:
>>>>>>> http://crosswire.org/flashcards/
>>>>>>> does the edit choice work for you?
>>>>>>> I can grab the corner of the very small editor window and resize it
>>>>>>> larger, but there is nothing on the client area.
>>>>>>> If you'd really like the breathing marks to be entered before the 
>>>>>>> letters,
>>>>>>> the IM mechanism supports multiple keystroke for character 
>>>>>>> entry.  This is
>>>>>>> used in the Michigan Claremont Hebrew keymap, if you'd like to 
>>>>>>> see how it
>>>>>>> works.  Actually, just reviewed HebrewMCIM.java and it looks really
>>>>>>> convoluted.  Sorry about that.
>>>>>>>      Thanks for your work!
>>>>>>>          -Troy.
>>>>>>> On Wed, 8 Sep 2004, John Jacques wrote:
>>>>>>>> Troy,
>>>>>>>> The main difference I see is that MainFrame.java doesn't use
>>>>>>>> java.awt.Toolkit to determine the screen size as in 
>>>>>>>> Editor.java.  It
>>>>>>>> might be worth setting a screen size there...
>>>>>>>> I'm glad my other changes didn't break anything!
>>>>>>>> I'll try to set up webstart on a local webserver.  Looks like I 
>>>>>>>> would
>>>>>>>> just have to edit Flashcards.jnlp.  Is it that simple?
>>>>>>>> On Wed, 2004-09-08 at 16:49, Troy A. Griffitts wrote:
>>>>>>>>> John,
>>>>>>>>>      Thank you for your recent submissions.  I have updated the
>>>>>>>>> webstart installer to the latest code and the editor doesn't 
>>>>>>>>> seem to
>>>>>>>>> launch for me.  I get an error:
>>>>>>>>>   ERROR :
>>>>>>>>> org.crosswire.flashcards.EditorFrame[frame0,0,0,0x0,invalid,hidden,layo 
>>>>>>>>> ut=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_C 
>>>>>>>>> LOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPan 
>>>>>>>>> e$RootLayout,alignmentX=null,alignmentY=null,border=,flags=385,maximumSize=,mini 
>>>>>>>>> mumSize=,preferredSize=],rootPaneCheckingEnabled=true] :
>>>>>>>>> Thread[main,5,main]
>>>>>>>>> null
>>>>>>>>> and a very small windows (actually just the titlebar).
>>>>>>>>> Let me know if you have an idea what it might be.  Thank you.
>>>>>>>>>      -Troy.
>>>>>>>>> On Wed, 18 Aug 2004, John Jacques wrote:
>>>>>>>>>> Troy,
>>>>>>>>>> I'm going to check in my changes to flashcards.  So far there 
>>>>>>>>>> are no
>>>>>>>>>> major changes, just minor fixes.
>>>>>>>>>> If I want to make larger changes, should we branch?  Does the 
>>>>>>>>>> revision
>>>>>>>>>> (4 in this case) match up with other CrossWire software such 
>>>>>>>>>> as modedit
>>>>>>>>>> (which I believe is used elsewhere)?
>>>>>>>>>> One last question, is there a mailing list, or any other 
>>>>>>>>>> forum, where
>>>>>>>>>> new ideas should be discussed before they are implemented?
>>>>>>>>>> On Sun, 2004-08-15 at 03:23, Troy A. Griffitts wrote:
>>>>>>>>>>> John,
>>>>>>>>>>>     We've recently changed servers and it has been keeping me 
>>>>>>>>>>> busy for the
>>>>>>>>>>> past few weeks.  We just put a new live SVN repository online 
>>>>>>>>>>> at:
>>>>>>>>>>> https://crosswire.org/svn/flashcards/
>>>>>>>>>>> The repository permission is currently WORLD READ/WRITE.  If 
>>>>>>>>>>> you would
>>>>>>>>>>> like to commit your changes to the repository, you are 
>>>>>>>>>>> welcome to do so.
>>>>>>>>>>>   Not sure if you've had subversion experience.  If now, you 
>>>>>>>>>>> can find
>>>>>>>>>>> info and software at:
>>>>>>>>>>> http://subversion.tigris.org
>>>>>>>>>>> Thanks again for your willingness to help.
>>>>>>>>>>>     -Troy.
>>>>>>>>>>> John Jacques wrote:
>>>>>>>>>>>> Troy,
>>>>>>>>>>>> I made the following changes.  Let me know if you keep any 
>>>>>>>>>>>> of them!
>>>>>>>>>>>> There are files named "Changes.eruditelite" in any directory 
>>>>>>>>>>>> I made
>>>>>>>>>>>> changes in that describe each change and the modified 
>>>>>>>>>>>> files.  I have
>>>>>>>>>>>> also included the change files in this messages (see below).
>>>>>>>>>>>> Are you using a revision control system?
>>>>>>>>>>>> Also, what do you think of the following proposals:
>>>>>>>>>>>>     1) Add a Quiz mode in which the user is presented with the
>>>>>>>>>>>>        vocabulary word only (not multiple choice) and then the
>>>>>>>>>>>>            answer (either time delayed or by pressing a 
>>>>>>>>>>>> button).  The
>>>>>>>>>>>>            user then indicates whether they knew the word or 
>>>>>>>>>>>> not.  The
>>>>>>>>>>>>            current mode (multiple choice) would still be 
>>>>>>>>>>>> available.
>>>>>>>>>>>>     2) Cleanup ".flash" files when saving (eliminate unused
>>>>>>>>>>>>            entries, renumber etc.)
>>>>>>>>>>>> ========== In the top directory:
>>>>>>>>>>>> 1) Added GNUmakefile to speedup working from emacs/command 
>>>>>>>>>>>> line.
>>>>>>>>>>>> 2) Updated to the latest (on the website 22 July 2004) 
>>>>>>>>>>>> modedit.  This
>>>>>>>>>>>>    allowed me to enter text (classical greek) in Mandrake 10.0.
>>>>>>>>>>>> 3) Added MounceBasicsChapter04.flash (Vocabulary from 
>>>>>>>>>>>> Chapter 4 of
>>>>>>>>>>>>    Mounce's Basics of Biblical Greek).
>>>>>>>>>>>> ========== In src/flash:
>>>>>>>>>>>> 1) Changed tool tip for "Save" from "Help" to "Save"
>>>>>>>>>>>> (EditorFrame.java:102)
>>>>>>>>>>>> 2) Stopped displaying exception on startup when 
>>>>>>>>>>>> "NewLesson.flash"
>>>>>>>>>>>>    didn't exist.  (EidtorFrame.java:247)
>>>>>>>>>>>> On Sat, 2004-07-17 at 16:37, Troy A. Griffitts wrote:
>>>>>>>>>>>>> John,
>>>>>>>>>>>>>     Thanks for the offer.  We'd love any help you'd be 
>>>>>>>>>>>>> willing to
>>>>>>>>>>>>> volunteer.  That's how our open projects improve!  You'll 
>>>>>>>>>>>>> find the source
>>>>>>>>>>>>> in the same directory pointed to by the download link.  I 
>>>>>>>>>>>>> don't think we
>>>>>>>>>>>>> have an actual link to it yet.
>>>>>>>>>>>>>     We do have some c++/linux/handheld apps:
>>>>>>>>>>>>>     http://crosswire.org/qpsword/
>>>>>>>>>>>>>     And we'd love to see flashcards run on the Zaurus! :)  
>>>>>>>>>>>>> Or at least
>>>>>>>>>>>>> a client that reads the same lesson formats.
>>>>>>>>>>>>>     Thanks you again for your persistence to get our app to 
>>>>>>>>>>>>> work and
>>>>>>>>>>>>> willingness to help!
>>>>>>>>>>>>>     -Troy A. Griffitts
>>>>>>>>>>>>> On Sat, 17 Jul 2004, John Jacques wrote:
>>>>>>>>>>>>>> Troy,
>>>>>>>>>>>>>> Thanks for the response!  The final sigma is " (double 
>>>>>>>>>>>>>> quote) and my
>>>>>>>>>>>>>> confusion about saving a new list was the pop-up hint for 
>>>>>>>>>>>>>> the save
>>>>>>>>>>>>>> button (which says "Help").  It all works now...
>>>>>>>>>>>>>> If you are interested in programming help, let me know.  I 
>>>>>>>>>>>>>> am a
>>>>>>>>>>>>>> programmer (embedded Linux/Real Time) so most of my 
>>>>>>>>>>>>>> experience is OS
>>>>>>>>>>>>>> porting and device drivers but I have written a fair 
>>>>>>>>>>>>>> amount of Java
>>>>>>>>>>>>>> (~7,000 lines) including a Swing GUI.
>>>>>>>>>>>>>> On Sat, 2004-07-17 at 07:02, Troy A. Griffitts wrote:
>>>>>>>>>>>>>>> John, I believe that final sigma is the ' key.  Did you 
>>>>>>>>>>>>>>> type a filename
>>>>>>>>>>>>>>> in the filename box before you hit save?  I realize this 
>>>>>>>>>>>>>>> isn't an
>>>>>>>>>>>>>>> orthodox method for saving a new file, but it's a first 
>>>>>>>>>>>>>>> rev of the
>>>>>>>>>>>>>>> software.  Please let me know if this information hasn't 
>>>>>>>>>>>>>>> helped get you
>>>>>>>>>>>>>>> going.
>>>>>>>>>>>>>>>     -Troy A. Griffitts.
>>>>>>>>>>>>>>> John Jacques wrote:
>>>>>>>>>>>>>>>> First of all, thank you for a wonderful program!  
>>>>>>>>>>>>>>>> However, I can't seem
>>>>>>>>>>>>>>>> to get FlashEditor.jar to save any of the changes I make 
>>>>>>>>>>>>>>>> or let me enter
>>>>>>>>>>>>>>>> a sigma (the end of word sigma that is)...
>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>> sword-support mailing list
>>>>>>>>>>>>>>>> sword-support at crosswire.org
>>>>> _______________________________________________
>>>>> jsword-devel mailing list
>>>>> jsword-devel at crosswire.org
>>>>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>>>> _______________________________________________
>>>> jsword-devel mailing list
>>>> jsword-devel at crosswire.org
>>>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>>> _______________________________________________
>>> jsword-devel mailing list
>>> jsword-devel at crosswire.org
>>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>> _______________________________________________
>> jsword-devel mailing list
>> jsword-devel at crosswire.org
>> http://www.crosswire.org/mailman/listinfo/jsword-devel
> _______________________________________________
> jsword-devel mailing list
> jsword-devel at crosswire.org
> http://www.crosswire.org/mailman/listinfo/jsword-devel

More information about the sword-devel mailing list