2 *******************************************************************************
\r
3 * Copyright (C) 1996-2007, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.demo.translit;
\r
9 import java.awt.event.*;
\r
10 import com.ibm.icu.text.*;
\r
11 import com.ibm.icu.dev.demo.impl.*;
\r
14 * A subclass of {@link DumbTextComponent} that passes key events through
\r
15 * a {@link com.ibm.icu.text.Transliterator}.
\r
19 public class TransliteratingTextComponent extends DumbTextComponent {
\r
24 private static final long serialVersionUID = -8672128213174154047L;
\r
26 private static boolean DEBUG = false;
\r
28 private Transliterator translit = null;
\r
30 // NOTE: DISABLE THE START AND CURSOR UNTIL WE CAN GET IT TO WORK AT ALL
\r
32 // Index into getText() where the start of transliteration is.
\r
33 // As we commit text during transliteration, we advance
\r
35 //private int start = 0;
\r
37 // Index into getText() where the cursor is; cursor >= start
\r
38 //private int cursor = 0;
\r
40 // private static final String COPYRIGHT =
\r
41 // "\u00A9 IBM Corporation 1999. All rights reserved.";
\r
46 public TransliteratingTextComponent() {
\r
49 addActionListener(new ActionListener() {
\r
50 public void actionPerformed(ActionEvent e) {
\r
51 // We get an ActionEvent only when the selection changes
\r
52 resetTransliterationStart();
\r
59 * {@link DumbTextComponent} API. Framework method that is called
\r
60 * when a <code>KeyEvent</code> is received. This implementation
\r
61 * runs the new character through the current
\r
62 * <code>Transliterator</code>, if one is set, and inserts the
\r
63 * transliterated text into the buffer.
\r
65 protected void handleKeyTyped(KeyEvent e) {
\r
66 char ch = e.getKeyChar();
\r
68 if (translit == null) {
\r
70 super.handleKeyTyped(e);
\r
74 transliterate(ch, false);
\r
77 public void flush() {
\r
78 if (translit != null) transliterate('\uFFFF', true);
\r
82 protected void transliterate(char ch, boolean flush) {
\r
84 // ------------------------------------------------------------
\r
85 // The following case motivates the two lines that recompute
\r
86 // start and cursor below.
\r
89 // a b c q r|s t u m m
\r
90 // 0 1 2 3 4 5 6 7 8 9
\r
93 // start 3, cursor 5, sel 6 -> { 0, 3, 2 }
\r
94 // : new int[] { 0, sel - start, cursor - start };
\r
99 // a b c q r 9 9|9 t u m m
\r
100 // 0 1 2 3 4 5 6 7 8 9 a b
\r
103 // { 3, 5, 4 } -> start 6, cursor 7, sel 8
\r
104 // : start += index[0];
\r
105 // : cursor = start + index[2] - index[0];
\r
106 // ------------------------------------------------------------
\r
108 // Need to save start because calls to replaceRange will update
\r
109 // start and cursor.
\r
110 //int saveStart = start;
\r
112 int end = flush ? getSelectionEnd() : getSelectionStart();
\r
113 String sourceText = getText().substring(0,end);
\r
114 ReplaceableString buf = new ReplaceableString(sourceText);
\r
115 /*buf.replace(0, 1, getText().substring(start,
\r
116 getSelectionStart()));*/
\r
118 Transliterator.Position index = new Transliterator.Position();
\r
119 index.contextLimit = buf.length();
\r
120 index.contextStart = 0;
\r
121 index.start = getKeyStart();
\r
122 if (index.start == -1) index.start = getSelectionStart();
\r
123 index.limit = buf.length();
\r
125 // StringBuffer log = null;
\r
127 System.out.println("Transliterator: " + translit.getID());
\r
128 System.out.println("From:\t" + '"' + buf.toString() + '"'
\r
129 + "; {cs: " + index.contextStart
\r
130 + ", s: " + index.start
\r
131 + ", l: " + index.limit
\r
132 + ", cl: " + index.contextLimit
\r
133 + "}" + "; '" + ch + "'"
\r
134 + " " + getKeyStart()
\r
139 translit.finishTransliteration(buf, index);
\r
141 translit.transliterate(buf, index, ch);
\r
145 System.out.println("To:\t" + '"' + buf.toString() + '"'
\r
146 + "; {cs: " + index.contextStart
\r
147 + ", s: " + index.start
\r
148 + ", l: " + index.limit
\r
149 + ", cl: " + index.contextLimit
\r
152 System.out.println();
\r
155 buf.replace(buf.length(), buf.length(), String.valueOf(ch));
\r
156 translit.transliterate(buf);
\r
159 String result = buf.toString();
\r
160 //if (result.equals(sourceText + ch)) return;
\r
162 replaceRange(result, 0, getSelectionEnd());
\r
163 setKeyStart(index.start);
\r
165 // At this point start has been changed by the callback to
\r
166 // resetTransliteratorStart() via replaceRange() -- so use our
\r
167 // local copy, saveStart.
\r
169 // The START index is zero-based. On entry to transliterate(),
\r
170 // it was zero. We can therefore just add it to our original
\r
171 // getText()-based index value of start (in saveStart) to get
\r
172 // the new getText()-based start.
\r
173 // start = saveStart + index.contextStart;
\r
175 // Make the cursor getText()-based. The CURSOR index is zero-based.
\r
176 // cursor = start + index.start - index.contextStart;
\r
180 String out = buf.toString();
\r
181 log.append(out.substring(0, index.contextStart)).
\r
183 append(out.substring(index.contextStart, index.start)).
\r
185 append(out.substring(index.start)).
\r
187 log.append(", {" + index.contextStart + ", " + index.contextLimit + ", " + index.start + "}, ");
\r
188 // log.append("start " + start + ", cursor " + cursor);
\r
189 log.append(", sel " + getSelectionStart());
\r
190 System.out.println(escape(log.toString()));
\r
196 * Set the {@link com.ibm.icu.text.Transliterator} and direction to
\r
197 * use to process incoming <code>KeyEvent</code>s.
\r
198 * @param t the {@link com.ibm.icu.text.Transliterator} to use
\r
200 public void setTransliterator(Transliterator t) {
\r
202 if (translit != t) { // [sic] pointer compare ok; singletons
\r
203 resetTransliterationStart();
\r
209 public Transliterator getTransliterator() {
\r
214 * Reset the start point at which transliteration begins. This
\r
215 * needs to be done when the user moves the cursor or when the
\r
216 * current {@link com.ibm.icu.text.Transliterator} is changed.
\r
219 private void resetTransliterationStart() {
\r
220 start = getSelectionStart();
\r
226 * Escape non-ASCII characters as Unicode.
\r
227 * JUST FOR DEBUGGING OUTPUT.
\r
229 public static final String escape(String s) {
\r
230 StringBuffer buf = new StringBuffer();
\r
231 for (int i=0; i<s.length(); ++i) {
\r
232 char c = s.charAt(i);
\r
233 if (c >= ' ' && c <= 0x007F) {
\r
235 buf.append("\\\\"); // That is, "\\"
\r
250 buf.append(Integer.toHexString(c));
\r
253 return buf.toString();
\r