This time, I will try to make it clear. I have run it for 2 days. No problem. But there are still lots of TODO. The version now is 0.1
I will try to give it a name and write a detail readme about how to use it. Of course need finish the TODO in the program.
/* * Config.java * Created on Sep 29, 2004 * TODO Write the log to file. */ package com.henry.vocabulary;
import java.io.*; import java.util.logging.*; import java.util.*;
/** * @author henry.pan * TODO Add unit test for this class */ public class Config { private static Logger logger = Logger.getLogger("Config"); private static String configFile = "config.ini"; /* here is the config and the default value */ private static String wordsFileName = "words.txt"; private static int sleepInterval = 6000 * 2; /** * @return The config of the file storing the words. */ public static String getWordsFileName() { return wordsFileName; } public static int getSleepInterval() { return sleepInterval; } /** * Read configuration from config file. * Config file is defined. */ public static void getTheConfiguration() { File file = new File(configFile); if (!file.exists()) { logger.severe("The config file does not exist!" + Calendar.getInstance().getTime()); } try { StringBuffer sb = new StringBuffer(); BufferedReader br = new BufferedReader(new FileReader(configFile)); String s; String[] configValues; while ((s = br.readLine()) != null) { if (s.equals("")) { continue; } if (s.substring(0,0).equals("#")) { continue; } configValues = s.split("="); parseConfigValue(configValues); } } catch (IOException ioe) { logger.severe("Error when reading confi file!"); logger.severe(ioe.getStackTrace().toString()); logger.severe(ioe.toString()); } } /** * @param configValues The config paire values. * configValues[0] is the config name * configValues[1] is the config value */ private static void parseConfigValue(String[] configValues) { assert configValues.length > 1 : "The config format is incorrect!"; try { if (configValues[0].trim().toLowerCase() == "WordsFile") { wordsFileName = configValues[1].trim(); } if (configValues[0].trim().toLowerCase() == "SleepInterval") { sleepInterval = Integer.parseInt( configValues[1].trim()); } } catch (Exception e) { logger.severe("The configuration's format is incorrect!"); logger.severe(e.getStackTrace().toString()); logger.severe(e.toString()); } }
}
/* * MainFrame.java * Created on Sep 28, 2004 * */ package com.henry.vocabulary;
import java.awt.*; import java.awt.event.*; import java.util.Calendar; import java.util.logging.*;
import javax.swing.*;
/******************************************************************************* * Title: * * * Description: * * * Copyright: Copyright (c) 2004 * * * Company: * * @author Henry * * @version 1.0 * TODO Add unit test for this class */ public class MainFrame extends JFrame {
Logger logger = Logger.getLogger("MainWin"); /* Used to manipulate the words */ WordsReview wr = new WordsReview(); JPanel contentPane; GridBagLayout gridBagLayout1 = new GridBagLayout(); JTextField word = new JTextField(); JRadioButton remember = new JRadioButton(); JRadioButton forget = new JRadioButton(); JButton next = new JButton(); ButtonGroup buttonGroup1 = new ButtonGroup(); /* Construct the frame */
public MainFrame() { enableEvents(AWTEvent.WINDOW_EVENT_MASK); try { jbInit(); wordsInit(); } catch (Exception e) { e.printStackTrace(); } }
/* Component initialization */ private void jbInit() throws Exception { contentPane = (JPanel) this.getContentPane(); word.setFont(new java.awt.Font("Dialog", 0, 16)); word.setSelectionStart(0); word.setText(""); contentPane.setLayout(gridBagLayout1); this.setSize(new Dimension(600, 300)); this.setTitle("TAFU Vocabulary"); remember.setFont(new java.awt.Font("Dialog", 0, 16)); remember.setText("I remember it well."); forget.setFont(new java.awt.Font("Dialog", 0, 16)); remember.setSelected(true); forget.setText("I forget it."); next.setFont(new java.awt.Font("Dialog", 0, 16)); next.setText("Next"); next.addActionListener(new Frame1_next_actionAdapter(this)); contentPane.add(word, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 17, 9, 0, 31), 494, 39)); contentPane.add(remember, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(26, 0, 1, 0), 0, 0)); contentPane.add(forget, new GridBagConstraints(1, 1, 1, 2, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(25, 0, 37, 0), 0, 0)); contentPane.add(next, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 0, 9, 59, 13), 44, 11)); buttonGroup1.add(forget); buttonGroup1.add(remember); }
/* Overridden so we can exit when window is closed */ protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { logger.info("Close the window!"); try { wr.saveToFile(); } catch (Exception ex) { System.out.println(ex.getStackTrace()); System.out.println(ex); } System.exit(0); } }
private void wordsInit() { try { wr.readFromFile(); getNextWord(); } catch (Exception e) { System.out.println(e.getStackTrace()); System.out.println(e); } }
private void getNextWord() { String s = this.wr.getWord(); if (s == null) { this.setVisible(false); this.wr.saveToFile(); while (s == null) { logger.info("Get a null word. No word needs review now. Goto Sleep." + Calendar.getInstance().getTime()); try { Thread.sleep(Config.getSleepInterval()); logger.info(" -- After sleep --" + Calendar.getInstance().getTime()); this.wr.readFromFile(); s = this.wr.getWord(); } catch (InterruptedException ie) { System.out.println(ie.getStackTrace()); System.out.println(ie); } } this.setVisible(true); } this.word.setText(s); this.remember.setSelected(true); }
void next_actionPerformed(ActionEvent e) { if (this.forget.isSelected()) { wr.saveWord(false); } else { wr.saveWord(true); } getNextWord(); }
}
class Frame1_next_actionAdapter implements java.awt.event.ActionListener { MainFrame adaptee;
Frame1_next_actionAdapter(MainFrame adaptee) { this.adaptee = adaptee; }
public void actionPerformed(ActionEvent e) { adaptee.next_actionPerformed(e); } }
/* * MainWin.java * Created on Sep 28, 2004 */ package com.henry.vocabulary;
import javax.swing.UIManager; import java.awt.*;
/******************************************************************************* * Title: * * * Description: * * * Copyright: Copyright (c) 2004 * * * Company: * * @author not attributable * * @version 1.0 * TODO Make sure there is only one instance running. */ public class MainWin { boolean packFrame = false;
/* Construct the application */ public MainWin() { MainFrame frame = new MainFrame();
/* * 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(); } /* Center the window */ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); frame.setVisible(true); }
/* Main method */ public static void main(String[] args) { boolean assertionsEnabled = false; /* Note intentioal side effect of assignment. */ assert assertionsEnabled = true; if (!assertionsEnabled) { throw new RuntimeException("Assertions disabled"); } try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } new MainWin(); System.out.println("Exit the MainWin.main()."); } }
/******************************************************************************* * Word.java * * Created on 2004-9-26 */ package com.henry.vocabulary;
import java.util.*; import java.text.*;
public class Word { private static final SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
private static final int[] memoryCurveMinute = {10, 30, 60, 180, 300, 500}; private static final int[] memoryCurveDay = { 1, 2, 4, 8, 12, 20, 36, 54, 87, 160, 360 ,680};
private String _wordValue; private Date _nextReviewTime; private int _reviewTimes; private int _forgetTimes; /** * * * * @param _wordValue * The _wordValue to set. */ public void setWordValue(String _wordValue) { this._wordValue = _wordValue; }
/** * * * * @return Returns the _wordValue. */ public String getWordValue() { return _wordValue; }
public Word(String wordValue, String nextReviewTime, int reviewTimes, int forgetTimes) { try { setWordValue(wordValue); _nextReviewTime = format.parse(nextReviewTime); _reviewTimes = reviewTimes; _forgetTimes = forgetTimes; } catch (ParseException pe) { System.out.println("The input is not a date!"); throw new RuntimeException(pe); } }
public Word(String strWord) { try { String[] values = strWord.split(","); setWordValue(values[0]); if(values.length > 2) { _nextReviewTime = format.parse(values[1]); _reviewTimes = Integer.parseInt(values[2].trim()); } else { Calendar yesterday = Calendar.getInstance(); yesterday.add(Calendar.DATE, -1); _nextReviewTime = yesterday.getTime(); _reviewTimes = 0; } if (values.length > 3) { /* For compatible to the old version */ _forgetTimes = Integer.parseInt(values[3]); } else { _forgetTimes = 0; } } catch (ParseException pe) { System.out.println("The input is not a date!"); throw new RuntimeException(pe); } }
public void forget() { Calendar nextTime = Calendar.getInstance(); nextTime.add(Calendar.MINUTE, -1); _nextReviewTime = nextTime.getTime(); _reviewTimes = 0; _forgetTimes++; }
public void remember() { Calendar nextTime = Calendar.getInstance(); if (this._reviewTimes < memoryCurveMinute.length) { nextTime.add(Calendar.MINUTE, memoryCurveMinute[_reviewTimes]); } else if (_reviewTimes - memoryCurveMinute.length < memoryCurveDay.length) { nextTime.add(Calendar.DATE, memoryCurveDay[_reviewTimes - memoryCurveMinute.length]); } else { nextTime.add(Calendar.YEAR, 100); /* Never need review this word */ } if(nextTime.get(Calendar.DATE) != Calendar.getInstance().get(Calendar.DATE)) { nextTime.set(Calendar.HOUR, 0); nextTime.set(Calendar.MINUTE, 0); nextTime.set(Calendar.SECOND, 0); } _nextReviewTime = nextTime.getTime(); _reviewTimes++; }
public String toString() { String s = getWordValue() + "," + format.format(_nextReviewTime) + "," + _reviewTimes + "," + _forgetTimes; return s; }
/** * Judge if this word need to be reviewed now. * Comment for isNeedReview */ public boolean isNeedReview() { if (this._nextReviewTime.after(Calendar.getInstance().getTime())) { return false; } return true; } public boolean equals (Object o) { if (this._wordValue.equalsIgnoreCase(((Word)o).getWordValue())) { return true; } return false; } public boolean isNeedNotReviewAnyMore() { Calendar later50Years = Calendar.getInstance(); later50Years.add(Calendar.YEAR, 50); if (this._nextReviewTime.after(later50Years.getTime())) { return true; } return false; } }
/* * WordsReview.java * * Created on 2004-9-26 * * */
package com.henry.vocabulary;
import java.util.*; import java.util.logging.*; import java.io.*;
/** * TODO Add unit test for this class * * @author Henry * */ public class WordsReview {
static Logger logger = Logger.getLogger("WordsReview");
List wordList = null;
List wordNeedReviewList = null;
Word currentWord = null;
Map wordMap = null;
/** * * * * @param fileName */ private void readFromFile(String fileName) { assert (this.wordList != null) : "Doesnt init the wordList when readFromFile."; createWordsFileIfItNotExist(); StringBuffer sb = null; BufferedReader br = null; try { sb = new StringBuffer(); br = new BufferedReader(new FileReader(fileName)); String s; while ((s = br.readLine()) != null) { this.currentWord = new Word(s); if (!this.wordMap.containsKey(this.currentWord.getWordValue())) { this.wordMap.put(this.currentWord.getWordValue(), this.currentWord); this.wordList.add(this.currentWord); if (this.currentWord.isNeedReview()) { this.wordNeedReviewList.add(this.currentWord); } } else { this.currentWord = (Word) this.wordMap.get(this.currentWord .getWordValue()); this.currentWord.forget(); } } this.currentWord = null; br.close(); } catch (FileNotFoundException e) { System.out.println(e); System.out.println(e.getStackTrace()); } catch (IOException ioe) { System.out.println(ioe); System.out.println(ioe.getStackTrace()); } finally { /* br.close(); */ } }
/* * TODO After create the words file. Add the advertise words in the file. * Such as http://blog.csdn.net/tafu * * TODO Put this function out of here. */ private void createWordsFileIfItNotExist() { File f = new File(Config.getWordsFileName()); if (!f.exists()) { try { f.createNewFile(); } catch (IOException ioe) { logger.severe("Cannot create file to save the words!" + Calendar.getInstance().getTime()); logger.severe(ioe.getStackTrace().toString()); logger.severe(ioe.toString()); } } }
/** * * * * @param fileName */ private void saveToFile(String fileName) { try { PrintWriter printWriter = new PrintWriter(new BufferedWriter( new FileWriter(fileName))); Iterator iterator = this.wordList.iterator(); while (iterator.hasNext()) { printWriter.println((Word) iterator.next()); } printWriter.close(); } catch (IOException ioe) { System.out.println(ioe.getStackTrace()); System.out.println(ioe); } }
public void saveToFile() { this.saveToFile(Config.getWordsFileName()); }
/** * * Get a word, which needs to be reviewed. * * * @return */ public String getWord() { if (this.wordNeedReviewList.isEmpty()) { return null; } Random random = new Random(); int ramdonIndex = random.nextInt() % this.wordNeedReviewList.size(); if (ramdonIndex < 0) { ramdonIndex = -ramdonIndex; } currentWord = (Word) this.wordNeedReviewList.get(ramdonIndex); return currentWord.getWordValue(); }
public void saveWord(boolean isRemember) { if (this.currentWord == null) { System.out.println("Should not come here!"); System.out.println("When you call saveWord to save the word, "); System.out.println(" you should get the word first."); return; } if (!isRemember) { this.currentWord.forget(); } else { this.currentWord.remember(); } this.wordNeedReviewList.remove(this.currentWord); if (this.currentWord.isNeedNotReviewAnyMore()) { this.wordList.remove(this.currentWord); this.wordMap.remove(this.currentWord.getWordValue()); } this.currentWord = null; }
public void regenerateNeedReviewList() { this.wordNeedReviewList = new ArrayList(); for (int i = 0; i < this.wordList.size(); i++) { if (((Word) this.wordList.get(i)).isNeedReview()) { this.wordNeedReviewList.add((Word) this.wordList.get(i)); } } this.currentWord = null; }
public void readFromFile() { this.wordList = new ArrayList(); this.wordNeedReviewList = new LinkedList(); this.wordMap = new HashMap(); this.readFromFile(Config.getWordsFileName()); }
}
/* * WordTest.java * Created on Sep 30, 2004 * */ package com.henry.vocabulary.junit;
import junit.framework.TestCase; import com.henry.vocabulary.*; import java.util.*; import java.text.*;
/** * @author henry.pan * */ public class WordTest extends TestCase {
/* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); }
/* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); }
public void testSetWordValue() { Word w = new Word("testWord"); w.setWordValue("newValue"); TestCase.assertEquals("newValue",w.getWordValue()); w = null; }
public void testGetWordValue() { Word w = new Word("testWord"); TestCase.assertEquals("testWord",w.getWordValue()); w = null; }
public void testForget() { Word w = new Word("testWord"); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MINUTE, -1); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:"); String s = df.format(calendar.getTime()); w.forget(); /* System.out.println(w); */ /* System.out.println("testWord," + s + "\\d\\d,0,\\d+"); */ TestCase.assertTrue(w.toString().matches("testWord," + s + "\\d\\d,0,\\d+")); w.forget(); w.remember(); w.remember(); w.forget(); TestCase.assertTrue(w.toString().matches("testWord," + s + "\\d\\d,0,\\d+")); w = null; }
public void testRemember() { }
public void testIsNeedReview() { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MINUTE, -1); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String s = df.format(calendar.getTime()); Word w = new Word("testWord," + s + ",3,2"); TestCase.assertTrue(w.isNeedReview()); w = null; }
/* * Class under test for boolean equals(Object) */ public void testEqualsObject() { Word w1 = new Word("testWord"); Word w2 = new Word("testWord"); w1.forget(); w2.remember(); TestCase.assertTrue(w1.equals(w2)); }
public void testIsNeedNotReviewAnyMore() { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.YEAR, 100); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String s = df.format(calendar.getTime()); Word w = new Word("testWord," + s + "3,2"); TestCase.assertTrue(w.isNeedNotReviewAnyMore()); w = null; }
}
//========================================== And the test data in words.txt file. distract,2004-10-01 00:00:00,7,0 marvel,2004-10-01 00:00:00,7,0 vaunt,2004-10-01 00:00:00,7,3 syllabus,2004-10-01 00:00:00,7,0 typo,2004-10-01 00:00:00,7,0 parallel,2004-10-01 00:00:00,7,0 paradigm,2004-10-01 00:00:00,7,0 mediocre,2004-10-01 00:00:00,7,2 stuck,2004-10-01 00:00:00,7,0 auxiliary,2004-10-01 00:00:00,7,1 somehow,2004-10-01 00:00:00,7,1 even number,2004-10-01 00:00:00,7,0 lore,2004-10-01 00:00:00,7,1 compel,2004-10-01 00:00:00,7,1 inclination,2004-10-01 00:00:00,7,1 garble,2004-10-01 00:00:00,7,1 innate,2004-10-01 00:00:00,7,0 imperative,2004-10-01 00:00:00,7,0 even up,2004-10-01 00:00:00,7,1 preemptive,2004-10-01 00:00:00,7,0 fathom,2004-10-01 00:00:00,7,0 moon cake,2004-10-01 00:00:00,7,0 chug,2004-10-01 00:00:00,7,0 unnecessary,2004-10-01 00:00:00,7,0 state,2004-10-01 00:00:00,7,0 largely,2004-10-01 00:00:00,7,0 elaborate,2004-10-01 00:00:00,7,0 gliph,2004-10-01 00:00:00,7,0 pug,2004-10-01 00:00:00,7,0 recipe,2004-10-01 00:00:00,7,0 adjective,2004-10-01 00:00:00,7,0 spam,2004-10-01 00:00:00,7,0 loaf,2004-10-01 00:00:00,7,0 circus,2004-10-01 00:00:00,7,0 incessantly,2004-10-01 00:00:00,7,1 cannibalize,2004-10-01 00:00:00,7,0 eligible,2004-10-01 00:00:00,7,0 parenthetic,2004-10-01 00:00:00,7,1 cue,2004-10-01 00:00:00,7,0 rejuvenate,2004-10-01 12:00:00,7,0 back away,2004-10-01 12:00:00,7,0 ballistic,2004-10-01 12:00:00,7,0 interrogate,2004-10-01 12:00:00,7,0 introspect,2004-10-01 12:00:00,7,0 plop,2004-10-01 12:00:00,7,0 self-aware,2004-10-01 12:00:00,7,0 deduction,2004-09-30 21:48:56,6,0 reimbursement,2004-09-30 21:51:09,6,0 relic,2004-09-30 21:51:13,6,0 unilateral,2004-09-30 21:53:23,6,0 loiter,2004-09-30 21:53:18,6,0 symptom,2004-09-30 18:39:04,5,0 conspire,2004-09-30 21:38:59,5,0 incubation,2004-09-30 21:41:03,5,0 ridiculous,2004-09-30 17:43:11,4,0 overextended,2004-09-30 20:13:37,4,0 summit,2004-09-30 20:15:39,4,1 endorse,2004-09-30 20:15:56,4,1

|