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.Rectangle;
023: import java.awt.Shape;
024: import java.util.ArrayList;
025: import java.util.List;
026: import javax.swing.event.DocumentEvent;
027: import javax.swing.event.DocumentListener;
028: import javax.swing.event.DocumentEvent.ElementChange;
029: import javax.swing.text.CompositeView_ModelViewTest.ChildView;
030: import javax.swing.text.CompositeView_ModelViewTest.WithChildrenView;
031: import javax.swing.text.Position.Bias;
032: import junit.framework.TestCase;
033:
034: public class View_ForwardUpdateRTest extends TestCase {
035: private class ParentView extends WithChildrenView {
036: private final String name;
037:
038: protected ParentView(Element element, String name) {
039: super (element);
040: this .name = name;
041: loadChildren(viewFactory);
042: }
043:
044: public String getName() {
045: return name;
046: }
047:
048: @Override
049: public String toString() {
050: return getName() + " on " + getElement();
051: }
052:
053: public String getModelRange() {
054: return "[" + getStartOffset() + ", " + getEndOffset() + "]";
055: }
056:
057: public String getInfo() {
058: return getName() + getModelRange();
059: }
060:
061: @Override
062: public int getViewIndex(int pos, Bias bias) {
063: int result = super .getViewIndex(pos, bias);
064: logger.println("\t" + getInfo() + ".getViewIndex(" + pos
065: + ", " + bias + ") = " + result);
066: return result;
067: }
068:
069: @Override
070: protected void forwardUpdate(ElementChange change,
071: DocumentEvent event, Shape shape, ViewFactory factory) {
072: logger.println(">>> " + getInfo() + ".forwardUpdate");
073: forwardUpdates.add(this );
074: super .forwardUpdate(change, event, shape, factory);
075: logger.println("<<< " + getInfo() + ".forwardUpdate");
076: }
077:
078: @Override
079: protected void forwardUpdateToView(View view,
080: DocumentEvent event, Shape shape, ViewFactory factory) {
081: viewsForwardedTo.add(view);
082: super .forwardUpdateToView(view, event, shape, factory);
083: }
084: }
085:
086: private final class RootView extends ParentView {
087: public RootView(Element element) {
088: super (element, "root");
089: }
090: }
091:
092: private final class ParagraphView extends ParentView {
093: protected ParagraphView(Element element) {
094: super (element, "paragraph");
095: }
096: }
097:
098: private static final class ContentView extends ChildView {
099: public ContentView(Element element) {
100: super (element);
101: }
102:
103: @Override
104: public String toString() {
105: return "content on " + getElement();
106: }
107: }
108:
109: private static final class Logger {
110: private final boolean active;
111:
112: public Logger(final boolean active) {
113: this .active = active;
114: }
115:
116: public void print(final Object object) {
117: print(object.toString());
118: }
119:
120: public void print(final String message) {
121: if (active) {
122: System.out.print(message);
123: }
124: }
125:
126: public void println() {
127: println("");
128: }
129:
130: public void println(final Object object) {
131: println(object.toString());
132: }
133:
134: public void println(final String message) {
135: print(message + "\n");
136: }
137: }
138:
139: private static final Rectangle rect = new Rectangle(200, 100);
140:
141: private static final Logger logger = new Logger(false);
142:
143: private Document doc;
144:
145: private Element root;
146:
147: private DocumentEvent docEvent;
148:
149: private ViewFactory viewFactory = new ViewFactory() {
150: public View create(Element element) {
151: final String name = element.getName();
152: if (AbstractDocument.SectionElementName.equals(name)) {
153: return new RootView(element);
154: } else if (AbstractDocument.ParagraphElementName
155: .equals(name)) {
156: return new ParagraphView(element);
157: } else if (AbstractDocument.ContentElementName.equals(name)) {
158: return new ContentView(element);
159: }
160: return null;
161: }
162: };
163:
164: private View view;
165:
166: private List<ParentView> forwardUpdates = new ArrayList<ParentView>();
167:
168: private List<View> viewsForwardedTo = new ArrayList<View>();
169:
170: public void testForwardUpdate01() throws BadLocationException {
171: doc = new PlainDocument();
172: doc.insertString(doc.getLength(), "line1", null);
173: doc.insertString(doc.getLength(), "\nline2", null);
174: root = doc.getDefaultRootElement();
175: view = viewFactory.create(root);
176: assertEquals(2, root.getElementCount());
177: assertEquals(2, view.getViewCount());
178: docEvent = new DocumentEvent() {
179: public int getOffset() {
180: return 0;
181: }
182:
183: public int getLength() {
184: return doc.getLength() + 1;
185: }
186:
187: public Document getDocument() {
188: return doc;
189: }
190:
191: public EventType getType() {
192: return EventType.CHANGE;
193: }
194:
195: public ElementChange getChange(Element elem) {
196: return null;
197: }
198: };
199: view.forwardUpdate(null, docEvent, rect, viewFactory);
200: assertEquals(2, viewsForwardedTo.size());
201: assertSame(view.getView(0), viewsForwardedTo.get(0));
202: assertSame(view.getView(1), viewsForwardedTo.get(1));
203: }
204:
205: public void testForwardUpdate02() throws BadLocationException {
206: initStyledDocument();
207: final MutableAttributeSet fontSize = new SimpleAttributeSet();
208: StyleConstants.setFontSize(fontSize, 36);
209: List<View> expected = new ArrayList<View>();
210: logger.print(view);
211: for (int i = 0; i < view.getViewCount(); i++) {
212: View child = view.getView(i);
213: expected.add(child);
214: logger.print("\t" + child);
215: for (int j = 0; j < child.getViewCount(); j++) {
216: expected.add(child.getView(j));
217: logger.print("\t\t" + child.getView(j));
218: }
219: }
220: logger.println();
221: ((StyledDocument) doc).setCharacterAttributes(0, doc
222: .getLength() + 1, fontSize, false);
223: view.forwardUpdate(docEvent.getChange(root), docEvent, rect,
224: viewFactory);
225: logger.println();
226: assertEquals(expected.size(), viewsForwardedTo.size());
227: for (int i = 0; i < viewsForwardedTo.size(); i++) {
228: assertSame("@ " + i, expected.get(i), viewsForwardedTo
229: .get(i));
230: logger.print(viewsForwardedTo.get(i));
231: }
232: }
233:
234: public void testForwardUpdate03() throws BadLocationException {
235: initStyledDocument();
236: final List<View> expected = new ArrayList<View>();
237: // We will use the view for the second paragraph
238: view = view.getView(1);
239: logger.print(view);
240: for (int i = 0; i < view.getViewCount(); i++) {
241: expected.add(view.getView(i));
242: logger.print("\t" + view.getView(i));
243: }
244: logger.println();
245: final MutableAttributeSet fontSize = new SimpleAttributeSet();
246: StyleConstants.setFontSize(fontSize, 36);
247: ((StyledDocument) doc).setCharacterAttributes(0, doc
248: .getLength(), fontSize, false);
249: assertEquals(-1, view.getViewIndex(docEvent.getOffset(),
250: Bias.Forward));
251: assertEquals(view.getViewCount() - 1, view.getViewIndex(
252: docEvent.getOffset() + docEvent.getLength(),
253: Bias.Forward));
254: view.forwardUpdate(docEvent.getChange(view.getElement()),
255: docEvent, rect, viewFactory);
256: logger.println();
257: assertEquals(expected.size(), viewsForwardedTo.size());
258: for (int i = 0; i < viewsForwardedTo.size(); i++) {
259: assertSame("@ " + i, expected.get(i), viewsForwardedTo
260: .get(i));
261: logger.print(viewsForwardedTo.get(i));
262: }
263: }
264:
265: @Override
266: protected void setUp() throws Exception {
267: super .setUp();
268: CompositeView_ModelViewTest.shape = rect;
269: }
270:
271: private void initStyledDocument() throws BadLocationException {
272: doc = new DefaultStyledDocument();
273: final MutableAttributeSet bold = new SimpleAttributeSet();
274: StyleConstants.setBold(bold, true);
275: doc.insertString(doc.getLength(), "plain", null);
276: doc.insertString(doc.getLength(), "bold", bold);
277: doc.insertString(doc.getLength(), "\nline2", null);
278: root = doc.getDefaultRootElement();
279: view = viewFactory.create(root);
280: doc.addDocumentListener(new DocumentListener() {
281: public void insertUpdate(DocumentEvent e) {
282: fail("insertUpdate is not expected");
283: }
284:
285: public void removeUpdate(DocumentEvent e) {
286: fail("removeUpdate is not expected");
287: }
288:
289: public void changedUpdate(DocumentEvent e) {
290: docEvent = e;
291: }
292: });
293: }
294: }
|