[Japi-cvs] SF.net SVN: japi:[647] progs
Status: Beta
Brought to you by:
christianhujer
|
From: <chr...@us...> - 2008-10-06 12:45:40
|
Revision: 647
http://japi.svn.sourceforge.net/japi/?rev=647&view=rev
Author: christianhujer
Date: 2008-10-06 12:44:39 +0000 (Mon, 06 Oct 2008)
Log Message:
-----------
Added module for jtype prototype.
Added Paths:
-----------
progs/jtype/
progs/jtype/branches/
progs/jtype/tags/
progs/jtype/trunk/
progs/jtype/trunk/jtype.iml
progs/jtype/trunk/src/
progs/jtype/trunk/src/doc/
progs/jtype/trunk/src/prj/
progs/jtype/trunk/src/prj/net/
progs/jtype/trunk/src/prj/net/sf/
progs/jtype/trunk/src/prj/net/sf/japi/
progs/jtype/trunk/src/prj/net/sf/japi/jtype/
progs/jtype/trunk/src/prj/net/sf/japi/jtype/Helper.java
progs/jtype/trunk/src/prj/net/sf/japi/jtype/JType.java
progs/jtype/trunk/src/prj/net/sf/japi/jtype/PerformancePane.java
progs/jtype/trunk/src/prj/net/sf/japi/jtype/ReflectionField.java
progs/jtype/trunk/src/prj/net/sf/japi/jtype/action.properties
progs/jtype/trunk/src/tst/
Added: progs/jtype/trunk/jtype.iml
===================================================================
--- progs/jtype/trunk/jtype.iml (rev 0)
+++ progs/jtype/trunk/jtype.iml 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src/doc" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/prj" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/tst" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="annotations" level="project" />
+ <orderEntry type="library" name="junit" level="project" />
+ <orderEntry type="module" module-name="libs-swing-action" />
+ <orderEntryProperties />
+ </component>
+</module>
+
Property changes on: progs/jtype/trunk/jtype.iml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:eol-style
+ LF
Added: progs/jtype/trunk/src/prj/net/sf/japi/jtype/Helper.java
===================================================================
--- progs/jtype/trunk/src/prj/net/sf/japi/jtype/Helper.java (rev 0)
+++ progs/jtype/trunk/src/prj/net/sf/japi/jtype/Helper.java 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1,113 @@
+package net.sf.japi.jtype;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/** Utility methods for Strings.
+ * @author <a href="mailto:ch...@ri...">Christian Hujer</a>
+ */
+// mögliche Suchstrategien:
+// - RE1 (alte und neue Buchstaben) passt
+// - RE1 (alte und neue Buchstaben) passt, RE2 (nur alte Buchstaben) passt nicht
+// - Buchstabenkombinationen
+public class Helper {
+
+ /** Utility class - do not instanciate. */
+ private Helper() {
+ }
+
+ /** Returns all strings that match a specific regular expression but not a second one.
+ * @param match regular expression pattern.
+ * @param nomatch regular expression pattern.
+ * @param strings Strings to search.
+ * @return All strings that match the pattern specified by match but do not match the pattern specified by nomatch.
+ */
+ public static List<String> find(@NotNull final Pattern match, @Nullable final Pattern nomatch, @NotNull final Iterable<String> strings) {
+ final List<String> found = new ArrayList<String>();
+ final Matcher m1 = match.matcher("");
+ final Matcher m2 = nomatch != null ? nomatch.matcher("") : null;
+ for (final String s : strings) {
+ if (m1.reset(s).matches() && (m2 == null || !m2.reset(s).matches())) {
+ found.add(s);
+ }
+ }
+ return found;
+ }
+
+ /** Returns all strings that match a specific regular expression but not a second one.
+ * @param match regular expression.
+ * @param nomatch regular expression.
+ * @param strings Strings to search.
+ * @return All strings that match the regular expression specified by match but do not match the regular expression specified by nomatch.
+ */
+ public static List<String> find(@NotNull final String match, @Nullable final String nomatch, @NotNull final Iterable<String> strings) {
+ return find(Pattern.compile(match), nomatch != null ? Pattern.compile(nomatch) : null, strings);
+ }
+
+ /** Returns all Strings from the aspell master.
+ * @return List with all words from the aspell master.
+ */
+ @NotNull public static List<String> getAspellMaster() {
+ return executeAndGetLines("aspell dump master");
+ }
+
+ /** Returns all Strings from the aspell master.
+ * @param language Language for which the aspell master shall be retrieved.
+ * @return List with all words from the aspell master in the specified language.
+ */
+ public static List<String> getAspellMaster(@NotNull final String language) {
+ if (!language.matches("^[a-zA-Z_]{2,10}$")) {
+ throw new IllegalArgumentException("Illegal language");
+ }
+ return executeAndGetLines("aspell -l " + language + " dump master");
+ }
+
+ /** Returns the output from executing a command.
+ * @param command Command to execute.
+ * @return The output of the executed command, line by line )without trailing newline character).
+ */
+ public static List<String> executeAndGetLines(@NotNull final String command) {
+ final Runtime runtime = Runtime.getRuntime();
+ try {
+ final Process process = runtime.exec(command);
+ final List<String> lines = new ArrayList<String>();
+ final BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ for (String line; (line = in.readLine()) != null; ) {
+ lines.add(line);
+ }
+ return lines;
+ } catch (final IOException e) {
+ e.printStackTrace();
+ return Collections.EMPTY_LIST;
+ }
+ }
+
+ /** Main program.
+ * @param args Command line arguments (try --help).
+ */
+ public static void main(@NotNull final String... args) {
+ for (final String word : find("[eidrEIDR]+", null, getAspellMaster())) {
+ System.out.println(word);
+ }
+ }
+
+ /** Random number generator. */
+ private static Random random = new Random();
+
+ /** Returns a random String from a List of Strings.
+ * @param strings List from which a random String shall be returned.
+ * @return A random String from that List.
+ */
+ public static String random(@NotNull final List<String> strings) {
+ return strings.get(random.nextInt(strings.size()));
+ }
+}
Property changes on: progs/jtype/trunk/src/prj/net/sf/japi/jtype/Helper.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ LF
Added: progs/jtype/trunk/src/prj/net/sf/japi/jtype/JType.java
===================================================================
--- progs/jtype/trunk/src/prj/net/sf/japi/jtype/JType.java (rev 0)
+++ progs/jtype/trunk/src/prj/net/sf/japi/jtype/JType.java 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1,90 @@
+package net.sf.japi.jtype;
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.JApplet;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import org.jetbrains.annotations.NotNull;
+
+/** JType is a program that measures the speed of typing.
+ * @author <a href="mailto:ch...@ri...">Christian Hujer</a>
+ */
+// TODO:cher:More detailled statistics.
+// TODO:cher:Excercise texts.
+// TODO:cher:Statistics about which characters were mistyped most frequently.
+// TODO:cher:Show keyboard layout.
+// TODO:cher:Make time at which a pause is detected configurable. Maybe use that time for the first char.
+// TODO:cher:Split statistics into recent (e.g. last line, 100 chars), session, day, week and all time.
+// TODO:cher:Per-char-statistics.
+// TODO;cher:Statistics about which character combinations.
+// TODO:cher:Use aspell to generate random word lists automatically.
+public class JType extends JApplet implements WindowListener {
+
+ /** The program frame. */
+ private static JFrame frame;
+
+ /** Main program.
+ * @param args Commandline arguments (currently ignered).
+ */
+ public static void main(@NotNull final String... args) {
+ frame = new JFrame("JType");
+ final JType jtype = new JType();
+ frame.add(jtype);
+ frame.addWindowListener(jtype);
+ frame.pack();
+ frame.setVisible(true);
+ }
+
+ /** Creates a new JType. */
+ public JType() {
+ setLayout(new BorderLayout());
+ final JTextArea textPane = new JTextArea(25, 81);
+ textPane.setLineWrap(true);
+ textPane.setWrapStyleWord(true);
+ final Font oldFont = textPane.getFont();
+ textPane.setFont(new Font(Font.MONOSPACED, oldFont.getStyle(), (int) (oldFont.getSize() * 1.5)));
+ add(new JScrollPane(textPane));
+ final PerformancePane pane = new PerformancePane();
+ add(pane, BorderLayout.SOUTH);
+ textPane.addKeyListener(pane);
+ }
+
+ /** {@inheritDoc} */
+ public void windowOpened(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void windowClosing(@NotNull final WindowEvent e) {
+ frame.dispose();
+ }
+
+ /** {@inheritDoc} */
+ public void windowClosed(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void windowIconified(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void windowDeiconified(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void windowActivated(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void windowDeactivated(@NotNull final WindowEvent e) {
+ // nothing to do
+ }
+}
Property changes on: progs/jtype/trunk/src/prj/net/sf/japi/jtype/JType.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ LF
Added: progs/jtype/trunk/src/prj/net/sf/japi/jtype/PerformancePane.java
===================================================================
--- progs/jtype/trunk/src/prj/net/sf/japi/jtype/PerformancePane.java (rev 0)
+++ progs/jtype/trunk/src/prj/net/sf/japi/jtype/PerformancePane.java 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1,129 @@
+package net.sf.japi.jtype;
+
+import javax.swing.JComponent;
+import javax.swing.JButton;
+import java.awt.event.KeyListener;
+import java.awt.event.KeyEvent;
+import java.awt.FlowLayout;
+import java.awt.Component;
+import java.util.Collection;
+import java.util.ArrayList;
+import net.sf.japi.swing.ActionBuilder;
+import net.sf.japi.swing.ActionBuilderFactory;
+import net.sf.japi.swing.ActionMethod;
+
+/** Display for simple typing statistics.
+ * @author <a href="mailto:ch...@ri...">Christian Hujer</a>
+ */
+public class PerformancePane extends JComponent implements KeyListener {
+
+ /** The ActionBuilder with which the Actions will be built. */
+ private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder(PerformancePane.class);
+
+ /** Default delay after which a keystoke will be treated as new key after a pause. */
+ private static final int DEFAULT_PAUSE_DETECTION_DELAY = 2000;
+
+ /** Delay after which a keystroke will be treated as new key after a pause.
+ * This allows users to pause their excercises without having to explicitely stop the program.
+ */
+ private int pauseDetectionDelay = DEFAULT_PAUSE_DETECTION_DELAY;
+
+ /** The number of keys typed correctly. */
+ private int keyTypes;
+
+ /** The number of keys typed wrongly. */
+ private int correctionTypes;
+
+ /** The timestamp of the previous keystroke. */
+ private long lastTime;
+
+ /** The sum of time all keystrokes took alltogether so far. */
+ private long timeSums;
+
+ private Collection<ReflectionField> reflectionFields = new ArrayList<ReflectionField>();
+
+ /** Creates a PerformancePane. */
+ public PerformancePane() {
+ setLayout(new FlowLayout());
+ reflectionFields.add(new ReflectionField("Speed", "%3f", this, "speed"));
+ reflectionFields.add(new ReflectionField("Correctness", "%3.2f %%", this, "correctness"));
+ for (final Component reflectionField : reflectionFields) {
+ add(reflectionField);
+ }
+ updateDisplay();
+ ACTION_BUILDER.createAction(true, "reset", this);
+ final Component button = new JButton(ACTION_BUILDER.getAction("reset"));
+ button.setFocusable(false);
+ add(button);
+ }
+
+ /** Resets the statistics of this PerformancePane. */
+ @ActionMethod
+ public void reset() {
+ keyTypes = 0;
+ timeSums = 0;
+ correctionTypes = 0;
+ lastTime = 0;
+ updateDisplay();
+ }
+
+ /** Updates the displayed statistics. */
+ public void updateDisplay() {
+ for (final ReflectionField fieldLabelHandler : reflectionFields) {
+ fieldLabelHandler.update();
+ }
+ }
+
+ /** Returns the speed.
+ * @return The speed.
+ */
+ public double getSpeed() {
+ return keyTypes * 1000.0 * 60 / timeSums;
+ }
+
+ /** Returns the correctness.
+ * @return The correctness.
+ */
+ public double getCorrectness() {
+ return keyTypes * 100.0 / (keyTypes + correctionTypes);
+ }
+
+ /** Returns the speed of typing, measured in keystrokes per minute.
+ * @return The speed of typing, measured in keystrokes per minute.
+ */
+ public double getTypingSpeedInKeystrokesPerMinute() {
+ return keyTypes * 1000.0 * 60 / timeSums;
+ }
+
+ /** {@inheritDoc} */
+ public void keyTyped(final KeyEvent e) {
+ final long time = System.currentTimeMillis();
+ final long deltaTime = time - lastTime;
+ if (deltaTime > pauseDetectionDelay) {
+ lastTime = 0;
+ }
+ if (e.getKeyChar() == 8) {
+ correctionTypes++;
+ keyTypes--;
+ } else {
+ keyTypes++;
+ }
+ if (lastTime != 0) {
+ timeSums += deltaTime;
+ } else {
+ timeSums += pauseDetectionDelay;
+ }
+ updateDisplay();
+ lastTime = time;
+ }
+
+ /** {@inheritDoc} */
+ public void keyPressed(final KeyEvent e) {
+ // nothing to do
+ }
+
+ /** {@inheritDoc} */
+ public void keyReleased(final KeyEvent e) {
+ // nothing to do
+ }
+}
Property changes on: progs/jtype/trunk/src/prj/net/sf/japi/jtype/PerformancePane.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ LF
Added: progs/jtype/trunk/src/prj/net/sf/japi/jtype/ReflectionField.java
===================================================================
--- progs/jtype/trunk/src/prj/net/sf/japi/jtype/ReflectionField.java (rev 0)
+++ progs/jtype/trunk/src/prj/net/sf/japi/jtype/ReflectionField.java 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1,77 @@
+package net.sf.japi.jtype;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.awt.GridBagLayout;
+import java.util.Locale;
+import org.jetbrains.annotations.NotNull;
+
+/** A component that displays a property value along with a label.
+ * It uses reflection to get the object's value.
+ * @author <a href="mailto:ch...@ri...">Christian Hujer</a>
+ */
+public class ReflectionField extends JComponent {
+
+ /** The label to update. */
+ private final JLabel label;
+
+ /** The format to create the label text. */
+ private final String format;
+
+ /** The target object from which the field value will be read. */
+ private final Object target;
+
+ /** The method used to retrieve the value of the property. */
+ private final Method getter;
+
+ /** Creates a ReflactionField.
+ * @param label The label that shall be displayed.
+ * @param format The format with which the property value shall be formatted for display.
+ * @param target The target object of which the property value shall be displayed.
+ * @param fieldName The name of the property that shall be displayed.
+ */
+ public ReflectionField(@NotNull final String label, @NotNull final String format, @NotNull final Object target, @NotNull final String fieldName) {
+ setLayout(new GridBagLayout());
+ add(new JLabel(label + ": "));
+ this.label = new JLabel();
+ add(this.label);
+ this.format = format;
+ this.target = target;
+ getter = getGetterMethod(target.getClass(), fieldName);
+
+ }
+
+ /** Updates the display to reflect the latest property value. */
+ public void update() {
+ try {
+ label.setText(String.format(format, getter.invoke(target)));
+ } catch (final IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (final InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Returns a getter method for the specified property of the specified class.
+ * It supports the standard Java / JavaBeans names (isPropertyName() for boolean properties and getPropertyName() for others).
+ * @param clazz Class for which the Getter shall be returned.
+ * @param propertyName Name of the property for which the getter method shall be returned.
+ * @return The getter method for the specified property of the specified class or <code>null</code> if such a getter method cannot be returned.
+ */
+ private static Method getGetterMethod(@NotNull final Class<?> clazz, @NotNull final String propertyName) {
+ final String capName = propertyName.substring(0, 1).toUpperCase(Locale.ENGLISH) + propertyName.substring(1);
+ try {
+ return clazz.getMethod("get" + capName);
+ } catch (final NoSuchMethodException e) {
+ System.err.println(e);
+ try {
+ return clazz.getMethod("is" + capName);
+ } catch (final NoSuchMethodException e1) {
+ System.err.println(e);
+ return null;
+ }
+ }
+ }
+}
Property changes on: progs/jtype/trunk/src/prj/net/sf/japi/jtype/ReflectionField.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ LF
Added: progs/jtype/trunk/src/prj/net/sf/japi/jtype/action.properties
===================================================================
--- progs/jtype/trunk/src/prj/net/sf/japi/jtype/action.properties (rev 0)
+++ progs/jtype/trunk/src/prj/net/sf/japi/jtype/action.properties 2008-10-06 12:44:39 UTC (rev 647)
@@ -0,0 +1 @@
+reset.text=Reset
Property changes on: progs/jtype/trunk/src/prj/net/sf/japi/jtype/action.properties
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ LF
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|