private void updateView(final DocumentEvent event, final Shape shape) { final AbstractDocument doc = (AbstractDocument)getDocument(); final ElementChange change = event.getChange(doc.getBidiRootElement()); if (change != null) { updateChildren(); preferenceChanged(this, true, false); if (shape != null) { Rectangle rc = shape.getBounds(); getComponent().repaint(rc.x, rc.y, rc.width, rc.height); } } else { forwardUpdate(null, event, shape, null); } }
protected void updateDamage(final DocumentEvent event, final Shape shape, final ViewFactory factory) { if (shape == null) { return; } if (metrics == null) { updateMetrics(); preferenceChanged(null, true, true); return; } final ElementChange change = event.getChange(getElement()); if (event.getType() == EventType.INSERT) { updateDamageOnInsert(event, change, shape); } else { updateDamageOnRemove(event, change, shape); } }
private void updateDamageOnInsert(final DocumentEvent event, final ElementChange change, final Shape shape) { boolean linesAdded = change != null; int start = linesAdded ? change.getIndex() : getElement().getElementIndex(event.getOffset()); int length = linesAdded ? change.getChildrenAdded().length - 1 : 0; int width = widestLineWidth; if (widestLine.getEndOffset() < event.getOffset() || widestLine.getStartOffset() > event.getOffset() + event.getLength()) { // The previous longest line was not affected updateWidestLine(start, start + length); } else { updateWidestLine(); } preferenceChanged(null, widestLineWidth != width, linesAdded); damageLineRange(start, linesAdded ? getElement().getElementCount() - 1 : start, shape, getComponent()); }
private void updateDamageOnRemove(final DocumentEvent event, final ElementChange change, final Shape shape) { int width = widestLineWidth; if (change != null) { updateWidestLine(); preferenceChanged(null, widestLineWidth != width, true); getComponent().repaint(); } else { int lineNo = getElement().getElementIndex(event.getOffset()); Element line = getElement().getElement(lineNo); if (widestLine == line) { updateWidestLine(); preferenceChanged(null, widestLineWidth != width, false); } damageLineRange(lineNo, lineNo, shape, getComponent()); } }
private void updateView(final DocumentEvent event, final Shape shape, final ViewFactory factory) { if (getViewCount() == 0) { return; } ElementChange change = event.getChange(getElement()); if (change != null && !updateChildren(change, event, factory)) { // updateChildren returned false, then forwardUpdate and // updateLayout must be passed null as change despite // change is not null change = null; } forwardUpdate(change, event, shape, factory); updateLayout(change, event, shape); }
/** * Asserts that the removed and/or added children have the expected offsets. * * @param change the changes performed to an element. * @param removedOffsets the offsets of children removed in the form * <code>{start1, end1, start2, end2, ...}</code>. * @param addedOffsets the offsets of children added in the same form as * <code>removedOffsets</code>. */ public static void assertChange(final ElementChange change, final int[] removedOffsets, final int[] addedOffsets) { final Element[] removed = change.getChildrenRemoved(); assertEquals("change.removed.length", removedOffsets.length / 2, removed.length); for (int i = 0, j = 0; i < removed.length; i++, j += 2) { assertEquals("change.removed[" + i + "].start", removedOffsets[j], removed[i] .getStartOffset()); assertEquals("change.removed[" + i + "].end", removedOffsets[j + 1], removed[i] .getEndOffset()); } final Element[] added = change.getChildrenAdded(); assertEquals("change.added.length", addedOffsets.length / 2, added.length); for (int i = 0, j = 0; i < added.length; i++, j += 2) { assertEquals("change.added[" + i + "].start", addedOffsets[j], added[i] .getStartOffset()); assertEquals("change.added[" + i + "].end", addedOffsets[j + 1], added[i] .getEndOffset()); } }
/** * Adds text with no attributes. */ public void testInsertString01() throws Exception { doc.insertString(insertOffset, "^^^", null); assertEquals(2, getEdits(insertEvent).size()); List<?> edits = getEdits(insertEvent); assertChange(edits.get(1), paragraph, 1, 3); ElementChange change = (ElementChange) edits.get(1); assertSame(leaf, change.getChildrenRemoved()[0]); final Element[] added = change.getChildrenAdded(); for (int i = 0; i < added.length; i++) { assertSame("@" + i, paragraph.getElement(i + leafIndex), added[i]); } ElementAssert[] expected = { new ElementAssert(null, 0, 5), new ElementAssert(bold, 5, 7), new ElementAssert(null, 7, 10), new ElementAssert(bold, 10, 12), new ElementAssert(italic, 12, 18), new ElementAssert(null, 18, 19) }; assertEquals(expected.length, paragraph.getElementCount()); for (int i = 0; i < expected.length; i++) { expected[i].check(paragraph.getElement(i)); } assertEquals(1, specs.length); assertSpec(specs[0], ElementSpec.ContentType, ElementSpec.OriginateDirection, 0, 3); }
/** * Tests forwardUpdate when major axis is Y_AXIS and * document structure isn't changed. The child says it changed its * preference along both axes. * (See javax.swing.text.ViewTestHelpers.ChildView.insertUpdate()). */ public void testForwardUpdate01() throws BadLocationException { view.getContainer(); componentRepaint = false; doc.addDocumentListener(this); doc.insertString(root.getElement(2).getStartOffset() + 1, "123", null); ElementChange change = insertEvent.getChange(view.getElement()); assertNull(change); view.layout(shape.width, shape.height); assertTrue(view.isLayoutValid(X_AXIS)); assertTrue(view.isLayoutValid(Y_AXIS)); view.forwardUpdate(change, insertEvent, shape, factory); assertFalse(view.isLayoutValid(X_AXIS)); assertFalse(view.isLayoutValid(Y_AXIS)); assertFalse(componentRepaint); Rectangle bounds = view.getInsideAllocation(shape); int childIndex = view.getViewIndex(insertEvent.getOffset(), Bias.Forward); if (isHarmony()) { bounds.y += view.getOffset(view.getAxis(), childIndex); bounds.height -= view.getOffset(view.getAxis(), childIndex); } else { bounds.y = 28; bounds.height = 412; } assertEquals(paintRect, bounds); }
/** * Tests forwardUpdate when major axis is X_AXIS and * document structure isn't changed. The child says it changed its * preference along both axes. * (See javax.swing.text.ViewTestHelpers.ChildView.insertUpdate()). */ public void testForwardUpdate03() throws BadLocationException { view = new BoxViewImpl(root, X_AXIS); view.loadChildren(factory); view.getContainer(); componentRepaint = false; doc.addDocumentListener(this); doc.insertString(root.getElement(2).getStartOffset() + 1, "123", null); ElementChange change = insertEvent.getChange(view.getElement()); assertNull(change); view.layout(shape.width, shape.height); assertTrue(view.isLayoutValid(X_AXIS)); assertTrue(view.isLayoutValid(Y_AXIS)); view.forwardUpdate(change, insertEvent, shape, factory); assertFalse(view.isLayoutValid(X_AXIS)); assertFalse(view.isLayoutValid(Y_AXIS)); assertFalse(componentRepaint); Rectangle bounds = view.getInsideAllocation(shape); int childIndex = view.getViewIndex(insertEvent.getOffset(), Bias.Forward); bounds.x += view.getOffset(view.getAxis(), childIndex); bounds.width -= view.getOffset(view.getAxis(), childIndex); assertEquals(paintRect, bounds); }
private final void trigChangedUpdate(final int sLen) { ((AbstractDocument)model).fireChangedUpdate(new DocumentEvent() { @Override public EventType getType() { return EventType.CHANGE; } @Override public int getOffset() { return 0; } @Override public int getLength() { return sLen; } @Override public Document getDocument() { return model; } @Override public ElementChange getChange(Element elem) { return null; } }); }
@Override protected void updateLayout(ElementChange ec, DocumentEvent e, Shape a) { if ( (a != null)) { // should damage more intelligently preferenceChanged(null, true, true); Container host = getContainer(); if (host != null) { host.repaint(); } } }
public ElementChange getChange(final Element element) { if (changes != null) { return changes.get(element); } for (UndoableEdit edit : edits) { if (edit instanceof ElementChange) { ElementChange change = (ElementChange)edit; if (change.getElement() == element) { return change; } } } return null; }
/** * The event is forwarded to all child views that lie in the range of * the change, i.e. <code>event.getOffset()</code> up to * <code>(event.getOffset() + event.getLength())</code>. * <p> * If <code>event.getOffset()</code> is boundary of children, then * the previous child is included to the update range. * <p> * If <code>change</code> is not <code>null</code>, children that * have just been added by <code>updateChildren</code> are excluded * from the update range. * <p> * <code>change</code> can be <code>null</code> if the element this view * represents has not changed, or if its children represent portions of * elements. * * @param change is always <code>null</code> * if <code>updateChildren</code> returned <code>false</code>, * otherwise it has the value returned by * <code>event.getChange(getElement())</code>. */ protected void forwardUpdate(final DocumentEvent.ElementChange change, final DocumentEvent event, final Shape shape, final ViewFactory factory) { final int offset = event.getOffset(); int start = getViewIndex(offset, Bias.Forward); if (start < 0) { start = 0; } int end = event.getType() == EventType.REMOVE ? start : getViewIndex(offset + event.getLength(), Bias.Forward); if (end < 0) { end = getViewCount() - 1; } if (start > 0 && getView(start - 1).getEndOffset() == offset) { --start; } if (change != null) { end -= change.getChildrenAdded().length; } for (int i = start; i <= end; i++) { forwardUpdateToView(getView(i), event, getChildAllocation(i, shape), factory); } }
protected boolean updateChildren(final DocumentEvent.ElementChange change, final DocumentEvent event, final ViewFactory factory) { final Element[] added = change.getChildrenAdded(); View[] views = null; if (added != null && added.length > 0) { views = new View[added.length]; for (int i = 0; i < added.length; i++) { views[i] = factory.create(added[i]); } } replace(change.getIndex(), change.getChildrenRemoved().length, views); return true; }
protected void updateLayout(final DocumentEvent.ElementChange change, final DocumentEvent event, final Shape shape) { if (change != null) { preferenceChanged(null, true, true); final Component c = getComponent(); if (c != null) { c.repaint(); } } }
@Override protected void forwardUpdate(final ElementChange change, final DocumentEvent event, final Shape shape, final ViewFactory factory) { boolean allocValid = isLayoutValid(majorAxis); super.forwardUpdate(change, event, shape, factory); if (allocValid && !isLayoutValid(majorAxis)) { Component component = getComponent(); if (component != null) { int index = getViewIndexAtPosition(event.getOffset()); Rectangle rect = getInsideAllocation(shape); int viewOffset = getOffset(majorAxis, index); if (majorAxis == Y_AXIS) { rect.y += viewOffset; rect.height -= viewOffset; } else { rect.x += viewOffset; rect.width -= viewOffset; } component.repaint(rect.x, rect.y, rect.width, rect.height); } } }
protected void forwardUpdate(ElementChange change, DocumentEvent event, Shape shape, ViewFactory factory) { boolean xValid = isLayoutValid(X_AXIS); super.forwardUpdate(change, event, shape, factory); if (xValid && !isLayoutValid(X_AXIS)) { Rectangle rc = shape.getBounds(); getContainer().repaint(rc.x, rc.y, ((BoxView)getParent()).getWidth(), rc.height); } }
/** * Dumps the changes stored in <code>change</code>. * * @param change the change to print removed and added children from. */ public static void printChange(ElementChange change) { System.out.print("@ " + change.getIndex() + ": " + change.getElement()); System.out.println(" <<< Removed:"); printElements(change.getChildrenRemoved()); System.out.println(" >>> Added:"); printElements(change.getChildrenAdded()); }
/** * Prints all the changes to elements performed. * * @param edits the list extracted from a <code>DefaultDocumentEvet</code> * object. */ public static void printChanges(List<?> edits) { for (int i = 0; i < edits.size(); i++) { Object edit = edits.get(i); if (edit instanceof ElementChange) { printChange((ElementChange) edit); System.out.println(); } } }
@Override protected void forwardUpdate(ElementChange change, DocumentEvent event, Shape shape, ViewFactory factory) { logger.println(">>> " + getInfo() + ".forwardUpdate"); forwardUpdates.add(this); super.forwardUpdate(change, event, shape, factory); logger.println("<<< " + getInfo() + ".forwardUpdate"); }
public void testForwardUpdate01() throws BadLocationException { doc = new PlainDocument(); doc.insertString(doc.getLength(), "line1", null); doc.insertString(doc.getLength(), "\nline2", null); root = doc.getDefaultRootElement(); view = viewFactory.create(root); assertEquals(2, root.getElementCount()); assertEquals(2, view.getViewCount()); docEvent = new DocumentEvent() { public int getOffset() { return 0; } public int getLength() { return doc.getLength() + 1; } public Document getDocument() { return doc; } public EventType getType() { return EventType.CHANGE; } public ElementChange getChange(Element elem) { return null; } }; view.forwardUpdate(null, docEvent, rect, viewFactory); assertEquals(2, viewsForwardedTo.size()); assertSame(view.getView(0), viewsForwardedTo.get(0)); assertSame(view.getView(1), viewsForwardedTo.get(1)); }