Package javax.swing.text

Source Code of javax.swing.text.CompositeView_ModelViewTest$ChildFactory

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Alexey A. Ivanov
* @version $Revision$
*
*/
package javax.swing.text;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.BasicSwingTestCase;
import javax.swing.text.AbstractDocument.BranchElement;
import javax.swing.text.CompositeViewTest.CompositeViewImpl;
import javax.swing.text.Position.Bias;
import junit.framework.TestCase;

/**
* Tests CompositeView methods that deal with model/view conversions.
*
*/
public class CompositeView_ModelViewTest extends TestCase {
    static PlainDocument doc; // Document used in tests

    static Element root; // Default root element of the document

    static CompositeView view; // View object used in tests

    static ViewFactory factory; // View factory used to create new views

    static Shape shape; // View allocation (area to render into)

    static Bias[] bias; // Place for bias return

    /**
     * View which passed as parameter to modelToView or viewToModel method.
     */
    private static View viewAsked;

    /**
     * Shape which passed as parameter to modelToView or viewToModel method.
     */
    private static Shape shapeAsked;

    /**
     * Width of one position in the view.
     */
    static final int POS_WIDTH = 4;

    /**
     * Height of one child view, or line.
     */
    static final int LINE_HEIGHT = 16;

    /**
     * Stores the same value as <code>shape</code> but with different
     * type. Actually <code>bounds</code> and <code>shape</code>
     * are the same object.
     */
    private static Rectangle bounds;

    /**
     * Manages some children of type ChildView.
     */
    public static class WithChildrenView extends CompositeViewImpl {
        public WithChildrenView(final Element element) {
            super(element);
        }

        @Override
        protected void childAllocation(final int index, final Rectangle rc) {
            // The each view allocation is LINE_HEIGHT in height and
            // represents a line-like rectangle
            rc.y = ((Rectangle) shape).y + LINE_HEIGHT * index;
            rc.height = LINE_HEIGHT;
        }

        @Override
        protected View getViewAtPoint(final int x, final int y, final Rectangle rc) {
            int index = getViewIndex(x, y, rc);
            if (index != -1) {
                childAllocation(index, rc);
                return getView(index);
            }
            return null;
        }
    }

    /**
     * Represents child view managed by WithChildrenView.
     */
    public static class ChildView extends View {
        public ChildView(final Element element) {
            super(element);
        }

        @Override
        public int viewToModel(float x, final float y, final Shape shape,
                final Bias[] biasReturn) {
            assertTrue(shape.contains(x, y));
            viewAsked = this;
            shapeAsked = shape;
            Rectangle rect = shape.getBounds();
            x -= rect.x;
            return getStartOffset() + (int) x / POS_WIDTH;
        }

        @Override
        public Shape modelToView(int pos, final Shape shape, final Bias bias)
                throws BadLocationException {
            Rectangle bounds = shape.getBounds();
            viewAsked = this;
            shapeAsked = shape;
            pos -= getStartOffset();
            return new Rectangle(bounds.x + pos * POS_WIDTH, bounds.y, 1, 16);
        }

        @Override
        public void paint(final Graphics g, final Shape shape) {
        }

        @Override
        public float getPreferredSpan(final int axis) {
            return 0;
        }
    }

    /**
     * View factory to create ChildView instances.
     */
    public static class ChildFactory implements ViewFactory {
        public View create(final Element element) {
            return new ChildView(element);
        }
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        doc = new PlainDocument();
        doc.insertString(0, "line1\nline2\n\u05DC\u05DD\nline3\n", null);
        // positions: 012345 678901 2 3 4 567890
        // 0 1 2
        root = doc.getDefaultRootElement();
        view = new WithChildrenView(root);
        view.loadChildren(factory = new ChildFactory());
        shape = new Rectangle(100, 200, 190, 560);
        bounds = (Rectangle) shape;
        bias = new Position.Bias[1];
    }

    private Rectangle getChildRect(final int index) throws BadLocationException {
        View child = view.getView(index);
        return (Rectangle) child.modelToView(child.getStartOffset(), Bias.Forward, child
                .getEndOffset(), Bias.Forward, view.getChildAllocation(index, shape));
    }

