KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > event > InputMethodEvent


1 /*
2  * @(#)InputMethodEvent.java 1.22 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.event;
9
10 import java.awt.AWTEvent JavaDoc;
11 import java.awt.Component JavaDoc;
12 import java.awt.EventQueue JavaDoc;
13 import java.awt.font.TextHitInfo JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.ObjectInputStream JavaDoc;
16 import java.lang.Integer JavaDoc;
17 import java.text.AttributedCharacterIterator JavaDoc;
18 import java.text.CharacterIterator JavaDoc;
19
20 /**
21  * Input method events contain information about text that is being
22  * composed using an input method. Whenever the text changes, the
23  * input method sends an event. If the text component that's currently
24  * using the input method is an active client, the event is dispatched
25  * to that component. Otherwise, it is dispatched to a separate
26  * composition window.
27  *
28  * <p>
29  * The text included with the input method event consists of two parts:
30  * committed text and composed text. Either part may be empty. The two
31  * parts together replace any uncommitted composed text sent in previous events,
32  * or the currently selected committed text.
33  * Committed text should be integrated into the text component's persistent
34  * data, it will not be sent again. Composed text may be sent repeatedly,
35  * with changes to reflect the user's editing operations. Committed text
36  * always precedes composed text.
37  *
38  * @author JavaSoft Asia/Pacific
39  * @version 1.22 12/19/03
40  * @since 1.2
41  */

