mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-3713 add translit input method tool to icu4j
X-SVN-Rev: 15010
This commit is contained in:
parent
24bc2f870c
commit
9a8ce89bc6
6 changed files with 627 additions and 0 deletions
|
@ -81,6 +81,9 @@
|
|||
<property name="icu4j.manifest" value="${src.dir}/com/ibm/icu/manifest.stub"/>
|
||||
<property name="icu4j.module.manifest" value="${src.dir}/com/ibm/icu/manifest.module.stub"/>
|
||||
<property name="icu4j.tests.manifest" value="${src.dir}/com/ibm/icu/dev/test/manifest.test.stub"/>
|
||||
<property name="ime.manifest" value="${src.dir}/com/ibm/icu/dev/tool/ime/manifest.stub"/>
|
||||
<property name="ime.jar.file" value="icutransime.jar"/>
|
||||
<property name="ime.dir" value="tmp${DSTAMP}"/>
|
||||
<property name="zip.file" value="../icu4j${DSTAMP}.zip"/>
|
||||
<property name="zipSrc.file" value="../icu4jSrc${DSTAMP}.zip"/>
|
||||
|
||||
|
@ -266,6 +269,43 @@
|
|||
manifest="${icu4j.manifest}"/>
|
||||
</target>
|
||||
|
||||
<target name="imeJar" depends="collator, transliterator">
|
||||
<javac includes="com/ibm/icu/dev/tool/ime/*.java"
|
||||
excludes="**/CVS/**/*"
|
||||
srcdir="${src.dir}"
|
||||
destdir="${build.dir}"
|
||||
classpathref="build.classpath"
|
||||
debug="on" deprecation="off"/>
|
||||
<jar jarfile="${ime.jar.file}"
|
||||
compress="true"
|
||||
basedir="${build.dir}"
|
||||
includes="com/ibm/icu/dev/tool/ime/**/*"
|
||||
manifest="${ime.manifest}">
|
||||
|
||||
<metainf dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="services/*"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="imeStandaloneJar" depends="collator, transliterator">
|
||||
<javac includes="com/ibm/icu/dev/tool/ime/*.java"
|
||||
excludes="**/CVS/**/*"
|
||||
srcdir="${src.dir}"
|
||||
destdir="${build.dir}"
|
||||
classpathref="build.classpath"
|
||||
debug="on" deprecation="off"/>
|
||||
<copy toDir="${build.dir}/com/ibm/icu/dev/tool/ime">
|
||||
<fileset dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="*.properties"/>
|
||||
</copy>
|
||||
<jar jarfile="${ime.jar.file}"
|
||||
compress="true"
|
||||
basedir="${build.dir}"
|
||||
includes="com/ibm/icu/util/**/*,com/ibm/icu/text/**/*,com/ibm/icu/math/**/*,com/ibm/icu/impl/**/*,com/ibm/icu/lang/**/*,com/ibm/icu/dev/tool/ime/**/*"
|
||||
manifest="${ime.manifest}">
|
||||
|
||||
<metainf dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="services/*"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<!-- jars up richedit but without tests -->
|
||||
<target name="richeditJar" depends="richedit">
|
||||
<mkdir dir="${richedit.dir}"/>
|
||||
|
|
11
icu4j/src/com/ibm/icu/dev/tool/ime/Transliterator.properties
Normal file
11
icu4j/src/com/ibm/icu/dev/tool/ime/Transliterator.properties
Normal file
|
@ -0,0 +1,11 @@
|
|||
name=ICU Transliterator
|
||||
title=ICU Transliterator Input Method
|
||||
start=Please wait, loading transliterators
|
||||
activeError=Dispatch method called while the IME was inactive
|
||||
disposedError=Dispatch called after IME was disposed
|
||||
inputError=Dispatch called without an InputEvent
|
||||
activateError=IME is already active
|
||||
deactivateError=IME is already deactivated
|
||||
hideError=Cannot hide IME while active
|
||||
disposeError=Cannot dispose IME while active
|
||||
multipleDisposeError=IME is already disposed
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* ===========================================================================
|
||||
* IBM ICU Transliterator IME - TransliteratorInputMethod.java version 1.0
|
||||
* (C) Copyright IBM Corp. 2004. All Rights Reserved
|
||||
* ===========================================================================
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.tool.ime;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.im.spi.InputMethod;
|
||||
import java.awt.im.spi.InputMethodContext;
|
||||
import java.text.AttributedString;
|
||||
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.ReplaceableString;
|
||||
import com.ibm.icu.text.Collator;
|
||||
|
||||
|
||||
public class TransliteratorInputMethod implements InputMethod {
|
||||
|
||||
// windows - shared by all instances of this input method
|
||||
private static Window statusWindow;
|
||||
|
||||
// current or last statusWindow owner instance
|
||||
private static TransliteratorInputMethod statusWindowOwner;
|
||||
|
||||
// true if Solaris style; false if PC style
|
||||
private static boolean attachedStatusWindow = false;
|
||||
|
||||
// remember the statusWindow location per instance
|
||||
private Rectangle clientWindowLocation;
|
||||
|
||||
// status window location in PC style
|
||||
private static Point globalStatusWindowLocation;
|
||||
|
||||
// keep live input method instances (synchronized using statusWindow)
|
||||
private static HashSet inputMethodInstances = new HashSet(5);
|
||||
|
||||
|
||||
// per-instance state
|
||||
InputMethodContext inputMethodContext;
|
||||
private boolean active;
|
||||
private boolean disposed;
|
||||
private StringBuffer rawText;
|
||||
private Transliterator transliterator = null;
|
||||
private Transliterator.Position index = null;
|
||||
private ReplaceableString replaceableText = null;
|
||||
private ResourceBundle rb = null;
|
||||
|
||||
public TransliteratorInputMethod() {
|
||||
rawText = new StringBuffer();
|
||||
replaceableText = new ReplaceableString(rawText);
|
||||
try {
|
||||
rb = ResourceBundle.getBundle("com.ibm.icu.dev.tool.ime.Transliterator");
|
||||
}
|
||||
catch(MissingResourceException m) {
|
||||
System.out.println("Transliterator resources missing: " + m);
|
||||
}
|
||||
}
|
||||
|
||||
public void setInputMethodContext(InputMethodContext context) {
|
||||
inputMethodContext = context;
|
||||
String title = null;
|
||||
|
||||
if (statusWindow == null) {
|
||||
try {
|
||||
title = rb.getString("title");
|
||||
}
|
||||
catch (MissingResourceException m) {
|
||||
title = "Transliterator Input Method";
|
||||
}
|
||||
|
||||
Window sw = context.createInputMethodWindow(title, false);
|
||||
|
||||
// This is to fix a problem in Java 1.4
|
||||
try {
|
||||
sw.setFocusableWindowState(true);
|
||||
}
|
||||
catch(NoSuchMethodError err) {
|
||||
/* we do not need to worry about catching this, the setFocusableWindowState
|
||||
only exists in Java 1.4. In Java 1.3 it is not necessary to make the
|
||||
status window focusable, because the default setting is focusable. */
|
||||
}
|
||||
|
||||
// get all the ICU Transliterators
|
||||
Enumeration e = Transliterator.getAvailableIDs();
|
||||
TreeSet types = new TreeSet(new LabelComparator());
|
||||
|
||||
while(e.hasMoreElements()) {
|
||||
String id = (String) e.nextElement();
|
||||
String name = Transliterator.getDisplayName(id);
|
||||
JLabel label = new JLabel(name);
|
||||
label.setName(id);
|
||||
types.add(label);
|
||||
}
|
||||
|
||||
// add the transliterators to the combo box
|
||||
System.out.println("types: " + types);
|
||||
|
||||
JComboBox choices = new JComboBox(types.toArray());
|
||||
|
||||
choices.setEditable(false);
|
||||
choices.setRenderer(new NameRenderer());
|
||||
choices.setActionCommand("transliterator");
|
||||
|
||||
synchronized (this.getClass()) {
|
||||
if (statusWindow == null) {
|
||||
statusWindow = sw;
|
||||
statusWindow.addComponentListener(new ComponentListener() {
|
||||
public void componentResized(ComponentEvent e) {}
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
synchronized (statusWindow) {
|
||||
if (!attachedStatusWindow) {
|
||||
Component comp = e.getComponent();
|
||||
if (comp.isVisible()) {
|
||||
globalStatusWindowLocation = comp.getLocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void componentShown(ComponentEvent e) {}
|
||||
public void componentHidden(ComponentEvent e) {}
|
||||
});
|
||||
|
||||
// setup the listener, to handle selection of a transliterator
|
||||
choices.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JComboBox cb = (JComboBox)e.getSource();
|
||||
JLabel item = (JLabel)cb.getSelectedItem();
|
||||
|
||||
// construct the actual transliterator
|
||||
// commit any text that may be present first
|
||||
commitAll();
|
||||
transliterator = Transliterator.getInstance(item.getName());
|
||||
index = new Transliterator.Position();
|
||||
rawText.setLength(0);
|
||||
index.contextLimit = replaceableText.length();
|
||||
index.contextStart = 0;
|
||||
index.start = 0;
|
||||
index.limit = replaceableText.length();
|
||||
}
|
||||
});
|
||||
statusWindow.add(choices);
|
||||
statusWindowOwner = this;
|
||||
updateStatusWindow();
|
||||
statusWindow.pack();
|
||||
choices.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
inputMethodContext.enableClientWindowNotification(this, attachedStatusWindow);
|
||||
synchronized (statusWindow) {
|
||||
inputMethodInstances.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setLocale(Locale locale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
|
||||
void updateStatusWindow() {
|
||||
synchronized (statusWindow) {
|
||||
statusWindow.pack();
|
||||
if (attachedStatusWindow) {
|
||||
if (clientWindowLocation != null) {
|
||||
statusWindow.setLocation(clientWindowLocation.x,
|
||||
clientWindowLocation.y + clientWindowLocation.height);
|
||||
}
|
||||
} else {
|
||||
setPCStyleStatusWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setPCStyleStatusWindow() {
|
||||
synchronized (statusWindow) {
|
||||
if (globalStatusWindowLocation == null) {
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
globalStatusWindowLocation = new Point(d.width - statusWindow.getWidth(),
|
||||
d.height - statusWindow.getHeight() - 25);
|
||||
}
|
||||
statusWindow.setLocation(globalStatusWindowLocation.x, globalStatusWindowLocation.y);
|
||||
}
|
||||
}
|
||||
|
||||
private void setStatusWindowForeground(Color fg) {
|
||||
synchronized (statusWindow) {
|
||||
if (statusWindowOwner != this) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleStatusWindowStyle() {
|
||||
synchronized (statusWindow) {
|
||||
if (attachedStatusWindow) {
|
||||
attachedStatusWindow = false;
|
||||
setPCStyleStatusWindow();
|
||||
} else {
|
||||
attachedStatusWindow = true;
|
||||
}
|
||||
Iterator itr = inputMethodInstances.iterator();
|
||||
while (itr.hasNext()) {
|
||||
TransliteratorInputMethod im = (TransliteratorInputMethod)itr.next();
|
||||
im.inputMethodContext.enableClientWindowNotification(im, attachedStatusWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCharacterSubsets(Character.Subset[] subsets) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
public void reconvert() {
|
||||
// not supported yet
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void dispatchEvent(AWTEvent event) {
|
||||
if (!active && (event instanceof KeyEvent)) {
|
||||
System.out.println(rb.getString("activeError"));
|
||||
}
|
||||
if (disposed) {
|
||||
System.out.println(rb.getString("disposedError"));
|
||||
}
|
||||
if (!(event instanceof InputEvent)) {
|
||||
System.out.println(rb.getString("inputError"));
|
||||
}
|
||||
|
||||
if (event.getID() == KeyEvent.KEY_TYPED) {
|
||||
KeyEvent e = (KeyEvent) event;
|
||||
if (handleCharacter(e.getKeyChar())) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
if (active) {
|
||||
System.out.println(rb.getString("activateError"));
|
||||
}
|
||||
System.out.println("activate");
|
||||
|
||||
active = true;
|
||||
synchronized (statusWindow) {
|
||||
statusWindowOwner = this;
|
||||
updateStatusWindow();
|
||||
if (!statusWindow.isVisible()) {
|
||||
statusWindow.setVisible(true);
|
||||
}
|
||||
setStatusWindowForeground(Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
public void deactivate(boolean isTemporary) {
|
||||
if (!active) {
|
||||
System.out.println(rb.getString("deactivateError"));
|
||||
}
|
||||
System.out.println("deactivate");
|
||||
setStatusWindowForeground(Color.lightGray);
|
||||
active = false;
|
||||
}
|
||||
|
||||
public void hideWindows() {
|
||||
if (active) {
|
||||
System.out.println(rb.getString("hideError"));
|
||||
}
|
||||
synchronized (statusWindow) {
|
||||
if (statusWindowOwner == this) {
|
||||
statusWindow.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeNotify() {
|
||||
}
|
||||
|
||||
public void endComposition() {
|
||||
commitAll();
|
||||
}
|
||||
|
||||
public void notifyClientWindowChange(Rectangle location) {
|
||||
clientWindowLocation = location;
|
||||
synchronized (statusWindow) {
|
||||
if (!attachedStatusWindow || statusWindowOwner != this) {
|
||||
return;
|
||||
}
|
||||
if (location != null) {
|
||||
statusWindow.setLocation(location.x, location.y+location.height);
|
||||
if (!statusWindow.isVisible()) {
|
||||
if (active) {
|
||||
setStatusWindowForeground(Color.black);
|
||||
} else {
|
||||
setStatusWindowForeground(Color.lightGray);
|
||||
}
|
||||
statusWindow.setVisible(true);
|
||||
}
|
||||
} else {
|
||||
statusWindow.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (active) {
|
||||
System.out.println(rb.getString("disposeError"));
|
||||
}
|
||||
if (disposed) {
|
||||
System.out.println(rb.getString("multipleDisposeError"));
|
||||
}
|
||||
synchronized (statusWindow) {
|
||||
inputMethodInstances.remove(this);
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public Object getControlObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setCompositionEnabled(boolean enable) {
|
||||
// not supported yet
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isCompositionEnabled() {
|
||||
// always enabled
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to handle a typed character.
|
||||
* @return whether the character was handled
|
||||
*/
|
||||
private boolean handleCharacter(char ch) {
|
||||
if (ch == '\n') {
|
||||
commitAll();
|
||||
return true;
|
||||
}
|
||||
else if (ch == '\b') {
|
||||
if (index.contextLimit > index.contextStart) {
|
||||
rawText.deleteCharAt(index.contextLimit - 1);
|
||||
--index.limit;
|
||||
--index.contextLimit;
|
||||
sendText();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rawText.append(ch);
|
||||
index.limit = rawText.length();
|
||||
index.contextLimit = rawText.length();
|
||||
transliterator.transliterate(replaceableText, index);
|
||||
sendText();
|
||||
index.contextStart = index.start;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* commits all chunks */
|
||||
void commitAll() {
|
||||
if(transliterator != null) {
|
||||
transliterator.finishTransliteration(replaceableText, index);
|
||||
sendText();
|
||||
rawText.setLength(0);
|
||||
index.start = 0;
|
||||
index.contextStart = 0;
|
||||
index.limit = 0;
|
||||
index.contextLimit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sendText() {
|
||||
AttributedString as = null;
|
||||
TextHitInfo caret = null;
|
||||
int committedCharacterCount = 0;
|
||||
InputMethodHighlight highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
|
||||
String text = null;
|
||||
|
||||
if(index.start > index.contextStart) {
|
||||
text = rawText.substring(index.contextStart, index.start);
|
||||
as = new AttributedString(text);
|
||||
committedCharacterCount = text.length();
|
||||
inputMethodContext.dispatchInputMethodEvent(
|
||||
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
|
||||
as.getIterator(),
|
||||
committedCharacterCount,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
if(index.contextLimit > index.start) {
|
||||
text = rawText.substring(index.start, index.contextLimit);
|
||||
as = new AttributedString(text);
|
||||
committedCharacterCount = 0;
|
||||
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
|
||||
caret = TextHitInfo.leading(text.length());
|
||||
inputMethodContext.dispatchInputMethodEvent(
|
||||
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
|
||||
as.getIterator(),
|
||||
committedCharacterCount,
|
||||
caret,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NameRenderer extends JLabel implements ListCellRenderer {
|
||||
|
||||
public Component getListCellRendererComponent(
|
||||
JList list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
|
||||
String s = ((JLabel)value).getText();
|
||||
setText(s);
|
||||
|
||||
if(isSelected) {
|
||||
setBackground(list.getSelectionBackground());
|
||||
setForeground(list.getSelectionForeground());
|
||||
}
|
||||
else {
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
|
||||
setEnabled(list.isEnabled());
|
||||
setFont(list.getFont());
|
||||
setOpaque(true);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
class LabelComparator implements Comparator {
|
||||
public int compare(Object obj1, Object obj2) {
|
||||
Collator collator = Collator.getInstance();
|
||||
return collator.compare(((JLabel)obj1).getText(), ((JLabel)obj2).getText());
|
||||
}
|
||||
|
||||
public boolean equals(Object obj1) {
|
||||
return this.equals(obj1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* ===========================================================================
|
||||
* IBM ICU Transliterator IME - TransliteratorInputMethodDescriptor.java version 1.0
|
||||
* (C) Copyright IBM Corp. 2004. All Rights Reserved
|
||||
* ===========================================================================
|
||||
*/
|
||||
package com.ibm.icu.dev.tool.ime;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.im.spi.InputMethod;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
/**
|
||||
* The TransliteratorInputMethodDescriptor class is used to identify this package
|
||||
* as an input method editor.
|
||||
*/
|
||||
|
||||
public class TransliteratorInputMethodDescriptor implements InputMethodDescriptor {
|
||||
|
||||
private ResourceBundle rb = null;
|
||||
|
||||
/**
|
||||
* Creates the Transliterator IME this is automatically callled by the
|
||||
* JVM when the Transliterator IME is selected from the input method list.
|
||||
*
|
||||
* @return InputMethod The Transliterator IME object.
|
||||
*/
|
||||
public InputMethod createInputMethod() throws Exception {
|
||||
return new TransliteratorInputMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of locales that this IME supports.
|
||||
*
|
||||
* @return Locale[] This will always have one locale. By default
|
||||
* we just return the current locale. Therefore
|
||||
* the Transliterator IME works in all locales.
|
||||
*/
|
||||
// use the current active locale
|
||||
public Locale[] getAvailableLocales() {
|
||||
return new Locale[] {Locale.getDefault()};
|
||||
}
|
||||
|
||||
/**
|
||||
* The Transliterator IME does not support dynamic locales. The Transliterator
|
||||
* IME's functionality does not depend upon any locale.
|
||||
*
|
||||
* @return boolean This will always be false.
|
||||
*/
|
||||
public boolean hasDynamicLocaleList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the localized name of the Transliterator IME
|
||||
*
|
||||
* @param inputLocale.
|
||||
* @param displayLanguge The requested translation of the Transliterator IME.
|
||||
*
|
||||
* @return String The localized name for the Transliterator IME.
|
||||
*/
|
||||
public String getInputMethodDisplayName(Locale inputLocale,
|
||||
Locale displayLanguage) {
|
||||
String name = null;
|
||||
|
||||
try {
|
||||
rb = ResourceBundle.getBundle("com.ibm.icu.dev.tool.ime.Transliterator", displayLanguage);
|
||||
name = rb.getString("name");
|
||||
}
|
||||
catch (MissingResourceException m) {
|
||||
// use a hardcoded value
|
||||
name = "Transliterator";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the icon for the Transliterator IME. This is not supported.
|
||||
*
|
||||
* @param inputLocale (This is ignored).
|
||||
*
|
||||
* @return Image This will always be null.
|
||||
*/
|
||||
public Image getInputMethodIcon(Locale inputLocale) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
11
icu4j/src/com/ibm/icu/dev/tool/ime/manifest.stub
Normal file
11
icu4j/src/com/ibm/icu/dev/tool/ime/manifest.stub
Normal file
|
@ -0,0 +1,11 @@
|
|||
Manifest-Version: 1.0
|
||||
Created-By: 1.0 (IBM Corporation)
|
||||
Extension-Name: com.ibm.icu.dev.tool.ime
|
||||
Implementation-Vendor: IBM Corporation
|
||||
Implementation-Version: 1.0
|
||||
Implementation-Title: ICU Transliterator IME
|
||||
Specification-Vendor: IBM
|
||||
Specification-Version: 1.0
|
||||
Specification-Title: ICU Transliterator IME
|
||||
|
||||
Name: com/ibm/icu/dev/tool/ime
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
#
|
||||
# fully-qualified name of the java.awt.im.spi.InputMethodDescriptor
|
||||
# implementation class
|
||||
#
|
||||
|
||||
com.ibm.icu.dev.tool.ime.TransliteratorInputMethodDescriptor
|
Loading…
Add table
Reference in a new issue