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 Alexey A. Ivanov
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.awt.FontMetrics;
023: import java.awt.Graphics;
024: import java.awt.Rectangle;
025: import java.awt.Shape;
026: import javax.swing.JFrame;
027: import javax.swing.JTextArea;
028: import javax.swing.SwingTestCase;
029:
030: /**
031: * This class tests PlainView behavior.
032: *
033: * <p>This class is initialized with a "real" PlainView that was obtained from
034: * JTextArea placed in JFrame.
035: *
036: */
037: public class PlainViewTest extends SwingTestCase {
038: private JTextArea area;
039:
040: private Document doc;
041:
042: private JFrame frame;
043:
044: private Shape shape;
045:
046: private PlainView view;
047:
048: public void testDrawSelectedText() throws BadLocationException {
049: area.setText("line1\nline2");
050: Graphics g = view.getGraphics();
051: FontMetrics m = view.metrics;
052: g.setFont(m.getFont());
053: assertEquals(m.charWidth('l'), view.drawSelectedText(g, 0, 0,
054: 0, 1));
055: assertEquals(m.stringWidth("line1"), view.drawSelectedText(g,
056: 0, 0, 0, 5));
057: assertEquals(m.stringWidth("line1\nli"), view.drawSelectedText(
058: g, 0, 0, 0, 8));
059: try {
060: view.drawSelectedText(g, 0, 0, -1, 1);
061: fail("BadLocationException expected");
062: } catch (BadLocationException e) {
063: }
064: try {
065: view.drawUnselectedText(g, 0, 0, 13, 13);
066: fail("BadLocationException expected");
067: } catch (BadLocationException e) {
068: }
069: try {
070: view.drawSelectedText(g, 0, 0, 10, 2);
071: fail("BadLocationException expected");
072: } catch (BadLocationException e) {
073: }
074: }
075:
076: public void testDrawUnselectedText() throws BadLocationException {
077: area.setText("line1\nline2");
078: Graphics g = view.getGraphics();
079: FontMetrics m = view.metrics;
080: g.setFont(m.getFont());
081: assertEquals(m.charWidth('l'), view.drawUnselectedText(g, 0, 0,
082: 0, 1));
083: assertEquals(5 + m.charWidth('l'), view.drawUnselectedText(g,
084: 5, 0, 0, 1));
085: assertEquals(m.stringWidth("line1"), view.drawUnselectedText(g,
086: 0, 0, 0, 5));
087: assertEquals(m.stringWidth("line1\nli"), view
088: .drawUnselectedText(g, 0, 0, 0, 8));
089: try {
090: view.drawUnselectedText(g, 0, 0, -1, 1);
091: fail("BadLocationException expected");
092: } catch (BadLocationException e) {
093: }
094: try {
095: view.drawUnselectedText(g, 0, 0, 13, 13);
096: fail("BadLocationException expected");
097: } catch (BadLocationException e) {
098: }
099: try {
100: view.drawUnselectedText(g, 0, 0, 10, 2);
101: fail("BadLocationException expected");
102: } catch (BadLocationException e) {
103: }
104: }
105:
106: public void testGetPreferredSpan() {
107: area.setText("1: 0\n2: 012345\n3:\n");
108: assertEquals(view.metrics.stringWidth("2: 012345"), // longest line
109: view.getPreferredSpan(View.X_AXIS), 0.00001f);
110: assertEquals(view.metrics.getHeight() * 4, view
111: .getPreferredSpan(View.Y_AXIS), 0.00001f);
112: area.setText("\ttext\t1");
113: float length = view.nextTabStop(0, 0);
114: length += view.metrics.stringWidth("text");
115: length = view.nextTabStop(length, 0);
116: length += view.metrics.stringWidth("1");
117: assertEquals(length, view.getPreferredSpan(View.X_AXIS),
118: 0.00001f);
119: }
120:
121: /**
122: * Generic tests of <code>modelToView(int, Shape, Position.Bias)</code>.
123: */
124: public void testModelToViewintShapeBias01()
125: throws BadLocationException {
126: area.setText("1: 0\n2: 012345\n3:\n");
127: // 01234 5678901234 567
128: assertTrue(view.modelToView(0, shape, Position.Bias.Backward) instanceof Rectangle);
129: assertEquals(new Rectangle(1, view.metrics.getHeight()), view
130: .modelToView(0, shape, Position.Bias.Forward));
131: assertEquals(new Rectangle(1, view.metrics.getHeight()), view
132: .modelToView(0, shape, Position.Bias.Backward));
133: assertEquals(new Rectangle(view.metrics.charWidth('1'), 0, 1,
134: view.metrics.getHeight()), view.modelToView(1, shape,
135: Position.Bias.Forward));
136: assertEquals(new Rectangle(view.metrics.charWidth('1'), 0, 1,
137: view.metrics.getHeight()), view.modelToView(1, shape,
138: Position.Bias.Backward));
139: assertEquals(new Rectangle(view.metrics.stringWidth("2: 012"),
140: view.metrics.getHeight(), 1, view.metrics.getHeight()),
141: view.modelToView(11, shape, Position.Bias.Forward));
142: try {
143: view.modelToView(-1, shape, Position.Bias.Forward);
144: fail("BadLocationException is expected");
145: } catch (BadLocationException e) {
146: }
147: assertEquals(new Rectangle(view.metrics.charWidth('\n')/*0*/,
148: view.metrics.getHeight() * 3, 1, view.metrics
149: .getHeight()), view.modelToView(
150: doc.getLength() + 1, shape, Position.Bias.Forward));
151: try {
152: view.modelToView(doc.getLength() + 2, shape,
153: Position.Bias.Forward);
154: fail("BadLocationException is expected");
155: } catch (BadLocationException e) {
156: }
157: // try {
158: view.modelToView(0, shape, null);
159: // isn't thrown
160: //fail("IllegalArgumentException must be thrown");
161: // } catch (IllegalArgumentException e) { }
162: doc.insertString(1, "\t", null);
163: assertEquals(new Rectangle(view.metrics.charWidth('1'), 0, 1,
164: view.metrics.getHeight()), view.modelToView(1, shape,
165: Position.Bias.Forward));
166: assertEquals(new Rectangle((int) view.nextTabStop(view.metrics
167: .charWidth('1'), 0), 0, 1, view.metrics.getHeight()),
168: view.modelToView(2, shape, Position.Bias.Forward));
169: assertEquals(new Rectangle((int) view.nextTabStop(view.metrics
170: .charWidth('1'), 0)
171: + view.metrics.charWidth(':'), 0, 1, view.metrics
172: .getHeight()), view.modelToView(3, shape,
173: Position.Bias.Forward));
174: }
175:
176: /**
177: * Tests <code>modelToView(int, Shape, Position.Bias)</code> when
178: * <code>shape.getBounds().x != 0</code> and/or
179: * <code>shape.getBounds().y != 0</code>.
180: */
181: public void testModelToViewintShapeBias02()
182: throws BadLocationException {
183: area.setText("1: 0\n2: 012345\n3:\n");
184: ((Rectangle) shape).setLocation(7, 10);
185: assertFalse(((Rectangle) shape).x == 0);
186: assertEquals(new Rectangle(((Rectangle) shape).x,
187: ((Rectangle) shape).y, 1, view.metrics.getHeight()),
188: view.modelToView(0, shape, Position.Bias.Forward));
189: }
190:
191: /**
192: * Tests <code>modelToView(int, Shape, Position.Bias)</code>
193: * with zero-length document.
194: */
195: public void testModelToViewintShapeBias03()
196: throws BadLocationException {
197: area.setText("");
198: assertEquals(0, view.getDocument().getLength());
199: assertEquals(new Rectangle(1, view.metrics.getHeight()), view
200: .modelToView(0, shape, Position.Bias.Forward));
201: assertEquals(new Rectangle(1, view.metrics.getHeight()), view
202: .modelToView(1, shape, Position.Bias.Forward));
203: try {
204: view.modelToView(-1, shape, Position.Bias.Forward);
205: fail("BadLocationException is expected");
206: } catch (BadLocationException e) {
207: }
208: try {
209: view.modelToView(2, shape, Position.Bias.Forward);
210: fail("BadLocationException is expected");
211: } catch (BadLocationException e) {
212: }
213: }
214:
215: /**
216: * Tests nextTabStop method with default tab size of 8.
217: */
218: public void testNextTabStop01() {
219: float tabPos = view.getTabSize() * view.metrics.charWidth('m');
220: assertEquals(8, view.getTabSize());
221: assertEquals(tabPos, view.nextTabStop(0.0f, 0), 0.00001f);
222: assertEquals(tabPos, view.nextTabStop(10.0f, 0), 0.00001f);
223: assertEquals(tabPos, view.nextTabStop(tabPos - 1, 0), 0.00001f);
224: assertEquals(tabPos * 2, view.nextTabStop(tabPos, 0), 0.00001f);
225: // Setting tab size to 4 has no effect on already initialized view
226: doc.putProperty(PlainDocument.tabSizeAttribute, new Integer(4));
227: assertEquals(4, view.getTabSize());
228: // The change has no effect
229: assertEquals(tabPos, view.nextTabStop(0.0f, 0), 0.00001f);
230: // But after metrics have been updated...
231: view.updateMetrics();
232: if (isHarmony()) {
233: // Our implemetation updates tabSize in updateMetrics
234: tabPos = view.getTabSize() * view.metrics.charWidth('m');
235: }
236: assertEquals(tabPos, view.nextTabStop(0.0f, 0), 0.00001f);
237: assertEquals(tabPos * 2, view.nextTabStop(tabPos, 0), 0.00001f);
238: }
239:
240: /*
241: * int viewToModel(float, float, Shape, Position.Bias[])
242: */
243: public void testViewToModelfloatfloatShapeBiasArray()
244: throws BadLocationException {
245: area.setText("1: 0\n2: 012345\n3:\n");
246: // 01234 5678901234 567
247: int h = view.metrics.getHeight();
248: int w = view.metrics.charWidth('1');
249: Position.Bias[] bias = new Position.Bias[1];
250: assertNull(bias[0]);
251: assertEquals(0, view.viewToModel(0f, 0f, shape, bias));
252: assertSame(Position.Bias.Forward, bias[0]);
253: bias[0] = null;
254: assertEquals(0, view.viewToModel(w / 4f, h / 4f, shape, bias));
255: assertSame(Position.Bias.Forward, bias[0]);
256: bias[0] = null;
257: assertEquals(1, view.viewToModel(w - 1f, h / 2f, shape, bias));
258: assertSame(Position.Bias.Forward, bias[0]);
259: bias[0] = null;
260: assertEquals(1, view.viewToModel(w - w / 4f, h / 2f, shape,
261: bias));
262: assertSame(Position.Bias.Forward, bias[0]);
263: bias[0] = null;
264: w = view.metrics.charWidth('2');
265: // Negative coordinates
266: assertEquals(0, view.viewToModel(-1f, h - 0.1f, shape, bias));
267: assertSame(Position.Bias.Forward, bias[0]);
268: bias[0] = null;
269: assertEquals(5, view.viewToModel(-1f, h, shape, bias));
270: assertSame(Position.Bias.Forward, bias[0]);
271: bias[0] = null;
272: assertEquals(5, view.viewToModel(-1f, h + 0.1f, shape, bias));
273: assertSame(Position.Bias.Forward, bias[0]);
274: bias[0] = null;
275: assertEquals(0, view.viewToModel(1f, -1f, shape, bias));
276: assertSame(Position.Bias.Forward, bias[0]);
277: bias[0] = null;
278: assertEquals(0, view.viewToModel(w + 1f, -1f, shape, bias));
279: assertSame(Position.Bias.Forward, bias[0]);
280: bias[0] = null;
281: // Past last character of line 1
282: assertEquals(4, view.viewToModel(view.metrics
283: .stringWidth("1: 0") + 1f, h / 2, shape, bias));
284: assertEquals(4, view.viewToModel(view.metrics
285: .stringWidth("1: 0") + 1f, h - 0.1f, shape, bias));
286: assertSame(Position.Bias.Forward, bias[0]);
287: bias[0] = null;
288: assertEquals(9, view.viewToModel(view.metrics
289: .stringWidth("1: 0"), h, shape, bias));
290: assertSame(Position.Bias.Forward, bias[0]);
291: bias[0] = null;
292: assertEquals(9, view.viewToModel(view.metrics
293: .stringWidth("1: 0"), h + 0.1f, shape, bias));
294: assertSame(Position.Bias.Forward, bias[0]);
295: bias[0] = null;
296: // Below last line
297: h = (int) view.getPreferredSpan(View.Y_AXIS);
298: int pos = doc.getLength();
299: assertEquals(pos, view.viewToModel(0f, h - 0.1f, shape, bias));
300: assertSame(Position.Bias.Forward, bias[0]);
301: bias[0] = null;
302: assertEquals(pos, view.viewToModel(0f, h, shape, bias));
303: assertSame(Position.Bias.Forward, bias[0]);
304: bias[0] = null;
305: assertEquals(pos, view.viewToModel(0f, h + 0.1f, shape, bias));
306: assertSame(Position.Bias.Forward, bias[0]);
307: bias[0] = null;
308: // Test with tab
309: w = view.metrics.charWidth('1');
310: doc.insertString(1, "\t", null);
311: int tab = (int) view.nextTabStop(w, 0);
312: int tabSize = tab - w;
313: assertEquals(1, view.viewToModel(w + tabSize / 2f - 0.5f, 0f,
314: shape, bias));
315: assertEquals(2, view.viewToModel(w + tabSize / 2f + 0.5f, 0f,
316: shape, bias));
317: assertEquals(2, view.viewToModel(tab - 1f, 0f, shape, bias));
318: assertEquals(3, view.viewToModel(tab
319: + view.metrics.charWidth(':') - 1f, 0, shape, bias));
320: }
321:
322: /**
323: * Creates JFrame (<code>frame</code>), puts JTextArea (<code>area</code>)
324: * into it and initializes <code>doc</code>, <code>root</code>,
325: * <code>view</code>, and <code>shape</code> using JTextArea methods.
326: */
327: @Override
328: protected void setUp() throws Exception {
329: super .setUp();
330: frame = new JFrame("PlainView Test");
331: area = new JTextArea(" ");
332: frame.getContentPane().add(area);
333: frame.setSize(100, 150);
334: frame.pack();
335: doc = area.getDocument();
336: view = (PlainView) area.getUI().getRootView(area).getView(0);
337: shape = area.getVisibleRect();
338: }
339:
340: /*
341: * @see TestCase#tearDown()
342: */
343: @Override
344: protected void tearDown() throws Exception {
345: super .tearDown();
346: frame.dispose();
347: }
348: // Painting methods are not tested
349: /*
350: public void testDrawLine() {
351: }
352:
353: public void testPaint() {
354: }
355: */
356: }
|