Created
May 3, 2011 18:34
-
-
Save EmilHernvall/953916 to your computer and use it in GitHub Desktop.
A tiny java-program for language training
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* WordTrainer 2008-12-02 | |
* Simple language training in Java. This program accepts text-files | |
* containing where each line contains two words in two diffrent languages | |
* separated by a comma (,). The first line follows the same format but | |
* specifies the language. | |
* | |
* Sample gloss-file: | |
* Engelska,Svenska | |
* cloud,moln | |
* world,värld | |
* day,dag | |
* stay,stanna | |
* mysterious,mysterisk | |
* | |
* This application uses swing and has no external dependencies, besides | |
* the standard java runtime. | |
* | |
* All comments are welcome. | |
* | |
* @author Emil Hernvall <[email protected]> | |
* @license PD - No rights reserved. | |
**/ | |
import java.io.*; | |
import java.util.*; | |
import javax.swing.*; | |
import java.awt.*; | |
import java.awt.event.*; | |
import java.util.List; | |
/** | |
* Main class. | |
* Static main()-method contains program flow. | |
**/ | |
public class WordTrainer | |
{ | |
/** | |
* A simple dialog that allows the user to select the language of the displayed | |
* glosses. | |
*/ | |
private static class LanguageSelector extends JDialog implements ActionListener | |
{ | |
private int choice = 0; | |
JRadioButton lang1; | |
JRadioButton lang2; | |
/** | |
* Initializes the dialog and creates the gui elements. | |
* | |
* @param String l1 - First language | |
* @param String l2 - Second language | |
**/ | |
public LanguageSelector(String l1, String l2) | |
{ | |
JPanel pane = new JPanel(); | |
pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); | |
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); | |
JLabel label = new JLabel("Please select the primary language:"); | |
pane.add(label); | |
ButtonGroup group = new ButtonGroup(); | |
lang1 = new JRadioButton(l1); | |
lang1.setSelected(true); | |
group.add(lang1); | |
pane.add(lang1); | |
lang2 = new JRadioButton(l2); | |
group.add(lang2); | |
pane.add(lang2); | |
JButton btnSelect = new JButton("Select"); | |
btnSelect.addActionListener(this); | |
pane.add(btnSelect); | |
JButton btnExit = new JButton("Exit"); | |
btnExit.addActionListener(new ActionListener() { | |
public void actionPerformed(ActionEvent e) { | |
System.exit(0); | |
} | |
}); | |
pane.add(btnExit); | |
add(pane); | |
setTitle("Language"); | |
setVisible(true); | |
pack(); | |
} | |
/** | |
* Implementation of the ActionListener-interface. Invoked by | |
* the Select-button. Stores the users choice of language and | |
* notifies the main thread that the user has made her/his | |
* choice. | |
**/ | |
public synchronized void actionPerformed(ActionEvent e) | |
{ | |
if (lang2.isSelected()) { | |
choice = 2; | |
} else { | |
choice = 1; | |
} | |
this.notify(); | |
setVisible(false); | |
} | |
/** | |
* Returns 1 or 2 depending on the choice of language. | |
**/ | |
public int getChoice() | |
{ | |
return choice; | |
} | |
} | |
/** | |
* A very simple frame that displays the results of the quiz in | |
* a text box. It also provides a button to close the frame and | |
* exit the application. | |
**/ | |
private static class ReportFrame extends JFrame implements ActionListener | |
{ | |
/** | |
* Initializes the frame and creates the gui elements. | |
**/ | |
public ReportFrame(String text) | |
{ | |
super(); | |
JPanel pane = new JPanel(); | |
pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); | |
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); | |
JTextArea txtInfo = new JTextArea(text); | |
txtInfo.setEditable(false); | |
pane.add(txtInfo); | |
pane.add(Box.createVerticalStrut(5)); | |
JButton exitButton = new JButton("Exit"); | |
exitButton.setMinimumSize(new Dimension(100,20)); | |
exitButton.addActionListener(this); | |
pane.add(exitButton); | |
add(pane); | |
setTitle("Result"); | |
setVisible(true); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
pack(); | |
} | |
public void actionPerformed(ActionEvent e) | |
{ | |
System.exit(0); | |
} | |
} | |
/** | |
* Class containg two words in two different languages. | |
**/ | |
private static class Gloss | |
{ | |
public String l1; | |
public String l2; | |
} | |
/** | |
* The class is never instantiated. | |
**/ | |
private WordTrainer() | |
{ | |
} | |
/** | |
* Application entry-point. | |
**/ | |
public static void main(String args[]) | |
throws Exception | |
{ | |
// Avoid the ugly java look and feel, if possible. | |
try { | |
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); | |
JFrame.setDefaultLookAndFeelDecorated(true); | |
} catch(Exception e) { | |
System.out.println("Error setting native LAF: " + e); | |
System.exit(0); | |
} | |
// Display a file dialog if needed, or retrieve file name | |
// by checking the application argument list. | |
String file; | |
if (args.length == 0) { | |
FileDialog fd = new FileDialog((Frame)null); | |
fd.setVisible(true); | |
file = fd.getFile(); | |
// Exit on abort. | |
if (file == null) { | |
System.exit(0); | |
} | |
} else { | |
file = args[0]; | |
} | |
// Ensure that the provided file exists. Exit if not. | |
if (!new File(file).exists()) { | |
JOptionPane.showMessageDialog(null, "Failed to find file!"); | |
System.exit(0); | |
} | |
// Open the provided file for reading. | |
FileReader fileReader = new FileReader(file); | |
BufferedReader reader = new BufferedReader(fileReader); | |
// Read the first line containing the language key. | |
String legend = reader.readLine(); | |
if (legend == null) { | |
JOptionPane.showMessageDialog(null, "First line should follow the format \"firstlang,secondlang\"."); | |
System.exit(0); | |
} | |
String[] langs = legend.split(","); | |
if (langs.length != 2) { | |
JOptionPane.showMessageDialog(null, "First line should follow the format \"firstlang,secondlang\"."); | |
System.exit(0); | |
} | |
// Read the rest of the glosses from the file, store them in a linked list for easy | |
// sequential access. | |
LinkedList<Gloss> glossary = new LinkedList(); | |
String line; | |
while ((line = reader.readLine()) != null) { | |
String[] lineSplit = line.split(","); | |
if (lineSplit.length != 2) { | |
JOptionPane.showMessageDialog(null, "Lines should follow the format \"firstlang,secondlang\"."); | |
System.exit(0); | |
} | |
Gloss gloss = new Gloss(); | |
gloss.l1 = lineSplit[0]; | |
gloss.l2 = lineSplit[1]; | |
glossary.add(gloss); | |
} | |
// Randomize the order. | |
Collections.shuffle(glossary); | |
// Done reading. Close the readers. | |
reader.close(); | |
fileReader.close(); | |
// Display the selection box. | |
String firstLang = langs[0]; | |
String secondLang = langs[1]; | |
LanguageSelector ls = new LanguageSelector(firstLang, secondLang); | |
synchronized(ls) { | |
// Wait until the user has made a selection. | |
ls.wait(); | |
} | |
// Retrieve the users choice. | |
int primLang = ls.getChoice(); | |
// Main query loop | |
int done = 0, correct = 0; | |
LinkedList<Gloss> invalid = new LinkedList(); | |
LinkedList<Gloss> valid = new LinkedList(); | |
while (glossary.size() > 0) | |
{ | |
// Pick a gloss from the linked list. Query the user. | |
Gloss gloss = glossary.poll(); | |
String text = "What's the translation of \""; | |
if (primLang == 2) { | |
text += gloss.l2; | |
} else { | |
text += gloss.l1; | |
} | |
text += "\"?"; | |
String res = JOptionPane.showInputDialog(null, text); | |
// Check if the answer is correct. | |
if (primLang == 2) { | |
if (gloss.l1.equals(res)) { | |
correct++; | |
valid.add(gloss); | |
} else { | |
invalid.add(gloss); | |
} | |
} else { | |
if (gloss.l2.equals(res)) { | |
correct++; | |
valid.add(gloss); | |
} else { | |
invalid.add(gloss); | |
} | |
} | |
done++; | |
} | |
// Display results | |
String endResult = "You got " + correct + " correct from a total of " + done + ".\n\n"; | |
endResult += "Failed: \n"; | |
for (Gloss gloss : invalid) { | |
endResult += gloss.l1 + " - " + gloss.l2 + "\n"; | |
} | |
endResult += "\nCorrect: \n"; | |
for (Gloss gloss : valid) { | |
endResult += gloss.l1 + " - " + gloss.l2 + "\n"; | |
} | |
ReportFrame report = new ReportFrame(endResult); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment