Button
rely on native objects
Button
peer is a Motif object
XmPushButton
, which is written in C
XmPushButton
) recognises
that it has been "clicked" and generates an action event
JButton
rely only on simple mechanisms such
as drawing lines and strings - a Swing object does not rely on an
associated peer object
This program uses a listener to change all keys to upper case
import java.awt.*;
import java.awt.event.*;
public class MapKey extends Frame {
public static void main(String argv[]) {
new MapKey().setVisible(true);
}
public MapKey() {
TextField text = new TextField(20);
add(text);
pack();
text.addKeyListener(new ToUpper());
}
}
class ToUpper implements KeyListener {
public void keyTyped(KeyEvent e) {
char ch = e.getKeyChar();
System.out.println("Key typed was: " + ch);
ch = Character.toUpperCase(ch);
e.setKeyChar(ch);
// empty
}
public void keyPressed(KeyEvent e) {
//e.setModifiers(Event.SHIFT_MASK);
char ch = e.getKeyChar();
System.out.println("Key typed was: " + ch);
ch = Character.toUpperCase(ch);
e.setKeyChar(ch);
}
public void keyReleased(KeyEvent e) {
// empty
}
}
The following program only accepts alphabetic characters
import java.awt.*;
import java.awt.event.*;
public class AlphaOnly extends Frame implements KeyListener {
public static void main(String argv[]) {
new AlphaOnly().setVisible(true);
}
public AlphaOnly() {
TextField text = new TextField(20);
add(text);
pack();
text.addKeyListener(this);
}
public void keyTyped(KeyEvent e) {
char ch = e.getKeyChar();
System.out.println("Key typed: " + ch);
if (! Character.isLetter(ch)) {
Toolkit.getDefaultToolkit().beep();
// we don't want it - stop it from getting
// to the text field
e.consume();
}
}
public void keyPressed(KeyEvent e) {
char ch = e.getKeyChar();
System.out.println("Key typed: " + ch);
if (! Character.isLetter(ch)) {
Toolkit.getDefaultToolkit().beep();
// we don't want it - stop it from getting
// to the text field
e.consume();
}
// empty
}
public void keyReleased(KeyEvent e) {
// empty
}
}
paint(Graphics g)
method
Graphics
object has methods such as drawLine()
,
drawChars()
etc
Graphics.drawString(AttributedStringIterator, int, int)
uses a string which has additional "attribute markers" added to it
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.font.*;
import java.text.*;
public class Attributes extends Frame {
public static void main(String argv[]) {
new Attributes().setVisible(true);
}
public Attributes() {
setSize(200, 200);
}
public void paint(Graphics g) {
AttributedString astr = new AttributedString("aLongishString");
// Apply styles to text
// Strikethrough on a red background
Font font = new Font("Dialog,", Font.PLAIN, 16);
Color red = Color.RED;
int start = 2;
int end = 4;
astr.addAttribute(TextAttribute.FONT, font, start, end);
astr.addAttribute(TextAttribute.BACKGROUND, red, start, end);
astr.addAttribute(TextAttribute.STRIKETHROUGH, new Boolean(true), start, end);
// Italic on a blue background
font = new Font("Serif", Font.ITALIC, 24);
Color blue = Color.BLUE;
start = 6;
end = 10;
astr.addAttribute(TextAttribute.FONT, font, start, end);
astr.addAttribute(TextAttribute.BACKGROUND, blue, start, end);
// Draw mixed-style text
g.drawString(astr.getIterator(), 30, 40);
}
}
From Concepts in C/UNIX Internationalisation
The following text editor uses a very naive way of entering unicode text. It uses on-the-spot pre-editing
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
/** A simple editor to enter Unicode text
* Does NOT use the Java input methods.
* Whenever the sequence \\uXXXX of 4 hex digits
* is seen, it is replaced with its Unicode value
*/
public class SimpleUnicodeEditor extends JFrame implements KeyListener {
private static int NONE = 0;
private static int ESCAPE = 1;
private static int ESCAPE_U = 2;
private static int FIRST = 3;
private static int SECOND = 4;
private static int THIRD = 5;
private JTextArea text;
private int state;
private StringBuffer unicodeText = new StringBuffer();
public static void main(String[] args) {
SimpleUnicodeEditor editor = new SimpleUnicodeEditor();
editor.pack();
editor.setVisible(true);
}
public SimpleUnicodeEditor() {
Container contentPane = getContentPane();
text = new JTextArea(20,100);
contentPane.setLayout(new BorderLayout());
contentPane.add(text, BorderLayout.CENTER);
text.addKeyListener(this);
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
char ch = e.getKeyChar() ;
switch (ch) {
case '\\':
state = ESCAPE;
break;
case 'u':
if (state == ESCAPE) {
state = ESCAPE_U;
} else {
state = NONE;
}
break;
default:
if (isHexDigit(ch)) {
if (state == NONE) {
// nothing
} else
if ((state == ESCAPE_U)) {
unicodeText.setLength(0);
unicodeText.append(ch);
state = FIRST;
} else
if (state == FIRST) {
unicodeText.append(ch);
state = SECOND;
} else
if (state == SECOND) {
unicodeText.append(ch);
state = THIRD;
} else
if (state == THIRD) {
unicodeText.append(ch);
// we've now seen the 4th digit
convertUnicode();
state = NONE;
// lose this 4th character
e.consume();
}
} else {
state = NONE;
}
}
}
private boolean isHexDigit(char ch) {
return (Character.digit(ch, 16) != -1);
}
private void convertUnicode() {
char unicodeValue = 0;
try {
unicodeValue = (char) Integer.valueOf(unicodeText.toString(), 16).intValue();
} catch (NumberFormatException e) {
// nothing
}
String s = text.getText();
int length = s.length();
text.replaceRange("" + unicodeValue, length-5, length);
}
}
jar
files that
are placed in standard locations
InputMethodHotKey
can be used to define a hot key:
java -jar InputMethodHotKey.jar
This shows a GUI that can be used to set a hot key for all Java
applications.
This jar file can be downloaded from http://java.sun.com/products/jfc/tsc/articles/InputMethod/inputmethod.html
text = ...
locale = ...
InputContext context = text.getInputContext();
context.selectInputMethod(locale);
Method 1: don't change the application, let the user choose by hotkeys or system menu
import java.util.Locale;
import java.awt.im.spi.InputMethodDescriptor;
import javax.swing.*;
import java.awt.*;
import java.awt.im.InputContext;
public class TestInputMethod extends JFrame {
public static void main(String[] args) {
TestInputMethod test = new TestInputMethod();
JTextArea text = new JTextArea(20, 200);
Font font = new Font("Courier", Font.PLAIN, 24);
text.setFont(font);
test.getContentPane().add(text, BorderLayout.NORTH);
test.pack();
test.setVisible(true);
}
}
While this is running, use the hot key or the system menu to get a selection
of input methods
Method 2: code the input method into the application
import java.util.Locale;
import java.awt.im.spi.InputMethodDescriptor;
import javax.swing.*;
import java.awt.*;
import java.awt.im.InputContext;
public class TestPigLatinInputMethod extends JFrame {
public static void main(String[] args) {
InputContext context = InputContext.getInstance();
if (context.selectInputMethod(PigLatinInputMethodDescriptor.PIG_LATIN_LOCALE)) {
System.out.println("Pig latin available");
} else {
System.out.println("Pig latin not available");
}
InputMethodDescriptor pigLatinDesc = new PigLatinInputMethodDescriptor();
try {
Locale[] inputLocales = pigLatinDesc.getAvailableLocales();
for (int n = 0; n < inputLocales.length; n++) {
System.out.println(inputLocales[n].toString());
}
} catch (java.awt.AWTException e) {
e.printStackTrace();
}
TestPigLatinInputMethod test = new TestPigLatinInputMethod();
JTextArea text = new JTextArea(20, 200);
Font font = new Font("Courier", Font.PLAIN, 24);
text.setFont(font);
test.getContentPane().add(text, BorderLayout.NORTH);
context = text.getInputContext();
if (context.selectInputMethod(PigLatinInputMethodDescriptor.PIG_LATIN_LOCALE)) {
System.out.println("Pig latin set for JText");
} else {
System.out.println("Pig latin not set for JText");
}
test.pack();
test.setVisible(true);
}
}
java.awt.im.style
:
java -Djava.awt.im.style="below-the-spot" ...
x-pig-latin
is unofficially
recognised as a possible value for the LANG
Locale PIG_LATIN_LOCALE = new Locale("en", "", "x-pig-latin")
InputMethodDescriptor
class
public interface InputMethodDescriptor {
InputMethod createInputMethod();
Locale[] getAvailableLocales();
String getInputMethodDisplayName(Locale inputLocale,
Locale displayLanguage);
Image getInputMethodIcon(Locale inputLocale);
boolean hasDynamicLocaleList();
}
import java.awt.Image;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Locale;
/**
* Provides sufficient information about an input method
* to enable selection and loading of that input method.
* The input method itself is only loaded when it is actually used.
*/
public class PigLatinInputMethodDescriptor implements InputMethodDescriptor {
public static Locale PIG_LATIN_LOCALE = new Locale("en", "", "x-pig-latin");
public PigLatinInputMethodDescriptor() {
}
/**
* @see java.awt.im.spi.InputMethodDescriptor#getAvailableLocales
*/
public Locale[] getAvailableLocales() {
Locale[] locales = {
PIG_LATIN_LOCALE
};
return locales;
}
/**
* @see java.awt.im.spi.InputMethodDescriptor#hasDynamicLocaleList
*/
public boolean hasDynamicLocaleList() {
return false;
}
/**
* @see java.awt.im.spi.InputMethodDescriptor#getInputMethodDisplayName
*/
public synchronized String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage) {
if (inputLocale == PIG_LATIN_LOCALE) {
return("PigLatin English");
} else if (inputLocale != null) {
return "PigLatin English - " + inputLocale.getCountry();
} else {
return "PigLatin English Method";
}
return null;
}
/**
* @see java.awt.im.spi.InputMethodDescriptor#getInputMethodIcon
*/
public Image getInputMethodIcon(Locale inputLocale) {
return null;
}
/**
* @see java.awt.im.spi.InputMethodDescriptor#getInputMethodClassName
*/
public InputMethod createInputMethod() throws Exception {
System.out.println("Creating pig latin input method");
return new PigLatinInputMethod();
}
}
InputMethodDescriptor
provides one level of indirection:
it describes what locales can be handled before instantiating the code
to do this
InputMethodDescriptor
's have to be made available to the
Java runtime
jar
file containing
InputMethodDescriptor
implementation file
(e.g. PigLatinInputMethodDescriptor.class
InputMethod
implementation file could
optionally go in this jar
file, or be accessible
to a Java application by the classpath
setting
META-INF/services/java.awt.im.spi.InputMethodDescriptor
PigLatinInputMethodDescriptor
jar
file by
jar cvf my_input.jar META-INF <class files>
$JAVA_HOME/jre/lib/ext
java -Djava.ext.dirs=<input descriptor dir> ...
// required by InputMethod
import java.awt.im.spi.InputMethod;
import java.awt.Rectangle;
import java.awt.im.spi.InputMethodContext;
import java.util.Locale;
import java.awt.AWTEvent;
// required by implementation
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.awt.event.InputMethodEvent;
import java.awt.font.TextHitInfo;
import java.text.AttributedString;
import java.awt.im.InputMethodHighlight;
import java.awt.*;
public class PigLatinInputMethod implements InputMethod {
private static Locale[] SUPPORTED_LOCALES = {
PigLatinInputMethodDescriptor.PIG_LATIN_LOCALE
};
private Locale locale;
private InputMethodContext inputMethodContext;
private StringBuffer rawText = new StringBuffer();
// private String convertedText;
private static Window statusWindow;
public void activate() {
// Activates the input method for immediate input processing.
// do nothing
}
public void deactivate(boolean isTemporary) {
// Deactivates the input method.
}
public void dispatchEvent(AWTEvent event) {
// Dispatches the event to the input method.
if (event.getID() == KeyEvent.KEY_TYPED) {
KeyEvent e = (KeyEvent) event;
if (handleCharacter(e.getKeyChar())) {
e.consume();
}
}
// Also handle selection by mouse here
}
public void dispose() {
// Disposes of the input method and releases the resources used by it.
System.out.println("Pig latin di-XXX");
}
public void endComposition() {
// Ends any input composition that may currently be going on in this context.
String convertedText = convert(rawText);
if (convertedText != null) {
commit(convertedText);
}
}
public Object getControlObject() {
// Returns a control object from this input method, or null.
// not supported yet
System.out.println("Pig latin gc-XXX");
return null;
}
public Locale getLocale() {
// Returns the current input locale.
return locale;
}
public void hideWindows() {
// Closes or hides all windows opened by this input method instance or its class.
}
public boolean isCompositionEnabled() {
// Determines whether this input method is enabled.
// always enabled
return true;
}
public void notifyClientWindowChange(Rectangle bounds) {
// Notifies this input method of changes in the client window location or state.
// not supported yet
System.out.println("Pig latin nw-XXX");
throw new UnsupportedOperationException();
}
public void reconvert() {
// Starts the reconversion operation.
// not supported yet
System.out.println("Pig latin re-XXX");
throw new UnsupportedOperationException();
}
public void removeNotify() {
// Notifies the input method that a client component has been removed from its containment hierarchy, or that input method support has been disabled for the component.
// not supported yet
System.out.println("Pig latin rn-XXX");
throw new UnsupportedOperationException();
}
public void setCharacterSubsets(Character.Subset[] subsets) {
// Sets the subsets of the Unicode character set that this input method is allowed to input.
// not supported yet
System.out.println("Pig latin sc-XXX");
return;
// throw new UnsupportedOperationException();
}
public void setCompositionEnabled(boolean enable) {
// Enables or disables this input method for composition, depending on the value of the parameter enable.
// not supported yet
System.out.println("Pig latin sce-XXX");
throw new UnsupportedOperationException();
}
public void setInputMethodContext(InputMethodContext context) {
// Sets the input method context, which is used to dispatch input method events to the client component and to request information from the client component.
inputMethodContext = context;
System.out.println("Input context set " + context);
/*
// if (statusWindow == null) {
statusWindow = context.createInputMethodWindow("Simp. Chinese Pinyin", false);
Label label = new Label("Pig Latin locale");
label.setBackground(Color.white);
statusWindow.add(label);
// updateStatusWindow(locale);
label.setSize(200, 50);
statusWindow.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
statusWindow.setLocation(d.width - statusWindow.getWidth(),
d.height - statusWindow.getHeight());
// }
*/
}
public boolean setLocale(Locale locale) {
// Attempts to set the input locale.
for (int i = 0; i < SUPPORTED_LOCALES.length; i++) {
if (locale.equals(SUPPORTED_LOCALES[i])) {
this.locale = locale;
/*
if (statusWindow != null) {
updateStatusWindow(locale);
}
*/
System.out.println("Locale set");
return true;
}
}
System.out.println("Locale not set");
return false;
}
/**
* Attempts to handle a typed character.
* @return whether the character was handled
*/
private boolean handleCharacter(char ch) {
System.out.println("handling char \"" + ch + "\"");
if (isEndChar(ch)) {
String convertedText = convert(rawText);
if (convertedText != null) {
commit(convertedText + ch);
return true;
}
// let the end char be passed on
return false;
}
if (ch == '\b') {
// backspace - delete char
if (rawText.length() != 0) {
rawText.setLength(rawText.length() - 1);
sendRawText();
return true;
}
} else if (Character.isLetter(ch)) {
rawText.append(ch);
sendRawText();
return true;
}
return false;
}
private boolean isEndChar(char ch) {
if (Character.isWhitespace(ch)) {
return true;
} else {
// Unicode category Po, Terminal punctuation: !,. etc
if (Character.getType(ch) == Character.OTHER_PUNCTUATION) {
return true;
}
}
return false;
}
private boolean isVowel(char ch) {
// we are in English - vowels are easy!
switch (Character.toLowerCase(ch)) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
private String convert(StringBuffer rawText) {
if (rawText.length() == 0) {
return null;
}
InputMethodHighlight highlight;
String convertedText = null;
// if the rawText begins with a vowel, add "yay" to the end
if (isVowel(rawText.charAt(0))) {
convertedText = rawText + "yay";
} else {
// move first consonant group to end and add "ay"
int n = 0;
while ( ! isVowel(rawText.charAt(n))) {
n++;
}
convertedText = rawText.substring(n, rawText.length()) +
rawText.substring(0, n) +
"ay";
}
return convertedText;
}
private void commit(String text) {
sendConvertedText(text);
rawText.setLength(0);
}
private void sendConvertedText(String convertedText) {
InputMethodHighlight highlight;
highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
AttributedString as = new AttributedString(convertedText);
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
convertedText.length(),
TextHitInfo.leading(convertedText.length()),
null);
}
private void sendRawText() {
String text = rawText.toString();
InputMethodHighlight highlight;
AttributedString as = new AttributedString(text);
highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
0,
null,
null);
}
}
// required by InputMethod
import java.awt.im.spi.InputMethod;
import java.awt.Rectangle;
import java.awt.im.spi.InputMethodContext;
import java.util.Locale;
import java.awt.AWTEvent;
// required by implementation
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.awt.event.InputMethodEvent;
import java.awt.font.TextHitInfo;
import java.text.AttributedString;
import java.awt.im.InputMethodHighlight;
import java.awt.*;
import javax.swing.*;
import java.util.Vector;
import java.io.*;
public class EnglishCompletionInputMethod implements InputMethod {
private static Locale[] SUPPORTED_LOCALES = {
Locale.ENGLISH
};
private Locale locale;
private InputMethodContext inputMethodContext;
private StringBuffer rawText = new StringBuffer();
// private String convertedText;
private boolean wordTerminated;
private static Window statusWindow;
private Window lookupWindow;
private JList list;
private Vector words;
public EnglishCompletionInputMethod() {
loadWords();
}
private void loadWords() {
// should pick up the filename from a property and the current locale
String filename = "english_words_en_UK";
words = new Vector();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
} catch (IOException e) {
System.err.println("Word file not found");
return;
}
String line;
try {
while ((line = in.readLine()) != null) {
words.add(line);
}
} catch (IOException e) {
// ignore
}
}
String [] completedWords() {
Vector completions = new Vector();
String rawWord = rawText.toString();
for (int n = 0; n < words.size(); n++) {
String word = (String) words.get(n);
if (word.startsWith(rawWord)) {
completions.add(word);
}
}
String[] returnArray = new String[completions.size()];
return (String[]) completions.toArray(returnArray);
}
public void activate() {
// Activates the input method for immediate input processing.
// do nothing
}
public void deactivate(boolean isTemporary) {
// Deactivates the input method.
}
public void dispatchEvent(AWTEvent event) {
// Dispatches the event to the input method.
if (event.getID() == KeyEvent.KEY_TYPED) {
KeyEvent e = (KeyEvent) event;
if (handleCharacter(e.getKeyChar())) {
e.consume();
}
}
// Also handle selection by mouse here
}
public void dispose() {
// Disposes of the input method and releases the resources used by it.
System.out.println("English completion di-XXX");
}
public void endComposition() {
// Ends any input composition that may currently be going on in this context.
String convertedText = convert(rawText);
if (convertedText != null) {
commit(convertedText);
}
}
public Object getControlObject() {
// Returns a control object from this input method, or null.
// not supported yet
System.out.println("English completion gc-XXX");
return null;
}
public Locale getLocale() {
// Returns the current input locale.
return locale;
}
public void hideWindows() {
// Closes or hides all windows opened by this input method instance or its class.
}
public boolean isCompositionEnabled() {
// Determines whether this input method is enabled.
// always enabled
return true;
}
public void notifyClientWindowChange(Rectangle bounds) {
// Notifies this input method of changes in the client window location or state.
// not supported yet
System.out.println("English completion nw-XXX");
throw new UnsupportedOperationException();
}
public void reconvert() {
// Starts the reconversion operation.
// not supported yet
System.out.println("English completion re-XXX");
throw new UnsupportedOperationException();
}
public void removeNotify() {
// Notifies the input method that a client component has been removed from its containment hierarchy, or that input method support has been disabled for the component.
// not supported yet
System.out.println("English completion rn-XXX");
throw new UnsupportedOperationException();
}
public void setCharacterSubsets(Character.Subset[] subsets) {
// Sets the subsets of the Unicode character set that this input method is allowed to input.
// not supported yet
System.out.println("English completion sc-XXX");
return;
// throw new UnsupportedOperationException();
}
public void setCompositionEnabled(boolean enable) {
// Enables or disables this input method for composition, depending on the value of the parameter enable.
// not supported yet
System.out.println("English completion sce-XXX");
throw new UnsupportedOperationException();
}
public void setInputMethodContext(InputMethodContext context) {
// Sets the input method context, which is used to dispatch input method events to the client component and to request information from the client component.
inputMethodContext = context;
System.out.println("Input context set " + context);
/*
// if (statusWindow == null) {
statusWindow = context.createInputMethodWindow("Simp. Chinese Pinyin", false);
Label label = new Label("Pig Latin locale");
label.setBackground(Color.white);
statusWindow.add(label);
// updateStatusWindow(locale);
label.setSize(200, 50);
statusWindow.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
statusWindow.setLocation(d.width - statusWindow.getWidth(),
d.height - statusWindow.getHeight());
// }
*/
}
public boolean setLocale(Locale locale) {
// Attempts to set the input locale.
for (int i = 0; i < SUPPORTED_LOCALES.length; i++) {
if (locale.equals(SUPPORTED_LOCALES[i])) {
this.locale = locale;
/*
if (statusWindow != null) {
updateStatusWindow(locale);
}
*/
System.out.println("Locale set");
return true;
}
}
System.out.println("Locale not set");
return false;
}
/**
* Attempts to handle a typed character.
* @return whether the character was handled
*
* States that need to be looked at:
* - user is typing characters for composition
* - user has asked for alternative completions
* - user is asking for text to be committed
*/
private boolean handleCharacter(char ch) {
System.out.println("handling char \"" + ch + "\"");
System.out.println("raw is " + rawText);
if (lookupWindow != null) {
handleLookupWindow(ch);
// ch handled
return true;
}
if (wordTerminated) {
if (ch == ' ') {
// double spaces are a signal to bring up the
// word completion window
invokeLookupWindow();
// ch handled
return true;
}
// else we just assume this is a word separator and carry on
commitRawText();
wordTerminated = false;
// we used the space char to get into this state.
// We are about to resume "in word state" so we
// should pass on the space char first
sendConvertedText(" ");
// return to "in word state" with this char
rawText = new StringBuffer("" + ch);
sendRawText();
// ch handled
return true;
}
if (ch == ' ') {
wordTerminated = true;
// ch handled
return true;
}
if (Character.isLetter(ch)) {
appendRawText(ch);
// ch handled
return true;
}
// ch not handled
return false;
}
private void invokeLookupWindow() {
// stub
System.out.println("invoked lookup wondow");
lookupWindow = inputMethodContext.createInputMethodWindow("Lookup Window", true);
// make a list of possible completions
/*
String[] data = new String[] {
rawText.toString(),
rawText.toString()+rawText.toString(),
rawText.toString()+rawText.toString()+rawText.toString()
};
*/
String [] data = completedWords();
list = new JList(data);
list.setSelectedIndex(0);
lookupWindow.setLayout(new BorderLayout());
lookupWindow.add(list, BorderLayout.CENTER);
lookupWindow.setSize(200, 300);
lookupWindow.setVisible(true);
}
private void handleLookupWindow(char ch) {
if (ch == '\n') {
System.out.println("Committing lookup window");
String selection = (String) list.getSelectedValue();
rawText.setLength(0);
rawText.append(selection);
commitRawText();
wordTerminated = false;
lookupWindow.setVisible(false);
lookupWindow = null;
} else {
// move to next possibility
if (ch == ' ') {
list.setSelectedIndex(list.getSelectedIndex() + 1);
}
}
// stub
}
private void commitRawText() {
String converted = convert(rawText);
commit(converted);
}
private void appendRawText(char ch) {
rawText.append(ch);
sendRawText();
}
private String convert(StringBuffer rawText) {
if (rawText.length() == 0) {
return "";
}
InputMethodHighlight highlight;
String convertedText = rawText.toString();
return convertedText;
}
private void commit(String text) {
sendConvertedText(text);
rawText.setLength(0);
}
private void sendConvertedText(String convertedText) {
InputMethodHighlight highlight;
highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
AttributedString as = new AttributedString(convertedText);
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
convertedText.length(),
TextHitInfo.leading(convertedText.length()),
null);
}
private void sendRawText() {
String text = rawText.toString();
System.out.println("send raw text: " + text);
InputMethodHighlight highlight;
AttributedString as = new AttributedString(text);
highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
0,
null,
null);
}
}