001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Evgeniya G. Maenkova
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.awt.Color;
023: import java.awt.event.InputMethodEvent;
024: import java.awt.font.TextHitInfo;
025: import java.awt.im.InputMethodRequests;
026: import java.text.AttributedCharacterIterator;
027: import java.text.AttributedString;
028: import java.text.AttributedCharacterIterator.Attribute;
029: import java.util.HashMap;
030: import java.util.Map;
031: import javax.swing.JFrame;
032: import javax.swing.JTextArea;
033: import javax.swing.SwingTestCase;
034: import org.apache.harmony.awt.text.ComposedTextParams;
035: import org.apache.harmony.awt.text.PropertyNames;
036:
037: public class JTextComponent_IMTest extends SwingTestCase {
038: JTextArea jta;
039:
040: JFrame jf;
041:
042: InputMethodEvent ime;
043:
044: Map<Attribute, Object> map;
045:
046: AbstractDocument doc;
047:
048: AttributedCharacterIterator iter;
049:
050: AttributedString attrString;
051:
052: static final AttributedCharacterIterator.Attribute SEGMENT_ATTRIBUTE = AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT;
053:
054: static final String initialContent = "IM test";
055:
056: boolean bWasException;
057:
058: InputMethodRequests imr;
059:
060: String message;
061:
062: @Override
063: protected void setUp() throws Exception {
064: super .setUp();
065: map = new HashMap<Attribute, Object>();
066: jf = new JFrame();
067: jta = new JTextArea();
068: jta.setText(initialContent);
069: doc = (AbstractDocument) jta.getDocument();
070: imr = jta.getInputMethodRequests();
071: bWasException = false;
072: message = null;
073: jf.getContentPane().add(jta);
074: jf.setSize(200, 300);
075: jf.pack();
076: }
077:
078: @Override
079: protected void tearDown() throws Exception {
080: jf.dispose();
081: super .tearDown();
082: }
083:
084: private InputMethodEvent getCaretEvent(
085: AttributedCharacterIterator text,
086: int committedCharacterCount, TextHitInfo caret,
087: TextHitInfo visiblePosition) {
088: return getEvent(InputMethodEvent.CARET_POSITION_CHANGED, text,
089: committedCharacterCount, caret, visiblePosition);
090: }
091:
092: private InputMethodEvent getTextEvent(
093: AttributedCharacterIterator text,
094: int committedCharacterCount, TextHitInfo caret,
095: TextHitInfo visiblePosition) {
096: return getEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
097: text, committedCharacterCount, caret, visiblePosition);
098: }
099:
100: private InputMethodEvent getEvent(final int id,
101: final AttributedCharacterIterator text,
102: final int committedCharacterCount, final TextHitInfo caret,
103: final TextHitInfo visiblePosition) {
104: return new InputMethodEvent(jta, id, text,
105: committedCharacterCount, caret, visiblePosition);
106: }
107:
108: private Map<Attribute, Object> putSegmentAttribute(
109: final Map<Attribute, Object> map, final Object value) {
110: map.put(SEGMENT_ATTRIBUTE, value);
111: return map;
112: }
113:
114: private AttributedCharacterIterator getIterator(final String text,
115: final Map<Attribute, Object> map) {
116: attrString = new AttributedString(text, map);
117: return attrString.getIterator();
118: }
119:
120: private void setComposedText() {
121: String content = "12345";
122: iter = getIterator(content, putSegmentAttribute(map, Color.RED));
123: ime = getTextEvent(iter, 0, TextHitInfo.afterOffset(0),
124: TextHitInfo.afterOffset(0));
125: jta.processInputMethodEvent(ime);
126: assertEquals(7, jta.getCaretPosition());
127: checkComposedTextParams(true, 7, 5);
128: assertEquals(initialContent + content, jta.getText());
129: }
130:
131: private void checkComposedTextParams(final boolean shouldBe,
132: final int start, final int length) {
133: if (isHarmony()) {
134: Object value = doc
135: .getProperty(PropertyNames.COMPOSED_TEXT_PROPERTY);
136: if (!shouldBe) {
137: if (value != null) {
138: ComposedTextParams params = (ComposedTextParams) value;
139: assertNull(params.getComposedText());
140: assertEquals(0, params.getComposedTextLength());
141: }
142: return;
143: }
144: assertTrue(value instanceof ComposedTextParams);
145: ComposedTextParams params = (ComposedTextParams) value;
146: assertEquals(start, params.getComposedTextStart());
147: assertEquals(length, params.getComposedTextLength());
148: AttributedString text = params.getComposedText();
149: AttributedCharacterIterator iter1 = attrString
150: .getIterator();
151: AttributedCharacterIterator iter2 = text.getIterator();
152: assertEquals(iter1.getAttributes(), iter2.getAttributes());
153: assertEquals(iter1.getRunStart(SEGMENT_ATTRIBUTE), iter2
154: .getRunStart(SEGMENT_ATTRIBUTE));
155: assertEquals(Math.min(iter1.getRunLimit(SEGMENT_ATTRIBUTE),
156: iter2.getEndIndex()), iter2
157: .getRunLimit(SEGMENT_ATTRIBUTE));
158: }
159: }
160:
161: public void testProcessItME_Caret() {
162: setComposedText();
163: for (int i = 0; i < 10; i++) {
164: int pos = Math.min(12, i + 7);
165: ime = getCaretEvent(null, 0, TextHitInfo.afterOffset(i),
166: null);
167: jta.processInputMethodEvent(ime);
168: assertEquals(pos, jta.getCaretPosition());
169: ime = getCaretEvent(null, 0, TextHitInfo.beforeOffset(i),
170: null);
171: jta.processInputMethodEvent(ime);
172: assertEquals(pos, jta.getCaretPosition());
173: }
174: }
175:
176: public void testProcessIME_Text_NPE() {
177: String content = "12345";
178: iter = getIterator(content, putSegmentAttribute(map, Color.RED));
179: ime = getTextEvent(null, 0, null, null);
180: jta.processInputMethodEvent(ime);
181: checkComposedTextParams(false, 7, 5);
182: }
183:
184: public void testProcessIME_Text() {
185: String content = "12345";
186: iter = getIterator(content, putSegmentAttribute(map, Color.RED));
187: ime = getTextEvent(iter, 0, TextHitInfo.afterOffset(0),
188: TextHitInfo.afterOffset(0));
189: jta.processInputMethodEvent(ime);
190: assertEquals(7, jta.getCaretPosition());
191: checkComposedTextParams(true, 7, 5);
192: assertEquals(initialContent + content, jta.getText());
193: content = "abcdett";
194: iter = getIterator(content,
195: putSegmentAttribute(map, Color.BLUE));
196: ime = getTextEvent(iter, 0, TextHitInfo.afterOffset(1),
197: TextHitInfo.afterOffset(1));
198: jta.processInputMethodEvent(ime);
199: assertEquals(8, jta.getCaretPosition());
200: checkComposedTextParams(true, 7, 7);
201: assertEquals(initialContent + content, jta.getText());
202: //====================================================
203: content = "composite attributes";
204: Map<Attribute, Object> map1 = new HashMap<Attribute, Object>();
205: putSegmentAttribute(map1, Color.GRAY);
206: attrString = new AttributedString(content, map1);
207: attrString.addAttribute(SEGMENT_ATTRIBUTE, Color.YELLOW);
208: iter = attrString.getIterator();
209: ime = getTextEvent(iter, 0, TextHitInfo.afterOffset(0),
210: TextHitInfo.afterOffset(0));
211: jta.processInputMethodEvent(ime);
212: assertEquals(7, jta.getCaretPosition());
213: checkComposedTextParams(true, 7, 20);
214: assertEquals(initialContent + content, jta.getText());
215: //====================================================
216: content = "fghij";
217: iter = getIterator(content, putSegmentAttribute(map,
218: Color.BLACK));
219: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
220: TextHitInfo.afterOffset(0));
221: jta.processInputMethodEvent(ime);
222: assertEquals(12, jta.getCaretPosition());
223: checkComposedTextParams(false, 0, 0);
224: assertEquals(initialContent + content, jta.getText());
225: String lastCommited = content;
226: content = "finish";
227: iter = getIterator(content,
228: putSegmentAttribute(map, Color.PINK));
229: ime = getTextEvent(iter, 2, TextHitInfo.afterOffset(0),
230: TextHitInfo.afterOffset(0));
231: jta.processInputMethodEvent(ime);
232: assertEquals(14, jta.getCaretPosition());
233: checkComposedTextParams(true, 14, 4);
234: assertEquals(initialContent + lastCommited + content, jta
235: .getText());
236: }
237:
238: //InputMethodRequest tests==========================================
239: public void testCancelLatestCommittedText() {
240: AttributedCharacterIterator.Attribute[] attributes = new AttributedCharacterIterator.Attribute[] { SEGMENT_ATTRIBUTE };
241: assertNull(imr.cancelLatestCommittedText(attributes));
242: String content = "fghij";
243: iter = getIterator(content, putSegmentAttribute(map,
244: Color.BLACK));
245: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
246: TextHitInfo.afterOffset(0));
247: jta.processInputMethodEvent(ime);
248: assertEquals(initialContent + content, jta.getText());
249: imr.cancelLatestCommittedText(attributes);
250: assertEquals(initialContent, jta.getText());
251: content = "klnoprst";
252: iter = getIterator(content, putSegmentAttribute(map,
253: Color.BLACK));
254: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
255: TextHitInfo.afterOffset(0));
256: jta.processInputMethodEvent(ime);
257: assertEquals(initialContent + content, jta.getText());
258: imr.cancelLatestCommittedText(attributes);
259: assertEquals(initialContent
260: + content.substring(5, content.length()), jta.getText());
261: }
262:
263: private void checkIterator(
264: final AttributedCharacterIterator iterator,
265: final int attributesCount, final int start, final int end) {
266: assertEquals(attributesCount, iterator.getAttributes().size());
267: assertEquals(start, iterator.getBeginIndex());
268: assertEquals(end, iterator.getEndIndex());
269: }
270:
271: private void checkException(final String text) {
272: assertTrue(bWasException);
273: assertEquals(text, message);
274: bWasException = false;
275: message = null;
276: }
277:
278: public void testGetCommittedText() {
279: assertEquals(7, imr.getCommittedTextLength());
280: String content = "fghij";
281: iter = getIterator(content, putSegmentAttribute(map,
282: Color.BLACK));
283: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
284: TextHitInfo.afterOffset(0));
285: jta.processInputMethodEvent(ime);
286: checkIterator(imr.getCommittedText(0, 12, null), 0, 0, 12);
287: checkIterator(imr.getCommittedText(2, 6, null), 0, 0, 4);
288: jta.setCaretPosition(3);
289: iter = getIterator("finish", putSegmentAttribute(map,
290: Color.PINK));
291: ime = getTextEvent(iter, 2, TextHitInfo.afterOffset(0),
292: TextHitInfo.afterOffset(0));
293: jta.processInputMethodEvent(ime);
294: checkIterator(imr.getCommittedText(0, 14, null), 0, 0, 14);
295: AttributedCharacterIterator it = imr.getCommittedText(0, 14,
296: null);
297: String committedText = "IM fitestfghij";
298: for (int i = 0; i < 14; i++) {
299: it.setIndex(i);
300: assertEquals(committedText.charAt(i), it.current());
301: }
302: checkIterator(imr.getCommittedText(3, 8, null), 0, 0, 5);
303: try {
304: imr.getCommittedText(2, 20, null);
305: } catch (IllegalArgumentException e) {
306: bWasException = true;
307: message = e.getMessage();
308: }
309: checkException("Invalid range");
310: try {
311: imr.getCommittedText(5, 2, null);
312: } catch (IllegalArgumentException e) {
313: bWasException = true;
314: message = e.getMessage();
315: }
316: checkException("Invalid range");
317: }
318:
319: public void testGetCommittedTextLength() {
320: assertEquals(7, imr.getCommittedTextLength());
321: iter = getIterator("fghij", putSegmentAttribute(map,
322: Color.BLACK));
323: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
324: TextHitInfo.afterOffset(0));
325: jta.processInputMethodEvent(ime);
326: assertEquals(12, imr.getCommittedTextLength());
327: iter = getIterator("finish", putSegmentAttribute(map,
328: Color.PINK));
329: ime = getTextEvent(iter, 2, TextHitInfo.afterOffset(0),
330: TextHitInfo.afterOffset(0));
331: jta.processInputMethodEvent(ime);
332: assertEquals(14, imr.getCommittedTextLength());
333: }
334:
335: public void testGetInsertPositionOffset() {
336: setComposedText();
337: assertEquals(7, imr.getInsertPositionOffset());
338: iter = getIterator("finish", putSegmentAttribute(map,
339: Color.PINK));
340: ime = getTextEvent(iter, 2, TextHitInfo.afterOffset(0),
341: TextHitInfo.afterOffset(0));
342: jta.processInputMethodEvent(ime);
343: assertEquals(9, imr.getInsertPositionOffset());
344: }
345:
346: public void testGetSelectedText() {
347: assertNull(imr.getSelectedText(null));
348: jta.select(2, 5);
349: checkIterator(imr.getSelectedText(null), 0, 0, 3);
350: jta.setCaretPosition(7);
351: setComposedText();
352: jta.select(9, 11);
353: checkIterator(imr.getSelectedText(null), 0, 0, 2);
354: jta.select(2, 10);
355: checkIterator(imr.getSelectedText(null), 0, 0, 8);
356: }
357:
358: public void testDoubleCancelLatestCommittedText() {
359: String content = "fghij";
360: iter = getIterator(content, putSegmentAttribute(map,
361: Color.BLACK));
362: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
363: TextHitInfo.afterOffset(0));
364: jta.processInputMethodEvent(ime);
365: content = "klnoprst";
366: iter = getIterator(content, putSegmentAttribute(map,
367: Color.BLACK));
368: ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0),
369: TextHitInfo.afterOffset(0));
370: jta.processInputMethodEvent(ime);
371: assertNotNull(imr.cancelLatestCommittedText(null));
372: assertNull(imr.cancelLatestCommittedText(null));
373: assertEquals("IM testfghijrst", jta.getText());
374: }
375: }
|