|
|
|
The input method engine SPI enables the development of input
methods in the Java programming language that can be used with any
Java 2 runtime environment. As far as the input method framework is
concerned, an input method consists of two classes implementing the
InputMethodDescriptor
and InputMethod
interfaces, packaged with some additional information as an extension
and installed into a Java runtime. The specifications for the
java.awt.im.spi
package, and the
InputMethodDescriptor
and
InputMethod
interfaces provide the core information that's needed to implement an
input method. This tutorial provides additional information that
makes this task a little easier and helps avoid compatibility
problems between different implementations of the Java 2 platform.
Before the input method framework can start using an input method,
it needs to know about its capabilities. The necessary information is
provided by the input method's implementation of the
InputMethodDescriptor
class. This information is used in
selecting input
methods.
The list of available locales returned by
getAvailableLocales
should only return languages that the input method is really designed
for. For example, a Chinese Pinyin input method that produces
simplified Chinese characters should only return
SIMPLIFIED_CHINESE
,
even if it has a mode that simply lets key events pass through and
thus also makes it possible to write English or Malay. The
InputMethod.setLocale
method on the other hand may return true for a larger set of
languages. The reason is that getAvailableLocales
is
used to decide whether to load and switch to an input
method, which is only worthwhile if the input method handles the
language well, while setLocale
is used to decide whether
to switch away from an input method, which is only
worthwhile if the input method doesn't handle the language at all.
When an input method instance is created, it receives an
InputMethodContext
instance through
setInputMethodContext
.
This instance provides it with all the functionality that it needs to
communicate with the input method framework, the client component, or
the composition window. It lets the input method send information
about composed and committed text using the
dispatchInputMethodEvent
method. And it lets the input method request information from the
client component using the methods it inherits from the
InputMethodRequests
interface.
The input method framework provides the input method with an environment that makes it seem like it is always communicating with an active client component using the on-the-spot input style. If the actual client component is not an active client, or if a different input style is used, then the framework redirects events and requests as needed.
The input method should never try to access the client component directly, as doing so would conflict with the framework's switching and redirection functionality. Instead, the input method should always use the methods provided by its input method context.
Input methods may use a number of different windows to communicate with the user. Windows commonly used by input methods include:
Note: On some other platforms, input methods may also provide a composition window, which shows the composed text. In the Java input method framework, composed text is always displayed by the client component or the input method framework, never by the input method.
It is useful to consider three groups of windows:
Here's how these window groups can be handled by input methods written for the Java 2 platform:
InputMethodContext.createInputMethodWindow
,
typically with attachToInputContext
set to true. They
are opened either in the input method's implementation of
activate
,
or later when needed to respond to user input. They are closed in
the input method's implementations of
deactivate
or
hideWindows
,
or earlier if they are no longer needed.
InputMethodContext.createInputMethodWindow
,
with attachToInputContext
set to false. They are
typically opened in the input method's implementation of
activate
and closed in the input method's implementation of
hideWindows
.
Note that the focus behavior of a window created by
createInputMethodWindow
is implementation dependent. It
may never get the focus, it may get the focus when initially made
visible, or it may get the focus when the user clicks into it. An
input method must be able to handle either case.
To position windows (such as the look-up window) automatically
relative to the composed text, the input method can use the input
method context's
getTextLocation
method. To position windows (such as a status window) automatically
relative to the window containing the current client component, the
input method can register for notifications about that window's
location and state using the input method context's
enableClientWindowNotification
method; it then has to implement the
notifyClientWindowChange
method to receive notifications.
Input methods must call Window.dispose for all windows they create when they are no longer needed. This ensures that the JVM exits when the application terminates all non-daemon threads it started. Please refer to AWT Threading Issues for more information.
The main task of an input method is interpreting user actions in composing text input. The user actions may be typing on the keyboard, using the mouse, handwriting, or speaking.
The
activate
and
deactivate
methods indicate to the input method whether a client component has
the focus and therefore is the target of text input. Typically input
methods only process events to compose text while they're active.
When an input method is active, certain types of events are
dispatched to the input method using the
dispatchEvent
method before they are processed by the client component. The input
method decides for each event whether it wants to handle it. If it
does, it marks the event as consumed so that it is not processed by
the client component.
Note: For key events, input methods should use only KEY_TYPED events to obtain information about characters being entered, and use KEY_PRESSED or KEY_RELEASED events only to obtain information about function keys that don't result in KEY_TYPED events. The mapping from key-presses to characters depends on platforms, hardware, locales, and possibly other factors, and is best left to the underlying operating system.
As text is being composed and committed, the input method needs to
inform the client component about all changes so that the client
component can redraw the text. The input method does this by using
InputMethodContext.dispatchInputMethodEvent
to construct and dispatch input method events to the client
component. Depending on the current event flow model, the input
method framework may redirect the events to its composition window.
Dispatching input method events is the only way for Java input
methods to have composed text displayed.
Composed text is usually marked up with highlight styles that
indicate the current state of the conversion. This is accomplished by
adding attributes to the text using the
TextAttribute.INPUT_METHOD_HIGHLIGHT
key and instances of
InputMethodHighlight
as values. Normally input methods only define abstract highlights
(using the state and selected properties of the input method
highlight) and leave the mapping to concrete styles to the rendering
system. However, if desired, input methods can add concrete style
information to the highlight using the style property. It is a good
idea to design the concrete styles as variations of the styles
provided returned by
Toolkit.mapInputMethodHighlight
.
Both the client component and the input method framework may
recognize situations where the current composition needs to be ended
and all composed text either committed or cancelled. They inform the
input method about this need using the
endComposition
method. Note that endComposition
may be called while the
input method is not active.
Client components can influence composition using several methods.
The
InputContext.setCharacterSubsets
method lets them restrict the subset of the Unicode character set
that the input method is allowed to input. Input methods should
generally not create characters outside of the specified subsets, and
may switch to a different input mode that particularly supports the
specified character subsets. The
InputContext.setCompositionEnabled
and
isCompositionEnabled
methods let them control and examine whether the current input method
is enabled for composition. The
InputContext.reconvert
method lets them initiate reconversion.
Some input methods may want to provide functionality to client
components that can not be made available through the input method
framework API. This is possible through input method control
objects. The input method developer must publish an interface
for these objects, and return instances through
InputMethod.getControlObject
.
Client components that want to take advantage of the additional
functionality can then call
InputContext.getInputMethodControlObject
,
check whether the returned object is an instance of a known control
object class, and if it is, call its methods.
Input methods are packaged as installed extensions with specific content as described in the "Packaging Input Methods" section of the SPI specification. One important aspect to consider is that all extensions installed in a Java application environment share the same name space. To avoid name collisions, input methods should follow the package naming conventions as described in the Java Language Specification. Similar conventions should be applied to naming non-class files that are packaged in the input method JAR file, such as dictionaries.
City Input Method is a simple input method that shows how to use the interfaces provided by the input method engine SPI.
Copyright © 2004 Sun Microsystems, Inc. All Rights Reserved. |
|