0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package javax.swing.text;
0018:
0019: import java.awt.Container;
0020: import java.awt.Graphics;
0021: import java.awt.Rectangle;
0022: import java.awt.Shape;
0023: import java.awt.image.BufferedImage;
0024: import java.util.ArrayList;
0025: import javax.swing.BasicSwingTestCase;
0026: import javax.swing.JTextArea;
0027: import javax.swing.SizeRequirements;
0028: import javax.swing.event.DocumentEvent;
0029: import javax.swing.event.DocumentListener;
0030: import javax.swing.event.DocumentEvent.ElementChange;
0031: import javax.swing.text.Position.Bias;
0032: import javax.swing.text.ViewTestHelpers.ChildView;
0033: import javax.swing.text.ViewTestHelpers.ChildrenFactory;
0034:
0035: /**
0036: * Tests BoxView class which has special children.
0037: */
0038: public class BoxView_WithChildrenTest extends BasicSwingTestCase
0039: implements DocumentListener {
0040: private static final int Y_AXIS = View.Y_AXIS;
0041:
0042: private static final int X_AXIS = View.X_AXIS;
0043:
0044: private static final int POS = ViewTestHelpers.POS;
0045:
0046: /**
0047: * Invalid axis: neither X_AXIS nor Y_AXIS.
0048: */
0049: private static final int INVALID_AXIS = 2;
0050:
0051: private static final int MINIMUM = 0;
0052:
0053: private static final int PREFERRED = 1;
0054:
0055: private static final int MAXIMUM = 2;
0056:
0057: /**
0058: * Document used in testing.
0059: */
0060: private Document doc;
0061:
0062: /**
0063: * Default root of the document. It is the element <code>BoxView</code> is
0064: * constructed with.
0065: */
0066: private Element root;
0067:
0068: /**
0069: * View under test.
0070: */
0071: private BoxView view;
0072:
0073: /**
0074: * Factory to create child views.
0075: */
0076: private ChildrenFactory factory;
0077:
0078: /**
0079: * View allocation.
0080: */
0081: private Rectangle shape;
0082:
0083: /**
0084: * Size requirements along major - Y - axis.
0085: */
0086: private SizeRequirements major;
0087:
0088: /**
0089: * Size requirements along minor - X - axis.
0090: */
0091: private SizeRequirements minor;
0092:
0093: /**
0094: * Rectangle where repaint should occur.
0095: */
0096: private Rectangle paintRect;
0097:
0098: private boolean componentRepaint;
0099:
0100: private DocumentEvent insertEvent;
0101:
0102: private class BoxViewImpl extends BoxView {
0103: public BoxViewImpl(Element element, int axis) {
0104: super (element, axis);
0105: }
0106:
0107: @Override
0108: public ViewFactory getViewFactory() {
0109: return factory;
0110: }
0111:
0112: private Container container;
0113:
0114: @Override
0115: public Container getContainer() {
0116: if (container == null) {
0117: container = new JTextArea() {
0118: private static final long serialVersionUID = 1L;
0119:
0120: @Override
0121: public void repaint(final int x, final int y,
0122: final int w, final int h) {
0123: paintRect = new Rectangle(x, y, w, h);
0124: }
0125:
0126: @Override
0127: public void repaint() {
0128: componentRepaint = true;
0129: }
0130: };
0131: }
0132: return container;
0133: }
0134: }
0135:
0136: /*
0137: * @see TestCase#setUp()
0138: */
0139: @Override
0140: protected void setUp() throws Exception {
0141: super .setUp();
0142: doc = new PlainDocument();
0143: doc.insertString(0, "uno\ndos\t2\ntres\ncuatro", null);
0144: root = doc.getDefaultRootElement();
0145: view = new BoxViewImpl(root, Y_AXIS);
0146: factory = new ChildrenFactory();
0147: view.loadChildren(factory);
0148: shape = new Rectangle(10, 5, 123, 435);
0149: major = view.calculateMajorAxisRequirements(Y_AXIS, null);
0150: minor = view.calculateMinorAxisRequirements(X_AXIS, null);
0151: }
0152:
0153: public void testGetChildAllocation() {
0154: assertNull(view.getChildAllocation(0, shape));
0155: assertNull(view.getChildAllocation(1, shape));
0156: view.layout(shape.width, shape.height);
0157: assertNull(view.getChildAllocation(0, null));
0158: assertNull(view.getChildAllocation(1, null));
0159: assertEquals(new Rectangle(getChildX(0), getChildY(0),
0160: getWidth(0), getHeight(0)), view.getChildAllocation(0,
0161: shape));
0162: assertEquals(new Rectangle(getChildX(1), getChildY(1),
0163: getWidth(1), getHeight(1)), view.getChildAllocation(1,
0164: shape));
0165: assertEquals(new Rectangle(getChildX(2), getChildY(2),
0166: getWidth(2), getHeight(2)), view.getChildAllocation(2,
0167: shape));
0168: assertEquals(new Rectangle(getChildX(3), getChildY(3),
0169: getWidth(3), getHeight(3)), view.getChildAllocation(3,
0170: shape));
0171: }
0172:
0173: public void testChildAllocation() {
0174: Rectangle alloc;
0175: final Rectangle invalidLayoutAlloc = new Rectangle(shape.x,
0176: shape.y, 0, 0);
0177: alloc = (Rectangle) shape.clone();
0178: view.childAllocation(0, alloc);
0179: assertEquals(invalidLayoutAlloc, alloc);
0180: alloc = (Rectangle) shape.clone();
0181: view.childAllocation(1, alloc);
0182: assertEquals(invalidLayoutAlloc, alloc);
0183: view.layout(shape.width, shape.height);
0184: alloc = (Rectangle) shape.clone();
0185: view.childAllocation(0, alloc);
0186: assertEquals(new Rectangle(getChildX(0), getChildY(0),
0187: getWidth(0), getHeight(0)), alloc);
0188: alloc = (Rectangle) shape.clone();
0189: view.childAllocation(1, alloc);
0190: assertEquals(new Rectangle(getChildX(1), getChildY(1),
0191: getWidth(1), getHeight(1)), alloc);
0192: }
0193:
0194: // Regression test for HARMONY-2776
0195: public void testChildAllocationNull() throws Exception {
0196: final Marker marker = new Marker();
0197: view = new BoxView(root, Y_AXIS) {
0198: @Override
0199: protected void childAllocation(int index, Rectangle alloc) {
0200: marker.setOccurred();
0201: super .childAllocation(index, alloc);
0202: }
0203:
0204: @Override
0205: protected Rectangle getInsideAllocation(Shape shape) {
0206: return null;
0207: }
0208: };
0209: view.loadChildren(factory);
0210: view.layout(shape.width, shape.height);
0211: assertTrue(view.isLayoutValid(X_AXIS)
0212: && view.isLayoutValid(Y_AXIS));
0213: assertNull(view.getChildAllocation(0, null));
0214: assertFalse(marker.isOccurred());
0215: try {
0216: view.getChildAllocation(0, shape);
0217: fail("NullPointerException is expected");
0218: } catch (NullPointerException e) {
0219: // expected
0220: }
0221: assertTrue(marker.isOccurred());
0222: }
0223:
0224: public void testFlipEastAndWestAtEnds() {
0225: assertEquals(Y_AXIS, view.getAxis());
0226: // Child views are not instances of CompositeView (no flip method)
0227: assertFalse(view.flipEastAndWestAtEnds(1, Bias.Backward));
0228: final View[] viewCalledUpon = new View[1];
0229: // Fill view with new children which are instances of CompositeView
0230: view.removeAll();
0231: view.loadChildren(new ViewFactory() {
0232: public View create(final Element element) {
0233: return new CompositeViewTest.CompositeViewImpl(element) {
0234: @Override
0235: protected boolean flipEastAndWestAtEnds(
0236: final int position, final Bias bias) {
0237: viewCalledUpon[0] = this ;
0238: return (position & 1) == 0;
0239: }
0240: };
0241: }
0242: });
0243: // Test it may be true
0244: assertTrue(view.flipEastAndWestAtEnds(0, null));
0245: assertTrue(view.flipEastAndWestAtEnds(0, Bias.Backward));
0246: // Check flip is called on a child
0247: viewCalledUpon[0] = null;
0248: view.flipEastAndWestAtEnds(view.getView(0).getEndOffset(),
0249: Bias.Backward);
0250: assertSame(view.getView(0), viewCalledUpon[0]);
0251: viewCalledUpon[0] = null;
0252: view.flipEastAndWestAtEnds(view.getView(0).getEndOffset(),
0253: Bias.Forward);
0254: assertSame(view.getView(1), viewCalledUpon[0]);
0255: viewCalledUpon[0] = null;
0256: // Select X as major axis
0257: view.setAxis(X_AXIS);
0258: // This simply returns false without calling other methods
0259: assertFalse(view.flipEastAndWestAtEnds(0, Bias.Forward));
0260: assertNull(viewCalledUpon[0]);
0261: assertFalse(view.flipEastAndWestAtEnds(1, Bias.Backward));
0262: assertNull(viewCalledUpon[0]);
0263: }
0264:
0265: public void testFlipEastAndWestAtEndsIndex() throws Exception {
0266: final Marker marker = new Marker();
0267: view = new BoxView(root, Y_AXIS) {
0268: @Override
0269: protected int getViewIndexAtPosition(int pos) {
0270: marker.setOccurred();
0271: marker.setAuxiliary(new Integer(pos));
0272: return super .getViewIndexAtPosition(pos);
0273: }
0274: };
0275: view.loadChildren(factory);
0276: assertEquals(root.getElementCount(), view.getViewCount());
0277: view.flipEastAndWestAtEnds(0, Bias.Forward);
0278: assertTrue(marker.isOccurred());
0279: assertEquals(0, ((Integer) marker.getAuxiliary()).intValue());
0280: marker.reset();
0281: view.flipEastAndWestAtEnds(1, Bias.Backward);
0282: assertTrue(marker.isOccurred());
0283: assertEquals(0, ((Integer) marker.getAuxiliary()).intValue());
0284: marker.reset();
0285: view.flipEastAndWestAtEnds(1, null);
0286: assertTrue(marker.isOccurred());
0287: assertEquals(1, ((Integer) marker.getAuxiliary()).intValue());
0288: marker.reset();
0289: view.flipEastAndWestAtEnds(1, Bias.Forward);
0290: assertTrue(marker.isOccurred());
0291: assertEquals(1, ((Integer) marker.getAuxiliary()).intValue());
0292: marker.reset();
0293: view.flipEastAndWestAtEnds(1, Bias.Backward);
0294: assertTrue(marker.isOccurred());
0295: assertEquals(0, ((Integer) marker.getAuxiliary()).intValue());
0296: marker.reset();
0297: view.flipEastAndWestAtEnds(view.getEndOffset(), Bias.Forward);
0298: assertTrue(marker.isOccurred());
0299: assertEquals(view.getEndOffset(), ((Integer) marker
0300: .getAuxiliary()).intValue());
0301: marker.reset();
0302: view.flipEastAndWestAtEnds(view.getEndOffset(), Bias.Backward);
0303: assertTrue(marker.isOccurred());
0304: assertEquals(view.getEndOffset() - 1, ((Integer) marker
0305: .getAuxiliary()).intValue());
0306: marker.reset();
0307: }
0308:
0309: /**
0310: * General checks.
0311: */
0312: public void testGetViewAtPoint01() {
0313: Rectangle alloc;
0314: view.layout(shape.width, shape.height);
0315: alloc = (Rectangle) shape.clone();
0316: assertSame(view.getView(0), view.getViewAtPoint(
0317: getChildX(0) - 1, getChildY(0) - 1, alloc));
0318: assertEquals(view.getChildAllocation(0, shape), alloc);
0319: alloc = (Rectangle) shape.clone();
0320: assertSame(view.getView(0), view.getViewAtPoint(getChildX(0),
0321: getChildY(0), alloc));
0322: assertEquals(view.getChildAllocation(0, shape), alloc);
0323: alloc = (Rectangle) shape.clone();
0324: assertSame(view.getView(0), view.getViewAtPoint(getChildX(0)
0325: + getWidth(0) - 1, getChildY(0) + getHeight(0) - 1,
0326: alloc));
0327: assertEquals(view.getChildAllocation(0, shape), alloc);
0328: alloc = (Rectangle) shape.clone();
0329: assertSame(view.getView(1), view.getViewAtPoint(getChildX(0)
0330: + getWidth(0), getChildY(0) + getHeight(0), alloc));
0331: assertEquals(view.getChildAllocation(1, shape), alloc);
0332: alloc = (Rectangle) shape.clone();
0333: assertSame(view.getView(1), view.getViewAtPoint(shape.x,
0334: getChildY(1) + 1, alloc));
0335: assertEquals(view.getChildAllocation(1, shape), alloc);
0336: alloc = (Rectangle) shape.clone();
0337: assertSame(view.getView(1), view.getViewAtPoint(
0338: getChildX(1) - 1, getChildY(1) + 1, alloc));
0339: assertEquals(view.getChildAllocation(1, shape), alloc);
0340: alloc = (Rectangle) shape.clone();
0341: assertSame(view.getView(2), view.getViewAtPoint(shape.x - 5,
0342: getChildY(2) + 1, alloc));
0343: assertEquals(view.getChildAllocation(2, shape), alloc);
0344: }
0345:
0346: /**
0347: * Checks with invalid coordinates: outside of the shape.
0348: */
0349: public void testGetViewAtPoint02() {
0350: Rectangle alloc;
0351: view.layout(shape.width, shape.height);
0352: final int x = shape.x - 20;
0353: alloc = (Rectangle) shape.clone();
0354: assertSame(view.getView(0), view.getViewAtPoint(x,
0355: getChildY(0), alloc));
0356: assertEquals(view.getChildAllocation(0, shape), alloc);
0357: alloc = (Rectangle) shape.clone();
0358: assertSame(view.getView(0), view.getViewAtPoint(x,
0359: shape.y - 15, alloc));
0360: assertEquals(view.getChildAllocation(0, shape), alloc);
0361: alloc = (Rectangle) shape.clone();
0362: assertSame(view.getView(0), view.getViewAtPoint(shape.x
0363: + shape.width + 25, getChildY(0), alloc));
0364: assertEquals(view.getChildAllocation(0, shape), alloc);
0365: alloc = (Rectangle) shape.clone();
0366: assertSame(view.getView(view.getViewCount() - 1), view
0367: .getViewAtPoint(x, shape.y + shape.height, alloc));
0368: assertEquals(view.getChildAllocation(view.getViewCount() - 1,
0369: shape), alloc);
0370: alloc = (Rectangle) shape.clone();
0371: assertSame(view.getView(view.getViewCount() - 1), view
0372: .getViewAtPoint(x, shape.y + shape.height + 157, alloc));
0373: assertEquals(view.getChildAllocation(view.getViewCount() - 1,
0374: shape), alloc);
0375: }
0376:
0377: /**
0378: * Tests getViewAtPoint method when major axis of the view is X.
0379: */
0380: public void testGetViewAtPoint03() {
0381: Rectangle alloc;
0382: view = new BoxViewImpl(root, X_AXIS);
0383: factory.resetID();
0384: view.loadChildren(factory);
0385: major = view.calculateMajorAxisRequirements(X_AXIS, null);
0386: minor = view.calculateMinorAxisRequirements(Y_AXIS, null);
0387: view.layout(shape.width, shape.height);
0388: int x = shape.x - 20;
0389: int y = shape.y + view.getOffset(X_AXIS, 1)
0390: + view.getSpan(X_AXIS, 1) / 2;
0391: // This value of y is to catch the bug in our implementation which
0392: // uses not major axis but always y to find views. With this y value,
0393: // the original code will return view at index 1 but not 0.
0394: alloc = (Rectangle) shape.clone();
0395: assertTrue(view.isBefore(x, y, alloc));
0396: assertSame(view.getView(0), view.getViewAtPoint(x, y, alloc));
0397: assertEquals(view.getChildAllocation(0, shape), alloc);
0398: x = shape.x;
0399: alloc = (Rectangle) shape.clone();
0400: assertFalse(view.isBefore(x, y, alloc));
0401: assertFalse(view.isAfter(x, y, alloc));
0402: assertSame(view.getView(0), view.getViewAtPoint(x, y, alloc));
0403: assertEquals(view.getChildAllocation(0, shape), alloc);
0404: y = -277;
0405: alloc = (Rectangle) shape.clone();
0406: assertFalse(view.isBefore(x, y, alloc));
0407: assertFalse(view.isAfter(x, y, alloc));
0408: assertSame(view.getView(0), view.getViewAtPoint(x, y, alloc));
0409: assertEquals(view.getChildAllocation(0, shape), alloc);
0410: final int lastIndex = view.getViewCount() - 1;
0411: y = shape.y + shape.height / 2;
0412: x = shape.x + view.getOffset(X_AXIS, lastIndex)
0413: + view.getSpan(X_AXIS, lastIndex);
0414: alloc = (Rectangle) shape.clone();
0415: alloc.width = x - shape.x + 1; // This is to include the last child
0416: // in the allocation
0417: assertFalse(view.isBefore(x, y, alloc));
0418: assertFalse(view.isAfter(x, y, alloc));
0419: assertSame(view.getView(lastIndex), view.getViewAtPoint(x, y,
0420: alloc));
0421: assertEquals(view.getChildAllocation(lastIndex, shape), alloc);
0422: alloc = (Rectangle) shape.clone(); // The last child doesn't fit
0423: // in the allocation
0424: assertFalse(view.isBefore(x, y, alloc));
0425: assertTrue(view.isAfter(x, y, alloc));
0426: assertSame(view.getView(lastIndex), view.getViewAtPoint(x, y,
0427: alloc));
0428: assertEquals(view.getChildAllocation(lastIndex, shape), alloc);
0429: alloc = (Rectangle) shape.clone();
0430: alloc.width = x - shape.x + 1; // Adjust allocation to fit the last
0431: x += 315; // child and move x beyond
0432: assertTrue(view.isAfter(x, y, alloc));
0433: assertSame(view.getView(lastIndex), view.getViewAtPoint(x, y,
0434: alloc));
0435: assertEquals(view.getChildAllocation(lastIndex, shape), alloc);
0436: alloc = (Rectangle) shape.clone();
0437: alloc.width = x - shape.x + 1;
0438: x += 315;
0439: assertTrue(view.isAfter(x, y, alloc));
0440: assertSame(view.getView(lastIndex), view.getViewAtPoint(x, y,
0441: alloc));
0442: assertEquals(view.getChildAllocation(lastIndex, shape), alloc);
0443: }
0444:
0445: /**
0446: * Tests <code>baselineLayout</code> with
0447: * <em>non-resizable</em> child views.
0448: * <p>The test performed for both major and minor axes.
0449: */
0450: public void testBaselineLayout01() {
0451: int[] offsets = new int[view.getViewCount()];
0452: int[] spans = new int[view.getViewCount()];
0453: int axis = Y_AXIS;
0454: // Check with major axis
0455: assertEquals(axis, view.getAxis());
0456: view.baselineLayout(shape.height, axis, offsets, spans);
0457: int leftInset = shape.height / 2;
0458: for (int i = 0; i < offsets.length; i++) {
0459: View child = view.getView(i);
0460: float span = child.getPreferredSpan(axis);
0461: float offset = leftInset - span * child.getAlignment(axis);
0462: assertEquals("@ " + i, (int) offset, offsets[i]);
0463: assertEquals("@ " + i, (int) span, spans[i]);
0464: }
0465: // Check with minor axis
0466: axis = X_AXIS;
0467: view.baselineLayout(shape.width, axis, offsets, spans);
0468: leftInset = shape.width / 2;
0469: for (int i = 0; i < offsets.length; i++) {
0470: View child = view.getView(i);
0471: float span = child.getPreferredSpan(axis);
0472: float offset = leftInset - span * child.getAlignment(axis);
0473: if (i == 1) {
0474: // The cause is rounding errors
0475: offset += 1;
0476: }
0477: assertEquals("@ " + i, (int) offset, offsets[i]);
0478: assertEquals("@ " + i, (int) span, spans[i]);
0479: }
0480: }
0481:
0482: /**
0483: * Tests <code>baselineLayout</code> with <em>resizable</em> child views.
0484: * <p>The test performed for major axis only.
0485: */
0486: public void testBaselineLayout02() {
0487: makeFlexible();
0488: int[] offsets = new int[view.getViewCount()];
0489: int[] spans = new int[view.getViewCount()];
0490: int axis = Y_AXIS;
0491: // Check with major axis
0492: assertEquals(axis, view.getAxis());
0493: view.baselineLayout(shape.height, axis, offsets, spans);
0494: int[] resultOffsets = new int[] { 217, 201, 0, 209 };
0495: int[] resultSpans = new int[] { 80, 64, 217, 16 };
0496: for (int i = 0; i < offsets.length; i++) {
0497: assertEquals("@ " + i, resultOffsets[i], offsets[i]);
0498: assertEquals("@ " + i, resultSpans[i], spans[i]);
0499: }
0500: }
0501:
0502: /**
0503: * Tests <code>baselineRequirements</code> with ordinary children along
0504: * major axis - Y.
0505: */
0506: public void testBaselineRequirements01() {
0507: SizeRequirements sr;
0508: final int axis = Y_AXIS;
0509: sr = view.baselineRequirements(axis, null);
0510: // The sizes to the left and to the right from the alignment point
0511: int left = getLeft(PREFERRED, axis);
0512: int right = getRight(PREFERRED, axis);
0513: int size = left + right;
0514: assertEquals(size, sr.minimum);
0515: assertEquals(size, sr.preferred);
0516: assertEquals(size, sr.maximum);
0517: assertEquals((float) left / (float) size, sr.alignment,
0518: 0.00001f);
0519: SizeRequirements another = view.baselineRequirements(axis, sr);
0520: assertSame(sr, another);
0521: }
0522:
0523: /**
0524: * Tests <code>baselineRequirements</code> with flexible children along
0525: * major axis - Y.
0526: */
0527: public void testBaselineRequirements02() {
0528: if (!isHarmony()) {
0529: return;
0530: }
0531: makeFlexible();
0532: SizeRequirements sr;
0533: final int axis = Y_AXIS;
0534: sr = view.baselineRequirements(axis, null);
0535: // The sizes to the left and to the right from the alignment point
0536: int minL = getLeft(MINIMUM, axis);
0537: int minR = getRight(MINIMUM, axis);
0538: int prefL = getLeft(PREFERRED, axis);
0539: int prefR = getRight(PREFERRED, axis);
0540: int maxL = getLeft(MAXIMUM, axis);
0541: int maxR = getRight(MAXIMUM, axis);
0542: int min = minL + minR;
0543: int pref = prefL + prefR;
0544: int max = maxL + maxR;
0545: assertEquals(min, sr.minimum);
0546: assertEquals(pref, sr.preferred);
0547: assertEquals(max, sr.maximum);
0548: assertEquals((float) prefL / (float) pref, sr.alignment,
0549: 0.00001f);
0550: }
0551:
0552: /**
0553: * Tests <code>baselineRequirements</code> with ordinary children along
0554: * minor axis - X.
0555: */
0556: public void testBaselineRequirements03() {
0557: SizeRequirements sr;
0558: final int axis = X_AXIS;
0559: sr = view.baselineRequirements(axis, null);
0560: // The sizes to the left and to the right from the alignment point
0561: int left = getLeft(PREFERRED, axis);
0562: int right = getRight(PREFERRED, axis);
0563: int size = left + right + 1; // there should be no 1 added
0564: assertEquals(size, sr.minimum);
0565: assertEquals(size, sr.preferred);
0566: assertEquals(size, sr.maximum);
0567: assertEquals((float) left / (float) size, sr.alignment,
0568: 0.00001f);
0569: }
0570:
0571: /**
0572: * Tests <code>calculateMajorAxisRequirements</code> with ordinary children.
0573: */
0574: public void testCalculateMajorAxisRequirements01() {
0575: SizeRequirements in = null;
0576: SizeRequirements out;
0577: out = view.calculateMajorAxisRequirements(Y_AXIS, in);
0578: assertNull(in);
0579: assertNotNull(out);
0580: int height = 0;
0581: for (int i = 0; i < view.getViewCount(); i++) {
0582: height += getHeight(i);
0583: }
0584: assertEquals(height, out.minimum);
0585: assertEquals(height, out.preferred);
0586: assertEquals(height, out.maximum);
0587: assertEquals(view.getAlignment(Y_AXIS), out.alignment, 0.00001f);
0588: in = new SizeRequirements();
0589: out = view.calculateMajorAxisRequirements(Y_AXIS, in);
0590: assertSame(in, out);
0591: }
0592:
0593: /**
0594: * Tests <code>calculateMajorAxisRequirements</code> with flexible children.
0595: */
0596: public void testCalculateMajorAxisRequirements02() {
0597: makeFlexible();
0598: int min = 0; // Requirements are sum
0599: int pref = 0;
0600: int max = 0;
0601: for (int i = 0; i < view.getViewCount(); i++) {
0602: View child = view.getView(i);
0603: min += child.getMinimumSpan(Y_AXIS);
0604: pref += child.getPreferredSpan(Y_AXIS);
0605: max += child.getMaximumSpan(Y_AXIS);
0606: }
0607: assertEquals(min, major.minimum);
0608: assertEquals(pref, major.preferred);
0609: assertEquals(max, major.maximum);
0610: assertEquals(view.getAlignment(Y_AXIS), major.alignment,
0611: 0.00001f);
0612: }
0613:
0614: /**
0615: * Tests <code>calculateMinorAxisRequirements</code> with ordinary children.
0616: */
0617: public void testCalculateMinorAxisRequirements01() {
0618: SizeRequirements in = null;
0619: SizeRequirements out;
0620: out = view.calculateMinorAxisRequirements(X_AXIS, in);
0621: assertNull(in);
0622: assertNotNull(out);
0623: int width = getWidth(0);
0624: for (int i = 1; i < view.getViewCount(); i++) {
0625: if (getWidth(i) > width) {
0626: width = getWidth(i);
0627: }
0628: }
0629: assertEquals(width, out.minimum);
0630: assertEquals(width, out.preferred);
0631: assertEquals(Integer.MAX_VALUE, out.maximum);
0632: assertEquals(view.getAlignment(X_AXIS), out.alignment, 0.00001f);
0633: in = new SizeRequirements();
0634: out = view.calculateMinorAxisRequirements(X_AXIS, in);
0635: assertSame(in, out);
0636: }
0637:
0638: /**
0639: * Tests <code>calculateMinorAxisRequirements</code> with flexible children.
0640: */
0641: public void testCalculateMinorAxisRequirements02() {
0642: makeFlexible();
0643: int min = 0; // Requirements are maximum values
0644: int pref = 0;
0645: // The parent, however, can be huge
0646: int max = (int) view.getMaximumSpan(X_AXIS);
0647: for (int i = 0; i < view.getViewCount(); i++) {
0648: View child = view.getView(i);
0649: if (min < child.getMinimumSpan(X_AXIS)) {
0650: min = (int) child.getMinimumSpan(X_AXIS);
0651: }
0652: if (pref < child.getPreferredSpan(X_AXIS)) {
0653: pref = (int) child.getPreferredSpan(X_AXIS);
0654: }
0655: }
0656: assertEquals(min, minor.minimum);
0657: assertEquals(pref, minor.preferred);
0658: assertEquals(max, minor.maximum);
0659: assertEquals(view.getAlignment(X_AXIS), minor.alignment,
0660: 0.00001f);
0661: }
0662:
0663: /**
0664: * Tests forwardUpdate when major axis is Y_AXIS and
0665: * document structure isn't changed. The child says it changed its
0666: * preference along both axes.
0667: * (See javax.swing.text.ViewTestHelpers.ChildView.insertUpdate()).
0668: */
0669: public void testForwardUpdate01() throws BadLocationException {
0670: view.getContainer();
0671: componentRepaint = false;
0672: doc.addDocumentListener(this );
0673: doc.insertString(root.getElement(2).getStartOffset() + 1,
0674: "123", null);
0675: ElementChange change = insertEvent.getChange(view.getElement());
0676: assertNull(change);
0677: view.layout(shape.width, shape.height);
0678: assertTrue(view.isLayoutValid(X_AXIS));
0679: assertTrue(view.isLayoutValid(Y_AXIS));
0680: view.forwardUpdate(change, insertEvent, shape, factory);
0681: assertFalse(view.isLayoutValid(X_AXIS));
0682: assertFalse(view.isLayoutValid(Y_AXIS));
0683: assertFalse(componentRepaint);
0684: Rectangle bounds = view.getInsideAllocation(shape);
0685: int childIndex = view.getViewIndex(insertEvent.getOffset(),
0686: Bias.Forward);
0687: if (isHarmony()) {
0688: bounds.y += view.getOffset(view.getAxis(), childIndex);
0689: bounds.height -= view.getOffset(view.getAxis(), childIndex);
0690: } else {
0691: bounds.y = 28;
0692: bounds.height = 412;
0693: }
0694: assertEquals(paintRect, bounds);
0695: }
0696:
0697: /**
0698: * Tests forwardUpdate when major axis is Y_AXIS and
0699: * document structure isn't changed. The child says it changed its
0700: * prefence along X_AXIS only.
0701: */
0702: public void testForwardUpdate02() throws BadLocationException {
0703: doc.addDocumentListener(this );
0704: doc.insertString(root.getElement(2).getStartOffset() + 1,
0705: "123", null);
0706: ElementChange change = insertEvent.getChange(view.getElement());
0707: assertNull(change);
0708: final int childIndex = view.getViewIndex(insertEvent
0709: .getOffset(), Bias.Forward);
0710: final View child = view.getView(childIndex);
0711: view.replace(childIndex, 1, new View[] { new ChildView(child
0712: .getElement(), -1) {
0713: @Override
0714: public void preferenceChanged(final View child,
0715: final boolean width, final boolean height) {
0716: super .preferenceChanged(child, true, false);
0717: }
0718: } });
0719: view.layout(shape.width, shape.height);
0720: assertTrue(view.isLayoutValid(X_AXIS));
0721: assertTrue(view.isLayoutValid(Y_AXIS));
0722: view.forwardUpdate(change, insertEvent, shape, factory);
0723: assertFalse(view.isLayoutValid(X_AXIS));
0724: assertTrue(view.isLayoutValid(Y_AXIS));
0725: assertFalse(componentRepaint);
0726: assertNull(paintRect);
0727: }
0728:
0729: /**
0730: * Tests forwardUpdate when major axis is X_AXIS and
0731: * document structure isn't changed. The child says it changed its
0732: * preference along both axes.
0733: * (See javax.swing.text.ViewTestHelpers.ChildView.insertUpdate()).
0734: */
0735: public void testForwardUpdate03() throws BadLocationException {
0736: view = new BoxViewImpl(root, X_AXIS);
0737: view.loadChildren(factory);
0738: view.getContainer();
0739: componentRepaint = false;
0740: doc.addDocumentListener(this );
0741: doc.insertString(root.getElement(2).getStartOffset() + 1,
0742: "123", null);
0743: ElementChange change = insertEvent.getChange(view.getElement());
0744: assertNull(change);
0745: view.layout(shape.width, shape.height);
0746: assertTrue(view.isLayoutValid(X_AXIS));
0747: assertTrue(view.isLayoutValid(Y_AXIS));
0748: view.forwardUpdate(change, insertEvent, shape, factory);
0749: assertFalse(view.isLayoutValid(X_AXIS));
0750: assertFalse(view.isLayoutValid(Y_AXIS));
0751: assertFalse(componentRepaint);
0752: Rectangle bounds = view.getInsideAllocation(shape);
0753: int childIndex = view.getViewIndex(insertEvent.getOffset(),
0754: Bias.Forward);
0755: bounds.x += view.getOffset(view.getAxis(), childIndex);
0756: bounds.width -= view.getOffset(view.getAxis(), childIndex);
0757: assertEquals(paintRect, bounds);
0758: }
0759:
0760: /**
0761: * Tests forwardUpdate when major axis is X_AXIS and
0762: * document structure isn't changed. The child says it changed its
0763: * preference along Y_AXIS only.
0764: */
0765: public void testForwardUpdate04() throws BadLocationException {
0766: view = new BoxViewImpl(root, X_AXIS);
0767: view.loadChildren(factory);
0768: doc.addDocumentListener(this );
0769: doc.insertString(root.getElement(2).getStartOffset() + 1,
0770: "123", null);
0771: ElementChange change = insertEvent.getChange(view.getElement());
0772: assertNull(change);
0773: final int childIndex = view.getViewIndex(insertEvent
0774: .getOffset(), Bias.Forward);
0775: final View child = view.getView(childIndex);
0776: view.replace(childIndex, 1, new View[] { new ChildView(child
0777: .getElement(), -1) {
0778: @Override
0779: public void preferenceChanged(final View child,
0780: final boolean width, final boolean height) {
0781: super .preferenceChanged(child, false, true);
0782: }
0783: } });
0784: view.layout(shape.width, shape.height);
0785: assertTrue(view.isLayoutValid(X_AXIS));
0786: assertTrue(view.isLayoutValid(Y_AXIS));
0787: view.forwardUpdate(change, insertEvent, shape, factory);
0788: assertTrue(view.isLayoutValid(X_AXIS));
0789: assertFalse(view.isLayoutValid(Y_AXIS));
0790: assertFalse(componentRepaint);
0791: assertNull(paintRect);
0792: }
0793:
0794: public void testInsertUpdate() throws BadLocationException {
0795: doc.addDocumentListener(this );
0796: doc.insertString(root.getElement(2).getStartOffset() + 1,
0797: "\n123", null);
0798: view.layout(shape.width, shape.height);
0799: ElementChange change = insertEvent.getChange(view.getElement());
0800: assertNotNull(change);
0801: componentRepaint = false;
0802: view.insertUpdate(insertEvent, shape, factory);
0803: assertTrue(componentRepaint);
0804: }
0805:
0806: public void testUpdateLayout01() throws BadLocationException {
0807: doc.addDocumentListener(this );
0808: doc.insertString(root.getElement(2).getStartOffset() + 1,
0809: "123", null);
0810: view.layout(shape.width, shape.height);
0811: ElementChange change = insertEvent.getChange(view.getElement());
0812: assertNull(change);
0813: componentRepaint = false;
0814: view.updateLayout(change, insertEvent, shape);
0815: assertFalse(componentRepaint);
0816: }
0817:
0818: public void testUpdateLayout02() throws BadLocationException {
0819: doc.addDocumentListener(this );
0820: doc.insertString(root.getElement(2).getStartOffset() + 1,
0821: "\n123", null);
0822: view.layout(shape.width, shape.height);
0823: ElementChange change = insertEvent.getChange(view.getElement());
0824: assertNotNull(change);
0825: componentRepaint = false;
0826: view.updateLayout(change, insertEvent, shape);
0827: assertTrue(componentRepaint);
0828: }
0829:
0830: /**
0831: * Tests <code>getOffset</code> with Y axis.
0832: */
0833: public void testGetOffset01() {
0834: view.layout(shape.width, shape.height);
0835: assertEquals(getChildY(0) - shape.y, view.getOffset(Y_AXIS, 0));
0836: assertEquals(getChildY(1) - shape.y, view.getOffset(Y_AXIS, 1));
0837: assertEquals(getChildY(2) - shape.y, view.getOffset(Y_AXIS, 2));
0838: assertEquals(getChildY(3) - shape.y, view.getOffset(Y_AXIS, 3));
0839: }
0840:
0841: /**
0842: * Tests <code>getOffset</code> with X axis.
0843: */
0844: public void testGetOffset02() {
0845: view.layout(shape.width, shape.height);
0846: assertEquals(getChildX(0) - shape.x, view.getOffset(X_AXIS, 0));
0847: assertEquals(getChildX(1) - shape.x, view.getOffset(X_AXIS, 1));
0848: assertEquals(getChildX(2) - shape.x, view.getOffset(X_AXIS, 2));
0849: assertEquals(getChildX(3) - shape.x, view.getOffset(X_AXIS, 3));
0850: }
0851:
0852: /**
0853: * Tests <code>getSpan</code> with Y axis.
0854: */
0855: public void testGetSpan01() {
0856: view.layout(shape.width, shape.height);
0857: assertEquals(getHeight(0), view.getSpan(Y_AXIS, 0));
0858: assertEquals(getHeight(1), view.getSpan(Y_AXIS, 1));
0859: assertEquals(getHeight(2), view.getSpan(Y_AXIS, 2));
0860: assertEquals(getHeight(3), view.getSpan(Y_AXIS, 3));
0861: }
0862:
0863: /**
0864: * Tests <code>getSpan</code> with X axis.
0865: */
0866: public void testGetSpan02() {
0867: view.layout(shape.width, shape.height);
0868: assertEquals(getWidth(0), view.getSpan(X_AXIS, 0));
0869: assertEquals(getWidth(1), view.getSpan(X_AXIS, 1));
0870: assertEquals(getWidth(2), view.getSpan(X_AXIS, 2));
0871: assertEquals(getWidth(3), view.getSpan(X_AXIS, 3));
0872: }
0873:
0874: /**
0875: * Tests <code>layoutMajorAxis</code> with default settings:
0876: * not resizable children, enough height space.
0877: */
0878: public void testLayoutMajorAxis01() {
0879: int[] offsets = new int[view.getViewCount()];
0880: int[] spans = new int[view.getViewCount()];
0881: view.layoutMajorAxis(shape.height, Y_AXIS, offsets, spans);
0882: // This method doesn't mark layout as valid
0883: assertFalse(view.isLayoutValid(Y_AXIS));
0884: for (int i = 0; i < view.getViewCount(); i++) {
0885: assertEquals("Offsets are different @ " + i, getChildY(i)
0886: - shape.y, offsets[i]);
0887: assertEquals("Spans are different @ " + i, getHeight(i),
0888: spans[i]);
0889: }
0890: }
0891:
0892: /**
0893: * Tests <code>layoutMajorAxis</code> with default settings:
0894: * not resizable children, height space > maximum.
0895: */
0896: public void testLayoutMajorAxis02() {
0897: int[] offsets = new int[view.getViewCount()];
0898: int[] spans = new int[view.getViewCount()];
0899: view.layoutMajorAxis(major.preferred - 150, Y_AXIS, offsets,
0900: spans);
0901: // This method doesn't mark layout as valid
0902: assertFalse(view.isLayoutValid(Y_AXIS));
0903: for (int i = 0; i < view.getViewCount(); i++) {
0904: assertEquals("Offsets are different @ " + i, getChildY(i)
0905: - shape.y, offsets[i]);
0906: assertEquals("Spans are different @ " + i, getHeight(i),
0907: spans[i]);
0908: }
0909: }
0910:
0911: /**
0912: * Tests <code>layoutMajorAxis</code> with "flexible" settings:
0913: * resizable children, enough height space.
0914: */
0915: public void testLayoutMajorAxis03() {
0916: makeFlexible();
0917: int[] offsets = new int[view.getViewCount()];
0918: int[] spans = new int[view.getViewCount()];
0919: assertTrue(shape.height > major.maximum);
0920: view.layoutMajorAxis(shape.height, Y_AXIS, offsets, spans);
0921: // This method doesn't mark layout as valid
0922: assertFalse(view.isLayoutValid(Y_AXIS));
0923: int childOffset = 0;
0924: int childSpan;
0925: for (int i = 0; i < view.getViewCount(); i++) {
0926: assertEquals("Offsets are different @ " + i, childOffset,
0927: offsets[i]);
0928: childSpan = (int) view.getView(i).getMaximumSpan(Y_AXIS);
0929: assertEquals("Spans are different @ " + i, childSpan,
0930: spans[i]);
0931: childOffset += childSpan;
0932: }
0933: }
0934:
0935: /**
0936: * Tests <code>layoutMajorAxis</code> with "flexible" settings:
0937: * resizable children, height space > minimum but < preferred.
0938: */
0939: public void testLayoutMajorAxis04() {
0940: makeFlexible();
0941: int[] offsets = new int[view.getViewCount()];
0942: int[] spans = new int[view.getViewCount()];
0943: final int axis = Y_AXIS;
0944: shape.height = major.minimum - 50;
0945: assertTrue(shape.height < major.minimum);
0946: view.layoutMajorAxis(shape.height, axis, offsets, spans);
0947: // This method doesn't mark layout as valid
0948: assertFalse(view.isLayoutValid(axis));
0949: SizeRequirements[] childReq = new SizeRequirements[view
0950: .getViewCount()];
0951: int[] childOffsets = new int[view.getViewCount()];
0952: int[] childSpans = new int[view.getViewCount()];
0953: fillRequirements(childReq, axis);
0954: SizeRequirements.calculateTiledPositions(shape.height, major,
0955: childReq, childOffsets, childSpans);
0956: for (int i = 0; i < view.getViewCount(); i++) {
0957: assertEquals("Offsets are different @ " + i,
0958: childOffsets[i], offsets[i]);
0959: assertEquals("Spans are different @ " + i, childSpans[i],
0960: spans[i]);
0961: }
0962: }
0963:
0964: /**
0965: * Tests layout of minor axis with <em>normal (non-resizable)</em> children.
0966: */
0967: public void testLayoutMinorAxis01() {
0968: int[] offsets = new int[view.getViewCount()];
0969: int[] spans = new int[view.getViewCount()];
0970: view.layoutMinorAxis(shape.width, X_AXIS, offsets, spans);
0971: // This method doesn't mark layout as valid
0972: assertFalse(view.isLayoutValid(X_AXIS));
0973: for (int i = 0; i < view.getViewCount(); i++) {
0974: assertEquals("Offsets are different @ " + i, getChildX(i)
0975: - shape.x, offsets[i]);
0976: assertEquals("Spans are different @ " + i, getWidth(i),
0977: spans[i]);
0978: }
0979: }
0980:
0981: /**
0982: * Tests layout of minor axis with <em>resizable</em> children.
0983: */
0984: public void testLayoutMinorAxis02() {
0985: int[] offsets = new int[view.getViewCount()];
0986: int[] spans = new int[view.getViewCount()];
0987: makeFlexible();
0988: SizeRequirements[] childReq = new SizeRequirements[view
0989: .getViewCount()];
0990: fillRequirements(childReq, X_AXIS);
0991: view.layoutMinorAxis(shape.width, X_AXIS, offsets, spans);
0992: for (int i = 0; i < view.getViewCount(); i++) {
0993: int span = getChildSpan(shape.width, childReq[i]);
0994: assertEquals("Spans are different @ " + i, span, spans[i]);
0995: assertEquals("Offsets are different @ " + i,
0996: getChildOffset(shape.width, span,
0997: childReq[i].alignment), offsets[i]);
0998: }
0999: }
1000:
1001: /**
1002: * Tests layout of minor axis with <em>resizable</em> children in the case
1003: * where <code>targetSpan</code> <em>is less than the minimum span</em>
1004: * of at least one of the children.
1005: */
1006: public void testLayoutMinorAxis03() {
1007: int[] offsets = new int[view.getViewCount()];
1008: int[] spans = new int[view.getViewCount()];
1009: makeFlexible();
1010: SizeRequirements[] childReq = new SizeRequirements[view
1011: .getViewCount()];
1012: fillRequirements(childReq, X_AXIS);
1013: shape.width = 16;
1014: view.layoutMinorAxis(shape.width, X_AXIS, offsets, spans);
1015: boolean widthLessMinimum = false;
1016: for (int i = 0; i < view.getViewCount(); i++) {
1017: widthLessMinimum |= childReq[i].minimum > shape.width;
1018: int span = getChildSpan(shape.width, childReq[i]);
1019: assertEquals("Spans are different @ " + i, span, spans[i]);
1020: assertEquals("Offsets are different @ " + i,
1021: getChildOffset(shape.width, span,
1022: childReq[i].alignment), offsets[i]);
1023: }
1024: assertTrue("Minimum span of at least one child view must "
1025: + "be greater than targetSpan", widthLessMinimum);
1026: }
1027:
1028: /**
1029: * Test <code>getMaximumSpan</code> with ordinary children.
1030: */
1031: public void testGetMaximumSpan01() {
1032: assertEquals(major.maximum, (int) view.getMaximumSpan(Y_AXIS));
1033: assertEquals(minor.maximum, (int) view.getMaximumSpan(X_AXIS));
1034: }
1035:
1036: /**
1037: * Test <code>getMaximumSpan</code> with flexible children.
1038: */
1039: public void testGetMaximumSpan02() {
1040: makeFlexible();
1041: assertEquals(major.maximum, (int) view.getMaximumSpan(Y_AXIS));
1042: assertEquals(minor.maximum, (int) view.getMaximumSpan(X_AXIS));
1043: }
1044:
1045: /**
1046: * Test <code>getMaximumSpan</code> throws required exception.
1047: */
1048: public void testGetMaximumSpan03() {
1049: try {
1050: view.getMaximumSpan(INVALID_AXIS);
1051: fail("IllegalArgumentException is expected");
1052: } catch (IllegalArgumentException e) {
1053: }
1054: }
1055:
1056: /**
1057: * Test <code>getMinimumSpan</code> with ordinary children.
1058: */
1059: public void testGetMinimumSpan01() {
1060: assertEquals(major.minimum, (int) view.getMinimumSpan(Y_AXIS));
1061: assertEquals(minor.minimum, (int) view.getMinimumSpan(X_AXIS));
1062: }
1063:
1064: /**
1065: * Test <code>getMinimumSpan</code> with flexible children.
1066: */
1067: public void testGetMinimumSpan02() {
1068: makeFlexible();
1069: assertEquals(major.minimum, (int) view.getMinimumSpan(Y_AXIS));
1070: assertEquals(minor.minimum, (int) view.getMinimumSpan(X_AXIS));
1071: }
1072:
1073: /**
1074: * Test <code>getMinimumSpan</code> throws required exception.
1075: */
1076: public void testGetMinimumSpan03() {
1077: try {
1078: view.getMinimumSpan(INVALID_AXIS);
1079: fail("IllegalArgumentException is expected");
1080: } catch (IllegalArgumentException e) {
1081: }
1082: }
1083:
1084: /**
1085: * Test <code>getPreferredSpan</code> with ordinary children.
1086: */
1087: public void testGetPreferredSpan01() {
1088: assertEquals(major.preferred, (int) view
1089: .getPreferredSpan(Y_AXIS));
1090: assertEquals(minor.preferred, (int) view
1091: .getPreferredSpan(X_AXIS));
1092: }
1093:
1094: /**
1095: * Test <code>getPreferredSpan</code> with flexible children.
1096: */
1097: public void testGetPreferredSpan02() {
1098: makeFlexible();
1099: assertEquals(major.preferred, (int) view
1100: .getPreferredSpan(Y_AXIS));
1101: assertEquals(minor.preferred, (int) view
1102: .getPreferredSpan(X_AXIS));
1103: }
1104:
1105: /**
1106: * Test <code>getPreferredSpan</code> throws required exception.
1107: */
1108: public void testGetPreferredSpan03() {
1109: try {
1110: view.getPreferredSpan(INVALID_AXIS);
1111: fail("IllegalArgumentException is expected");
1112: } catch (IllegalArgumentException e) {
1113: }
1114: }
1115:
1116: /**
1117: * Test <code>getResizeWeight</code> with ordinary children.
1118: */
1119: public void testGetResizeWeight01() {
1120: assertEquals(0, view.getResizeWeight(Y_AXIS)); // major
1121: assertEquals(1, view.getResizeWeight(X_AXIS)); // minor
1122: }
1123:
1124: /**
1125: * Test <code>getResizeWeight</code> with flexible children.
1126: */
1127: public void testGetResizeWeight02() {
1128: makeFlexible();
1129: assertEquals(1, view.getResizeWeight(Y_AXIS));
1130: assertEquals(1, view.getResizeWeight(X_AXIS));
1131: }
1132:
1133: /**
1134: * Test <code>getResizeWeight</code> throws required exception.
1135: */
1136: public void testGetResizeWeight03() {
1137: try {
1138: view.getResizeWeight(INVALID_AXIS);
1139: fail("IllegalArgumentException is expected");
1140: } catch (IllegalArgumentException e) {
1141: }
1142: }
1143:
1144: /**
1145: * Test <code>getResizeWeight</code> with both ordinary and
1146: * flexible children while major axis is X.
1147: */
1148: public void testGetResizeWeight04() {
1149: view = new BoxView(root, X_AXIS);
1150: view.loadChildren(factory);
1151: assertEquals(1, view.getResizeWeight(Y_AXIS)); // minor
1152: assertEquals(0, view.getResizeWeight(X_AXIS)); // major
1153: makeFlexible();
1154: assertEquals(1, view.getResizeWeight(Y_AXIS));
1155: assertEquals(1, view.getResizeWeight(X_AXIS));
1156: assertTrue(1 < view.getMaximumSpan(X_AXIS)
1157: - view.getMinimumSpan(X_AXIS));
1158: assertTrue(1 < view.getMaximumSpan(Y_AXIS)
1159: - view.getMinimumSpan(Y_AXIS));
1160: }
1161:
1162: /*
1163: * Class under test for Shape modelToView(int, Shape, Bias)
1164: */
1165: public void testModelToView() throws BadLocationException {
1166: // Allocation is invalid
1167: assertFalse(view.isAllocationValid());
1168: // The call makes layout, so...
1169: assertEquals(new Rectangle(getChildX(0), getChildY(0), 1,
1170: getHeight(0)), view.modelToView(0, shape, Bias.Forward));
1171: // Allocation is valid
1172: assertTrue(view.isAllocationValid());
1173: assertEquals(shape.width, view.getWidth());
1174: assertEquals(shape.height, view.getHeight());
1175: View child = view.getView(0);
1176: // This will call on the first child
1177: assertEquals(new Rectangle(getChildX(0) + POS
1178: * child.getEndOffset(), getChildY(0), 1, getHeight(0)),
1179: view.modelToView(child.getEndOffset(), shape,
1180: Bias.Backward));
1181: // These will call on the second child
1182: assertEquals(new Rectangle(getChildX(1), getChildY(1), 1,
1183: getHeight(1)), view.modelToView(child.getEndOffset(),
1184: shape, Bias.Forward));
1185: assertEquals(new Rectangle(getChildX(1) + POS, getChildY(1), 1,
1186: getHeight(1)), view.modelToView(
1187: child.getEndOffset() + 1, shape, Bias.Forward));
1188: // The only illegal Bias possible is null
1189: try {
1190: view.modelToView(0, shape, null);
1191: // isn't thrown
1192: //fail("IllegalArgumentException must be thrown");
1193: } catch (IllegalArgumentException e) {
1194: }
1195: }
1196:
1197: /*
1198: * Tests method int viewToModel(float, float, Shape, Bias[])
1199: */
1200: public void testViewToModel() {
1201: final Bias[] bias = new Bias[1];
1202: // Allocation is invalid
1203: assertFalse(view.isAllocationValid());
1204: // The call makes layout, so...
1205: assertEquals(0, view.viewToModel(0, 0, shape, bias));
1206: // Allocation is valid
1207: assertTrue(view.isAllocationValid());
1208: assertEquals(shape.width, view.getWidth());
1209: assertEquals(shape.height, view.getHeight());
1210: View child = view.getView(0);
1211: assertEquals(child.getEndOffset(), view.viewToModel(
1212: getChildX(0) + POS * child.getEndOffset(),
1213: getChildY(0), shape, bias));
1214: child = view.getView(1);
1215: assertEquals(child.getStartOffset() + 1, view.viewToModel(
1216: getChildX(1) + POS, getChildY(1), shape, bias));
1217: }
1218:
1219: public void testPaint() {
1220: final class ChildPainted {
1221: public int index;
1222:
1223: public Rectangle alloc;
1224:
1225: public ChildPainted(final int index, final Rectangle alloc) {
1226: this .index = index;
1227: this .alloc = alloc;
1228: }
1229: }
1230: final ArrayList<ChildPainted> childrenPainted = new ArrayList<ChildPainted>();
1231: view = new BoxView(root, Y_AXIS) {
1232: @Override
1233: protected void paintChild(final Graphics g,
1234: final Rectangle alloc, final int index) {
1235: childrenPainted.add(new ChildPainted(index,
1236: (Rectangle) alloc.clone()));
1237: }
1238: };
1239: factory.resetID();
1240: view.loadChildren(factory);
1241: Graphics g = (new BufferedImage(shape.x + shape.width + 100,
1242: shape.y + shape.height + 50, BufferedImage.TYPE_INT_RGB))
1243: .getGraphics();
1244: Rectangle clip = new Rectangle(getChildX(0) + 10,
1245: getChildY(0) + 11, shape.width + 37, getHeight(0));
1246: g.setClip(clip);
1247: view.layout(shape.width, shape.height);
1248: view.paint(g, shape);
1249: for (int i = 0; i < view.getViewCount(); i++) {
1250: Rectangle childBounds = (Rectangle) view
1251: .getChildAllocation(i, shape);
1252: if (i < 2) {
1253: assertTrue("Child bounds IS NOT withing clip bounds @"
1254: + i, clip.intersects(childBounds));
1255: } else {
1256: assertFalse(
1257: "Child bounds IS withing clip bounds @" + i,
1258: clip.intersects(childBounds));
1259: }
1260: }
1261: assertEquals(2, childrenPainted.size());
1262: ChildPainted childPainted;
1263: childPainted = childrenPainted.get(0);
1264: assertEquals(0, childPainted.index);
1265: assertEquals(view.getChildAllocation(0, shape),
1266: childPainted.alloc);
1267: childPainted = childrenPainted.get(1);
1268: assertEquals(1, childPainted.index);
1269: assertEquals(view.getChildAllocation(1, shape),
1270: childPainted.alloc);
1271: }
1272:
1273: public void changedUpdate(final DocumentEvent event) {
1274: }
1275:
1276: public void insertUpdate(final DocumentEvent event) {
1277: insertEvent = event;
1278: }
1279:
1280: public void removeUpdate(final DocumentEvent event) {
1281: }
1282:
1283: private static float getAlign(final int axis, final int id) {
1284: return ViewTestHelpers.getAlign(axis, id);
1285: }
1286:
1287: private static int getHeight(final int id) {
1288: return ViewTestHelpers.getHeight(id);
1289: }
1290:
1291: private static int getWidth(final int id) {
1292: return ViewTestHelpers.getWidth(id);
1293: }
1294:
1295: /**
1296: * Returns <code>x</code> coordinate for a child at index <code>id</code>.
1297: * It respects child alignment request.
1298: *
1299: * @param id child number (or index)
1300: * @return x coordinate of the child
1301: */
1302: private int getChildX(final int id) {
1303: return (int) (shape.x + getAlign(X_AXIS, id)
1304: * (shape.width - getWidth(id)));
1305: }
1306:
1307: /**
1308: * Returns <code>y</code> coordinate for a child at index <code>id</code>.
1309: *
1310: * @param id child number (or index)
1311: * @return y coordinate of the child
1312: */
1313: private int getChildY(final int id) {
1314: int y = shape.y;
1315: for (int i = 0; i < id; i++) {
1316: y += getHeight(i);
1317: }
1318: return y;
1319: }
1320:
1321: /**
1322: * Returns the span of a child for minor axis layout.
1323: *
1324: * @param targetSpan target span where the child view should be placed
1325: * @param sr size requirements of the child view
1326: * @return the span of the child view
1327: */
1328: private int getChildSpan(final int targetSpan,
1329: final SizeRequirements sr) {
1330: int result;
1331: if (targetSpan >= sr.maximum) {
1332: result = sr.maximum;
1333: } else if (targetSpan >= sr.minimum) {
1334: result = targetSpan;
1335: } else {
1336: result = sr.minimum;
1337: }
1338: return result;
1339: }
1340:
1341: /**
1342: * Returns the offset of a child for minor axis layout.
1343: *
1344: * @param targetSpan target span where the child view should be placed
1345: * @param childSpan the span of the child view
1346: * @return the offset of the child view inside its container
1347: */
1348: private int getChildOffset(final int targetSpan,
1349: final int childSpan, final float alignment) {
1350: int result = (int) ((targetSpan - childSpan) * alignment);
1351: return result >= 0 ? result : 0;
1352: }
1353:
1354: /**
1355: * Reinitializes the view with flexible children.
1356: */
1357: private void makeFlexible() {
1358: factory.makeFlexible();
1359: view.removeAll();
1360: view.loadChildren(factory);
1361: // Recalculate
1362: major = view.calculateMajorAxisRequirements(Y_AXIS, null);
1363: minor = view.calculateMinorAxisRequirements(X_AXIS, null);
1364: }
1365:
1366: /**
1367: * Returns the maximum span of a child view to the left or top of
1368: * the aligning point (for baseline layout).
1369: *
1370: * @param which specifies which span is used:
1371: * <code>MINIMUM</code>, <code>PREFERRED</code>,
1372: * <code>MAXIMUM</code>
1373: * @param axis specifies the axis of the span: either <code>X_AXIS</code>
1374: * or <code>Y_AXIS</code>
1375: * @return the maximum span to the left or top of the aligning point
1376: */
1377: private int getLeft(final int which, final int axis) {
1378: int left = 0;
1379: for (int i = 0; i < view.getViewCount(); i++) {
1380: View child = view.getView(i);
1381: float span = 0;
1382: switch (which) {
1383: case MINIMUM:
1384: span = child.getMinimumSpan(axis);
1385: break;
1386: case PREFERRED:
1387: span = child.getPreferredSpan(axis);
1388: break;
1389: case MAXIMUM:
1390: span = child.getMaximumSpan(axis);
1391: break;
1392: }
1393: float cLeft = child.getAlignment(axis) * span;
1394: if (cLeft > left) {
1395: left = (int) cLeft;
1396: }
1397: }
1398: return left;
1399: }
1400:
1401: /**
1402: * Returns the maximum span of a child view to the right or bottom of
1403: * the aligning point (for baseline layout).
1404: *
1405: * @param which specifies which span is used:
1406: * <code>MINIMUM</code>, <code>PREFERRED</code>,
1407: * <code>MAXIMUM</code>
1408: * @param axis specifies the axis of the span: either <code>X_AXIS</code>
1409: * or <code>Y_AXIS</code>
1410: * @return the maximum span to the right or bottom of the aligning point
1411: */
1412: private int getRight(final int which, final int axis) {
1413: int right = 0;
1414: for (int i = 0; i < view.getViewCount(); i++) {
1415: View child = view.getView(i);
1416: float span = 0;
1417: switch (which) {
1418: case MINIMUM:
1419: span = child.getMinimumSpan(axis);
1420: break;
1421: case PREFERRED:
1422: span = child.getPreferredSpan(axis);
1423: break;
1424: case MAXIMUM:
1425: span = child.getMaximumSpan(axis);
1426: break;
1427: }
1428: float cLeft = child.getAlignment(axis) * span;
1429: float cRight = span - cLeft;
1430: if (cRight > right) {
1431: right = (int) cRight;
1432: }
1433: }
1434: return right;
1435: }
1436:
1437: private void fillRequirements(final SizeRequirements[] childReq,
1438: final int axis) {
1439: for (int i = 0; i < view.getViewCount(); i++) {
1440: View child = view.getView(i);
1441: childReq[i] = new SizeRequirements((int) child
1442: .getMinimumSpan(axis), (int) child
1443: .getPreferredSpan(axis), (int) child
1444: .getMaximumSpan(axis), child.getAlignment(axis));
1445: }
1446: }
1447: }
|