42
43 public class InputMethodEvent extends AWTEvent JavaDoc {
44
45     /**
46      * Serial Version ID.
47      */

48     private static final long serialVersionUID = 4727190874778922661L;
49
50     /**
51      * Marks the first integer id for the range of input method event ids.
52      */

53     public static final int INPUT_METHOD_FIRST = 1100;
54
55     /**
56      * The event type indicating changed input method text. This event is
57      * generated by input methods while processing input.
58      */

59     public static final int INPUT_METHOD_TEXT_CHANGED = INPUT_METHOD_FIRST;
60
61     /**
62      * The event type indicating a changed insertion point in input method text.
63      * This event is
64      * generated by input methods while processing input if only the caret changed.
65      */

66     public static final int CARET_POSITION_CHANGED = INPUT_METHOD_FIRST + 1;
67
68     /**
69      * Marks the last integer id for the range of input method event ids.
70      */

71     public static final int INPUT_METHOD_LAST = INPUT_METHOD_FIRST + 1;
72
73     /**
74      * The time stamp that indicates when the event was created.
75      *
76      * @serial
77      * @see #getWhen
78      * @since 1.4
79      */

80     long when;
81
82     // Text object
83
private transient AttributedCharacterIterator JavaDoc text;
84     private transient int committedCharacterCount;
85     private transient TextHitInfo JavaDoc caret;
86     private transient TextHitInfo JavaDoc visiblePosition;
87
88     /**
89      * Constructs an <code>InputMethodEvent</code> with the specified
90      * source component, type, time, text, caret, and visiblePosition.
91      * <p>
92      * The offsets of caret and visiblePosition are relative to the current
93      * composed text; that is, the composed text within <code>text</code>
94      * if this is an <code>INPUT_METHOD_TEXT_CHANGED</code> event,
95      * the composed text within the <code>text</code> of the
96      * preceding <code>INPUT_METHOD_TEXT_CHANGED</code> event otherwise.
97      * <p>Note that passing in an invalid <code>id</code> results in
98      * unspecified behavior. This method throws an
99      * <code>IllegalArgumentException</code> if <code>source</code>
100      * is <code>null</code>.
101      *
102      * @param source the object where the event originated
103      * @param id the event type
104      * @param when a long integer that specifies the time the event occurred
105      * @param text the combined committed and composed text,
106      * committed text first; must be <code>null</code>
107      * when the event type is <code>CARET_POSITION_CHANGED</code>;
108      * may be <code>null</code> for
109      * <code>INPUT_METHOD_TEXT_CHANGED</code> if there's no
110      * committed or composed text
111      * @param committedCharacterCount the number of committed
112      * characters in the text
113      * @param caret the caret (a.k.a. insertion point);
114      * <code>null</code> if there's no caret within current
115      * composed text
116      * @param visiblePosition the position that's most important
117      * to be visible; <code>null</code> if there's no
118      * recommendation for a visible position within current
119      * composed text
120      * @throws IllegalArgumentException if <code>id</code> is not
121      * in the range
122      * <code>INPUT_METHOD_FIRST</code>..<code>INPUT_METHOD_LAST</code>;
123      * or if id is <code>CARET_POSITION_CHANGED</code> and
124      * <code>text</code> is not <code>null</code>;
125      * or if <code>committedCharacterCount</code> is not in the range
126      * <code>0</code>..<code>(text.getEndIndex() - text.getBeginIndex())</code>
127      * @throws IllegalArgumentException if <code>source</code> is null
128      *
129      * @since 1.4
130      */

131     public InputMethodEvent(Component JavaDoc source, int id, long when,
132             AttributedCharacterIterator JavaDoc text, int committedCharacterCount,
133             TextHitInfo JavaDoc caret, TextHitInfo JavaDoc visiblePosition) {
134         super(source, id);
135         if (id < INPUT_METHOD_FIRST || id > INPUT_METHOD_LAST) {
136             throw new IllegalArgumentException JavaDoc("id outside of valid range");
137         }
138
139         if (id == CARET_POSITION_CHANGED && text != null) {
140             throw new IllegalArgumentException JavaDoc("text must be null for CARET_POSITION_CHANGED");
141         }
142
143     this.when = when;
144         this.text = text;
145         int textLength = 0;
146         if (text != null) {
147             textLength = text.getEndIndex() - text.getBeginIndex();
148         }
149
150         if (committedCharacterCount < 0 || committedCharacterCount > textLength) {
151             throw new IllegalArgumentException JavaDoc("committedCharacterCount outside of valid range");
152         }
153         this.committedCharacterCount = committedCharacterCount;
154
155         this.caret = caret;
156         this.visiblePosition = visiblePosition;
157    }
158
159     /**
160      * Constructs an <code>InputMethodEvent</code> with the specified
161      * source component, type, text, caret, and visiblePosition.
162      * <p>
163      * The offsets of caret and visiblePosition are relative to the current
164      * composed text; that is, the composed text within <code>text</code>
165      * if this is an <code>INPUT_METHOD_TEXT_CHANGED</code> event,
166      * the composed text within the <code>text</code> of the
167      * preceding <code>INPUT_METHOD_TEXT_CHANGED</code> event otherwise.
168      * The time stamp for this event is initialized by invoking
169      * {@link java.awt.EventQueue#getMostRecentEventTime()}.
170      * <p>Note that passing in an invalid <code>id</code> results in
171      * unspecified behavior. This method throws an
172      * <code>IllegalArgumentException</code> if <code>source</code>
173      * is <code>null</code>.
174      *
175      * @param source the object where the event originated
176      * @param id the event type
177      * @param text the combined committed and composed text,
178      * committed text first; must be <code>null</code>
179      * when the event type is <code>CARET_POSITION_CHANGED</code>;
180      * may be <code>null</code> for
181      * <code>INPUT_METHOD_TEXT_CHANGED</code> if there's no
182      * committed or composed text
183      * @param committedCharacterCount the number of committed
184      * characters in the text
185      * @param caret the caret (a.k.a. insertion point);
186      * <code>null</code> if there's no caret within current
187      * composed text
188      * @param visiblePosition the position that's most important
189      * to be visible; <code>null</code> if there's no
190      * recommendation for a visible position within current
191      * composed text
192      * @throws IllegalArgumentException if <code>id</code> is not
193      * in the range
194      * <code>INPUT_METHOD_FIRST</code>..<code>INPUT_METHOD_LAST</code>;
195      * or if id is <code>CARET_POSITION_CHANGED</code> and
196      * <code>text</code> is not <code>null</code>;
197      * or if <code>committedCharacterCount</code> is not in the range
198      * <code>0</code>..<code>(text.getEndIndex() - text.getBeginIndex())</code>
199      * @throws IllegalArgumentException if <code>source</code> is null
200      */

201     public InputMethodEvent(Component JavaDoc source, int id,
202             AttributedCharacterIterator JavaDoc text, int committedCharacterCount,
203             TextHitInfo JavaDoc caret, TextHitInfo JavaDoc visiblePosition) {
204         this(source, id, EventQueue.getMostRecentEventTime(), text,
205          committedCharacterCount, caret, visiblePosition);
206     }
207
208     /**
209      * Constructs an <code>InputMethodEvent</code> with the
210      * specified source component, type, caret, and visiblePosition.
211      * The text is set to <code>null</code>,
212      * <code>committedCharacterCount</code> to 0.
213      * <p>
214      * The offsets of <code>caret</code> and <code>visiblePosition</code>
215      * are relative to the current composed text; that is,
216      * the composed text within the <code>text</code> of the
217      * preceding <code>INPUT_METHOD_TEXT_CHANGED</code> event if the
218      * event being constructed as a <code>CARET_POSITION_CHANGED</code> event.
219      * For an <code>INPUT_METHOD_TEXT_CHANGED</code> event without text,
220      * <code>caret</code> and <code>visiblePosition</code> must be
221      * <code>null</code>.
222      * The time stamp for this event is initialized by invoking
223      * {@link java.awt.EventQueue#getMostRecentEventTime()}.
224      * <p>Note that passing in an invalid <code>id</code> results in
225      * unspecified behavior. This method throws an
226      * <code>IllegalArgumentException</code> if <code>source</code>
227      * is <code>null</code>.
228      *
229      * @param source the object where the event originated
230      * @param id the event type
231      * @param caret the caret (a.k.a. insertion point);
232      * <code>null</code> if there's no caret within current
233      * composed text
234      * @param visiblePosition the position that's most important
235      * to be visible; <code>null</code> if there's no
236      * recommendation for a visible position within current
237      * composed text
238      * @throws IllegalArgumentException if <code>id</code> is not
239      * in the range
240      * <code>INPUT_METHOD_FIRST</code>..<code>INPUT_METHOD_LAST</code>
241      * @throws IllegalArgumentException if <code>source</code> is null
242      */

243     public InputMethodEvent(Component JavaDoc source, int id, TextHitInfo JavaDoc caret,
244             TextHitInfo JavaDoc visiblePosition) {
245         this(source, id, EventQueue.getMostRecentEventTime(), null,
246          0, caret, visiblePosition);
247     }
248
249     /**
250      * Gets the combined committed and composed text.
251      * Characters from index 0 to index <code>getCommittedCharacterCount() - 1</code> are committed
252      * text, the remaining characters are composed text.
253      *
254      * @return the text.
255      * Always null for CARET_POSITION_CHANGED;
256      * may be null for INPUT_METHOD_TEXT_CHANGED if there's no composed or committed text.
257      */

258     public AttributedCharacterIterator JavaDoc getText() {
259         return text;
260     }
261
262     /**
263      * Gets the number of committed characters in the text.
264      */

265     public int getCommittedCharacterCount() {
266         return committedCharacterCount;
267     }
268
269     /**
270      * Gets the caret.
271      * <p>
272      * The offset of the caret is relative to the current
273      * composed text; that is, the composed text within getText()
274      * if this is an <code>INPUT_METHOD_TEXT_CHANGED</code> event,
275      * the composed text within getText() of the
276      * preceding <code>INPUT_METHOD_TEXT_CHANGED</code> event otherwise.
277      *
278      * @return the caret (a.k.a. insertion point).
279      * Null if there's no caret within current composed text.
280      */

281     public TextHitInfo JavaDoc getCaret() {
282         return caret;
283     }
284
285     /**
286      * Gets the position that's most important to be visible.
287      * <p>
288      * The offset of the visible position is relative to the current
289      * composed text; that is, the composed text within getText()
290      * if this is an <code>INPUT_METHOD_TEXT_CHANGED</code> event,
291      * the composed text within getText() of the
292      * preceding <code>INPUT_METHOD_TEXT_CHANGED</code> event otherwise.
293      *
294      * @return the position that's most important to be visible.
295      * Null if there's no recommendation for a visible position within current composed text.
296      */

297     public TextHitInfo JavaDoc getVisiblePosition() {
298         return visiblePosition;
299     }
300
301     /**
302      * Consumes this event so that it will not be processed
303      * in the default manner by the source which originated it.
304      */

305     public void consume() {
306         consumed = true;
307     }
308
309     /**
310      * Returns whether or not this event has been consumed.
311      * @see #consume
312      */

313     public boolean isConsumed() {
314         return consumed;
315     }
316     
317     /**
318      * Returns the time stamp of when this event occurred.
319      *
320      * @return this event's timestamp
321      * @since 1.4
322      */

323     public long getWhen() {
324       return when;
325     }
326
327     /**
328      * Returns a parameter string identifying this event.
329      * This method is useful for event-logging and for debugging.
330      * It contains the event ID in text form, the characters of the
331      * committed and composed text
332      * separated by "+", the number of committed characters,
333      * the caret, and the visible position.
334      *
335      * @return a string identifying the event and its attributes
336      */

337     public String JavaDoc paramString() {
338         String JavaDoc typeStr;
339         switch(id) {
340           case INPUT_METHOD_TEXT_CHANGED:
341               typeStr = "INPUT_METHOD_TEXT_CHANGED";
342               break;
343           case CARET_POSITION_CHANGED:
344               typeStr = "CARET_POSITION_CHANGED";
345               break;
346           default:
347               typeStr = "unknown type";
348         }
349
350         String JavaDoc textString;
351         if (text == null) {
352             textString = "no text";
353         } else {
354             StringBuffer JavaDoc textBuffer = new StringBuffer JavaDoc("\"");
355             int committedCharacterCount = this.committedCharacterCount;
356             char c = text.first();
357             while (committedCharacterCount-- > 0) {
358                 textBuffer.append(c);
359                 c = text.next();
360             }
361             textBuffer.append("\" + \"");
362             while (c != CharacterIterator.DONE) {
363                 textBuffer.append(c);
364                 c = text.next();
365             }
366             textBuffer.append("\"");
367             textString = textBuffer.toString();
368         }
369         
370         String JavaDoc countString = committedCharacterCount + " characters committed";
371         
372         String JavaDoc caretString;
373         if (caret == null) {
374             caretString = "no caret";
375         } else {
376             caretString = "caret: " + caret.toString();
377         }
378         
379         String JavaDoc visiblePositionString;
380         if (visiblePosition == null) {
381             visiblePositionString = "no visible position";
382         } else {
383             visiblePositionString = "visible position: " + visiblePosition.toString();
384         }
385         
386         return typeStr + ", " + textString + ", " + countString + ", " + caretString + ", " + visiblePositionString;
387     }
388
389     /**
390      * Initializes the <code>when</code> field if it is not present in the
391      * object input stream. In that case, the field will be initialized by
392      * invoking {@link java.awt.EventQueue#getMostRecentEventTime()}.
393      */

394     private void readObject(ObjectInputStream JavaDoc s) throws ClassNotFoundException JavaDoc, IOException JavaDoc {
395     s.defaultReadObject();
396     if (when == 0) {
397         when = EventQueue.getMostRecentEventTime();
398     }
399     }
400 }
401
Popular Tags