This note describes how to detect when ‘enter’ is pressed in an EditText field. It’s helpful for the prefix-word game, but possibly others as well.
Make your activity implement OnEditorActionListener
:
public class MyActivity extends Activity
implements TextView.OnEditorActionListener {
// ...
}
You’ll need to add the method onEditorAction
:
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// This method can be called when you press enter in an EditText
// field. Returning true means we CONSUME the event, and it
// doesn't perform its default action. You probably want to
// ignore the DOWN event, and just respond to UP.
if(event.getAction() != KeyEvent.ACTION_UP) return true;
// Now you can do whatever else you want in response to
// the key press.
// ...
return true;
}
You still have to install this handler in the onCreate
method:
editText = (EditText) findViewById(R.id.editText);
editText.setOnEditorActionListener(this);
and here is how you can initialize the content of the field… both the text it contains, and the position of the cursor:
editText.setText(goalPrefix);
editText.setSelection(goalPrefix.length());
Now, I’ll include the code for the revised Dictionary class I created. It can now choose two-letter prefixes, eliminating those that have only a few words.
package com.example.words;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
public class Dictionary {
HashSet<String> hashSet = new HashSet<String>();
HashMap<String, Integer> prefixes = new HashMap<String, Integer>();
Random rng = new Random();
public Dictionary(InputStream is) {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line1;
int numWords = 0;
try {
line1 = br.readLine();
while(line1 != null) {
if(acceptableWord(line1)) {
if(line1.length() > 2) {
String prefix = line1.substring(0, 2);
Integer k = prefixes.get(prefix);
if(k == null) {
prefixes.put(prefix, 1);
} else {
prefixes.put(prefix, k+1);
}
}
hashSet.add(line1);
numWords++;
}
line1 = br.readLine();
}
} catch(IOException exn) {
line1 = "ERROR!";
}
// temporary: show all prefixes
for(String prefix : prefixes.keySet()) {
int k = prefixes.get(prefix);
if(k > 5) {
System.out.println(prefix + " => " + prefixes.get(prefix));
}
}
}
public String choosePrefix() {
int n = prefixes.size();
int k = rng.nextInt(n);
for(String prefix : prefixes.keySet()) {
if(k == 0) {
return prefix;
}
k--;
}
return "ERROR";
}
public boolean acceptableWord(String word) {
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(!Character.isLowerCase(c)) return false;
}
return true;
}
public boolean contains(String word) {
return hashSet.contains(word);
}
public int getNumWords() {
return hashSet.size();
}
public static void testWord(Dictionary d, String word) {
System.out.println(word + ": " + d.hashSet.contains(word));
}
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Hello.");
Dictionary d = new Dictionary(new FileInputStream("/usr/share/dict/words"));
testWord(d, "elephant");
testWord(d, "anvil");
testWord(d, "koala");
testWord(d, "aroceuhalcue");
testWord(d, "junkkkk");
testWord(d, "helllllllllllllllllllllllllo");
System.out.println(d.hashSet.size() + "words");
for(int i = 0; i < 10; i++) {
System.out.println("Sample prefix: " + d.choosePrefix());
}
}
}
Here is the tail end of the output when we run Dictionary.main
as a test program.
elephant: true
anvil: true
koala: true
aroceuhalcue: false
junkkkk: false
helllllllllllllllllllllllllo: false
64147words
Sample prefix: ke
Sample prefix: ep
Sample prefix: dé
Sample prefix: eu
Sample prefix: gi
Sample prefix: it
Sample prefix: la
Sample prefix: ll
Sample prefix: éc
Sample prefix: gr
We’ll probably want to find a way to eliminate those accented characters, so that prefixes like éc
don’t show up… unless you’re playing the game in French!