    /*
     * Class under test for Shape modelToView(int, Bias, int, Bias, Shape)
     */
    public void testModelToViewintBiasintBiasShape() throws BadLocationException {
        Shape res;
        Rectangle rc1;
        Rectangle rc2;
        // Same positions
        res = view.modelToView(0, Bias.Forward, 0, Bias.Forward, shape);
        assertEquals(view.modelToView(0, shape, Bias.Forward), res);
        // Both Forward
        rc1 = (Rectangle) view.modelToView(0, shape, Bias.Forward);
        rc2 = (Rectangle) view.modelToView(1, shape, Bias.Forward);
        res = view.modelToView(0, Bias.Forward, 1, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        rc1 = (Rectangle) view.modelToView(0, shape, Bias.Forward);
        rc2 = (Rectangle) view.modelToView(2, shape, Bias.Forward);
        res = view.modelToView(0, Bias.Forward, 2, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // Different biases
        rc1 = (Rectangle) view.modelToView(0, shape, Bias.Forward);
        rc2 = (Rectangle) view.modelToView(2, shape, Bias.Forward);
        res = view.modelToView(0, Bias.Forward, 2, Bias.Backward, shape);
        assertEquals(rc1.union(rc2), res);
        // On different lines
        rc1 = (Rectangle) view.getView(0).modelToView(6, shape, Bias.Forward);
        rc2 = (Rectangle) view.modelToView(6, shape, Bias.Forward);
        res = view.modelToView(0, Bias.Forward, 6, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        rc1 = getChildRect(0);
        rc2 = (Rectangle) view.modelToView(7, shape, Bias.Forward);
        res = view.modelToView(0, Bias.Forward, 7, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // Assert both previous cases return the same value
        assertEquals(view.modelToView(0, Bias.Forward, 6, Bias.Forward, shape), view
                .modelToView(0, Bias.Forward, 7, Bias.Forward, shape));
        // When range doesn't include first line start
        rc1 = getChildRect(0);
        rc2 = (Rectangle) view.modelToView(9, shape, Bias.Forward);
        res = view.modelToView(2, Bias.Forward, 7, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // Both on line 2
        rc1 = (Rectangle) view.modelToView(7, shape, Bias.Forward);
        rc2 = (Rectangle) view.modelToView(9, shape, Bias.Forward);
        res = view.modelToView(7, Bias.Forward, 9, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // From line 1 to line 3
        // TODO investigate more carefully modelToView(int, B, int, B, Shape)
        //        Can't use this code 'cause view.getChildAllocation(1, shape) and
        //        view.getChildAllocation(2, shape) return the same instance of
        //        rectangles, tho' the instances MUST be different acc. to the spec
        //
        //        rc1 = (Rectangle)view.getChildAllocation(1, shape);
        //        rc1 = rc1.union((Rectangle)view.getChildAllocation(2, shape));
        //        rc1 = rc1.union((Rectangle)view.getChildAllocation(3, shape));
        //
        //        The work around is to get child allocations from the inside but
        //        not the public interface
        rc1 = shape.getBounds();
        view.childAllocation(0, rc1);
        rc2 = shape.getBounds();
        view.childAllocation(2, rc2);
        res = view.modelToView(1, Bias.Forward, 13, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // From line 2 to line 3
        rc1 = getChildRect(1);
        rc2 = (Rectangle) view.modelToView(13, shape, Bias.Forward);
        res = view.modelToView(9, Bias.Forward, 13, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
        // From line 2 to line 4
        rc1 = shape.getBounds();
        view.childAllocation(1, rc1);
        //System.out.println(rc1);
        rc2 = shape.getBounds();
        view.childAllocation(3, rc2);
        res = view.modelToView(9, Bias.Forward, 17, Bias.Forward, shape);
        assertEquals(rc1.union(rc2), res);
    }

    /*
     * Class under test for Shape modelToView(int, Shape, Bias)
     */
    public void testModelToViewintShapeBias() throws BadLocationException {
        assertEquals(new Rectangle(bounds.x, bounds.y, 1, LINE_HEIGHT), view.modelToView(0,
                shape, Bias.Forward));
        assertSame(view.getView(0), viewAsked);
        assertEquals(new Rectangle(bounds.x + 3 * POS_WIDTH, bounds.y, 1, LINE_HEIGHT), view
                .modelToView(3, shape, Bias.Forward));
        assertSame(view.getView(0), viewAsked);
        assertEquals(LINE_HEIGHT, ((Rectangle) shapeAsked).height);
        assertEquals(bounds.y, ((Rectangle) shapeAsked).y);
        assertEquals(new Rectangle(bounds.x + 1 * POS_WIDTH, bounds.y + LINE_HEIGHT, 1,
                LINE_HEIGHT), view.modelToView(7, shape, Bias.Forward));
        assertSame(view.getView(1), viewAsked);
        assertEquals(LINE_HEIGHT, ((Rectangle) shapeAsked).height);
        assertEquals(bounds.y + LINE_HEIGHT, ((Rectangle) shapeAsked).y);
        assertEquals(new Rectangle(bounds.x + 2 * POS_WIDTH, bounds.y + 3 * LINE_HEIGHT, 1,
                LINE_HEIGHT), view.modelToView(17, shape, Bias.Forward));
        assertSame(view.getView(3), viewAsked);
        assertEquals(LINE_HEIGHT, ((Rectangle) shapeAsked).height);
        assertEquals(bounds.y + 3 * LINE_HEIGHT, ((Rectangle) shapeAsked).y);
    }

    /**
     * Tests viewToModel(float, float, Shape, Bias[]).
     * For isBefore, isAfter the Y is used only. In this test either
     * isBefore or isAfter is true.
     */
    public void testViewToModel01() {
        CompositeViewTest.useBoth = false;
        CompositeViewTest.useX = false;
        int x, y;
        // Before the allocation
        x = bounds.x;
        y = bounds.y - 1;
        assertTrue(view.isBefore(x, y, bounds));
        assertEquals(0, view.viewToModel(x, y, shape, bias));
        // After the allocation
        y = bounds.y + bounds.height + 1;
        assertTrue(view.isAfter(x, y, bounds));
        assertEquals(doc.getLength(), view.viewToModel(x, y, shape, bias));
    }

    /**
     * Tests viewToModel(float, float, Shape, Bias[]).
     * For isBefore, isAfter (always false in the test) the Y is used only.
     */
    public void testViewToModel02() {
        CompositeViewTest.useBoth = false;
        CompositeViewTest.useX = false;
        int x, y;
        // In the first box
        x = bounds.x + 5;
        y = bounds.y + 4;
        assertEquals(5 / POS_WIDTH, view.viewToModel(x, y, shape, bias));
        assertSame(view.getView(0), viewAsked);
        assertEquals(view.getChildAllocation(0, shape), shapeAsked);
        viewAsked = null;
        shapeAsked = null;
        // X coordinate is not in the shape
        x = bounds.x - 1;
        y = bounds.y + 4 + LINE_HEIGHT;
        // Assert the condition used internally
        assertFalse(view.isBefore(x, y, bounds));
        assertFalse(view.isAfter(x, y, bounds));
        assertEquals(-1, view.getViewIndex(x, y, shape));
        assertNull(view.getViewAtPoint(x, y, shape.getBounds()));
        // We will get -1, however it's invalid model position
        assertEquals(-1, view.viewToModel(x, y, shape, bias));
        // No view was asked
        assertNull(viewAsked);
        assertNull(shapeAsked);
        // One may easily the assertions above are also true for this case
        x = bounds.x + bounds.width;
        y = bounds.y + 4 + LINE_HEIGHT;
        assertEquals(-1, view.viewToModel(x, y, shape, bias));
        assertNull(viewAsked);
        assertNull(shapeAsked);
        // In the second box
        x = bounds.x;
        y = bounds.y + 4 + LINE_HEIGHT;
        assertEquals(1, view.getViewIndex(x, y, shape));
        assertSame(view.getView(1), view.getViewAtPoint(x, y, shape.getBounds()));
        assertEquals(view.getView(1).getStartOffset(), view.viewToModel(x, y, shape, bias));
        assertSame(view.getView(1), viewAsked);
        assertEquals(LINE_HEIGHT, ((Rectangle) shapeAsked).height);
        assertEquals(bounds.y + LINE_HEIGHT, ((Rectangle) shapeAsked).y);
        viewAsked = null;
        shapeAsked = null;
    }

    /**
     * Tests viewToModel(float, float, Shape, Bias[]).
     * The body is the same as in testViewToModel02
     * (irrelevant asserts are removed) but:
     * for isBefore and isAfter, the X is used only.
     */
    public void testViewToModel03() {
        CompositeViewTest.useBoth = false;
        CompositeViewTest.useX = true;
        int x, y;
        // In the first box
        x = bounds.x + 5;
        y = bounds.y + 4;
        assertEquals(5 / POS_WIDTH, view.viewToModel(x, y, shape, bias));
        assertSame(view.getView(0), viewAsked);
        assertEquals(view.getChildAllocation(0, shape), shapeAsked);
        viewAsked = null;
        shapeAsked = null;
        // X coordinate is not in the shape
        x = bounds.x - 1;
        y = bounds.y + 4 + LINE_HEIGHT;
        // Assert the condition used internally
        assertTrue(view.isBefore(x, y, bounds));
        assertEquals(0, view.viewToModel(x, y, shape, bias));
        // No view was asked
        assertNull(viewAsked);
        assertNull(shapeAsked);
        x = bounds.x + bounds.width + 1;
        y = bounds.y + 4 + LINE_HEIGHT;
        assertTrue(view.isAfter(x, y, bounds));
        assertEquals(doc.getLength(), view.viewToModel(x, y, shape, bias));
        assertNull(viewAsked);
        assertNull(shapeAsked);
        // In the second box
        x = bounds.x;
        y = bounds.y + 4 + LINE_HEIGHT;
        assertEquals(1, view.getViewIndex(x, y, shape));
        assertSame(view.getView(1), view.getViewAtPoint(x, y, shape.getBounds()));
        assertEquals(view.getView(1).getStartOffset(), view.viewToModel(x, y, shape, bias));
        assertSame(view.getView(1), viewAsked);
        assertEquals(LINE_HEIGHT, ((Rectangle) shapeAsked).height);
        assertEquals(bounds.y + LINE_HEIGHT, ((Rectangle) shapeAsked).y);
        viewAsked = null;
        shapeAsked = null;
    }

    /**
     * Tests viewToModel(float, float, Shape, Bias[]).
     * For isBefore, isAfter the Y is used only. In this test either
     * isBefore or isAfter is true.
     * <p>In this test modified <code>root</code> is used so that
     * <code>view.getStartOffset() != 0</code> and
     * <code>view.getEndOffset() != doc.getLength()</code>.
     */
    public void testViewToModel04() {
        // Modify the root
        final int oldCount = root.getElementCount();
        BranchElement docRoot = (BranchElement) root;
        final Element[] empty = new Element[0];
        docRoot.replace(0, 1, empty);
        docRoot.replace(docRoot.getElementCount() - 1, 1, empty);
        final int newCount = root.getElementCount();
        assertEquals(oldCount - 2, newCount);
        // Re-load children
        view.removeAll();
        view.loadChildren(factory);
        CompositeViewTest.useBoth = false;
        CompositeViewTest.useX = false;
        int x, y;
        // Before the allocation
        x = bounds.x;
        y = bounds.y - 1;
        assertTrue(view.isBefore(x, y, bounds));
        int offset = view.viewToModel(x, y, shape, bias);
        assertEquals(view.getStartOffset(), offset);
        assertEquals(root.getElement(0).getStartOffset(), offset);
        // After the allocation
        y = bounds.y + bounds.height + 1;
        assertTrue(view.isAfter(x, y, bounds));
        bias[0] = null;
        offset = view.viewToModel(x, y, shape, bias);
        assertEquals(view.getEndOffset() - 1, offset);
        assertEquals(root.getElement(root.getElementCount() - 1).getEndOffset() - 1, offset);
        if (BasicSwingTestCase.isHarmony()) {
            assertSame(Bias.Backward, bias[0]);
        }
    }

    public void testViewToModel05() {
        final boolean[] methodCalled = new boolean[] { false };
        view = new WithChildrenView(root) {
            @Override
            protected View getViewAtPoint(int x, int y, Rectangle rc) {
                methodCalled[0] = true;
                return super.getViewAtPoint(x, y, rc);
            }
        };
        view.loadChildren(factory);
        assertFalse(methodCalled[0]);
        view.viewToModel(bounds.x + bounds.width / 2, bounds.y + bounds.height, shape, bias);
        assertTrue(methodCalled[0]);
        assertSame(view.getView(view.getViewIndex(bounds.x, bounds.y, shape)), view
                .getViewAtPoint(bounds.x, bounds.y, view.getInsideAllocation(shape)));
    }
}
TOP

Related Classes of javax.swing.text.CompositeView_ModelViewTest$ChildFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.