|
1 /* |
|
2 * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 package javax.swing.text; |
|
26 |
|
27 import java.util.Vector; |
|
28 import java.awt.*; |
|
29 import javax.swing.event.*; |
|
30 |
|
31 /** |
|
32 * ZoneView is a View implementation that creates zones for which |
|
33 * the child views are not created or stored until they are needed |
|
34 * for display or model/view translations. This enables a substantial |
|
35 * reduction in memory consumption for situations where the model |
|
36 * being represented is very large, by building view objects only for |
|
37 * the region being actively viewed/edited. The size of the children |
|
38 * can be estimated in some way, or calculated asynchronously with |
|
39 * only the result being saved. |
|
40 * <p> |
|
41 * ZoneView extends BoxView to provide a box that implements |
|
42 * zones for its children. The zones are special View implementations |
|
43 * (the children of an instance of this class) that represent only a |
|
44 * portion of the model that an instance of ZoneView is responsible |
|
45 * for. The zones don't create child views until an attempt is made |
|
46 * to display them. A box shaped view is well suited to this because: |
|
47 * <ul> |
|
48 * <li> |
|
49 * Boxes are a heavily used view, and having a box that |
|
50 * provides this behavior gives substantial opportunity |
|
51 * to plug the behavior into a view hierarchy from the |
|
52 * view factory. |
|
53 * <li> |
|
54 * Boxes are tiled in one direction, so it is easy to |
|
55 * divide them into zones in a reliable way. |
|
56 * <li> |
|
57 * Boxes typically have a simple relationship to the model (i.e. they |
|
58 * create child views that directly represent the child elements). |
|
59 * <li> |
|
60 * Boxes are easier to estimate the size of than some other shapes. |
|
61 * </ul> |
|
62 * <p> |
|
63 * The default behavior is controled by two properties, maxZoneSize |
|
64 * and maxZonesLoaded. Setting maxZoneSize to Integer.MAX_VALUE would |
|
65 * have the effect of causing only one zone to be created. This would |
|
66 * effectively turn the view into an implementation of the decorator |
|
67 * pattern. Setting maxZonesLoaded to a value of Integer.MAX_VALUE would |
|
68 * cause zones to never be unloaded. For simplicity, zones are created on |
|
69 * boundaries represented by the child elements of the element the view is |
|
70 * responsible for. The zones can be any View implementation, but the |
|
71 * default implementation is based upon AsyncBoxView which supports fairly |
|
72 * large zones efficiently. |
|
73 * |
|
74 * @author Timothy Prinzing |
|
75 * @see View |
|
76 * @since 1.3 |
|
77 */ |
|
78 public class ZoneView extends BoxView { |
|
79 |
|
80 int maxZoneSize = 8 * 1024; |
|
81 int maxZonesLoaded = 3; |
|
82 Vector loadedZones; |
|
83 |
|
84 /** |
|
85 * Constructs a ZoneView. |
|
86 * |
|
87 * @param elem the element this view is responsible for |
|
88 * @param axis either View.X_AXIS or View.Y_AXIS |
|
89 */ |
|
90 public ZoneView(Element elem, int axis) { |
|
91 super(elem, axis); |
|
92 loadedZones = new Vector(); |
|
93 } |
|
94 |
|
95 /** |
|
96 * Get the current maximum zone size. |
|
97 */ |
|
98 public int getMaximumZoneSize() { |
|
99 return maxZoneSize; |
|
100 } |
|
101 |
|
102 /** |
|
103 * Set the desired maximum zone size. A |
|
104 * zone may get larger than this size if |
|
105 * a single child view is larger than this |
|
106 * size since zones are formed on child view |
|
107 * boundaries. |
|
108 * |
|
109 * @param size the number of characters the zone |
|
110 * may represent before attempting to break |
|
111 * the zone into a smaller size. |
|
112 */ |
|
113 public void setMaximumZoneSize(int size) { |
|
114 maxZoneSize = size; |
|
115 } |
|
116 |
|
117 /** |
|
118 * Get the current setting of the number of zones |
|
119 * allowed to be loaded at the same time. |
|
120 */ |
|
121 public int getMaxZonesLoaded() { |
|
122 return maxZonesLoaded; |
|
123 } |
|
124 |
|
125 /** |
|
126 * Sets the current setting of the number of zones |
|
127 * allowed to be loaded at the same time. This will throw an |
|
128 * <code>IllegalArgumentException</code> if <code>mzl</code> is less |
|
129 * than 1. |
|
130 * |
|
131 * @param mzl the desired maximum number of zones |
|
132 * to be actively loaded, must be greater than 0 |
|
133 * @exception IllegalArgumentException if <code>mzl</code> is < 1 |
|
134 */ |
|
135 public void setMaxZonesLoaded(int mzl) { |
|
136 if (mzl < 1) { |
|
137 throw new IllegalArgumentException("ZoneView.setMaxZonesLoaded must be greater than 0."); |
|
138 } |
|
139 maxZonesLoaded = mzl; |
|
140 unloadOldZones(); |
|
141 } |
|
142 |
|
143 /** |
|
144 * Called by a zone when it gets loaded. This happens when |
|
145 * an attempt is made to display or perform a model/view |
|
146 * translation on a zone that was in an unloaded state. |
|
147 * This is imlemented to check if the maximum number of |
|
148 * zones was reached and to unload the oldest zone if so. |
|
149 * |
|
150 * @param zone the child view that was just loaded. |
|
151 */ |
|
152 protected void zoneWasLoaded(View zone) { |
|
153 //System.out.println("loading: " + zone.getStartOffset() + "," + zone.getEndOffset()); |
|
154 loadedZones.addElement(zone); |
|
155 unloadOldZones(); |
|
156 } |
|
157 |
|
158 void unloadOldZones() { |
|
159 while (loadedZones.size() > getMaxZonesLoaded()) { |
|
160 View zone = (View) loadedZones.elementAt(0); |
|
161 loadedZones.removeElementAt(0); |
|
162 unloadZone(zone); |
|
163 } |
|
164 } |
|
165 |
|
166 /** |
|
167 * Unload a zone (Convert the zone to its memory saving state). |
|
168 * The zones are expected to represent a subset of the |
|
169 * child elements of the element this view is responsible for. |
|
170 * Therefore, the default implementation is to simple remove |
|
171 * all the children. |
|
172 * |
|
173 * @param zone the child view desired to be set to an |
|
174 * unloaded state. |
|
175 */ |
|
176 protected void unloadZone(View zone) { |
|
177 //System.out.println("unloading: " + zone.getStartOffset() + "," + zone.getEndOffset()); |
|
178 zone.removeAll(); |
|
179 } |
|
180 |
|
181 /** |
|
182 * Determine if a zone is in the loaded state. |
|
183 * The zones are expected to represent a subset of the |
|
184 * child elements of the element this view is responsible for. |
|
185 * Therefore, the default implementation is to return |
|
186 * true if the view has children. |
|
187 */ |
|
188 protected boolean isZoneLoaded(View zone) { |
|
189 return (zone.getViewCount() > 0); |
|
190 } |
|
191 |
|
192 /** |
|
193 * Create a view to represent a zone for the given |
|
194 * range within the model (which should be within |
|
195 * the range of this objects responsibility). This |
|
196 * is called by the zone management logic to create |
|
197 * new zones. Subclasses can provide a different |
|
198 * implementation for a zone by changing this method. |
|
199 * |
|
200 * @param p0 the start of the desired zone. This should |
|
201 * be >= getStartOffset() and < getEndOffset(). This |
|
202 * value should also be < p1. |
|
203 * @param p1 the end of the desired zone. This should |
|
204 * be > getStartOffset() and <= getEndOffset(). This |
|
205 * value should also be > p0. |
|
206 */ |
|
207 protected View createZone(int p0, int p1) { |
|
208 Document doc = getDocument(); |
|
209 View zone = null; |
|
210 try { |
|
211 zone = new Zone(getElement(), |
|
212 doc.createPosition(p0), |
|
213 doc.createPosition(p1)); |
|
214 } catch (BadLocationException ble) { |
|
215 // this should puke in some way. |
|
216 throw new StateInvariantError(ble.getMessage()); |
|
217 } |
|
218 return zone; |
|
219 } |
|
220 |
|
221 /** |
|
222 * Loads all of the children to initialize the view. |
|
223 * This is called by the <code>setParent</code> method. |
|
224 * This is reimplemented to not load any children directly |
|
225 * (as they are created by the zones). This method creates |
|
226 * the initial set of zones. Zones don't actually get |
|
227 * populated however until an attempt is made to display |
|
228 * them or to do model/view coordinate translation. |
|
229 * |
|
230 * @param f the view factory |
|
231 */ |
|
232 protected void loadChildren(ViewFactory f) { |
|
233 // build the first zone. |
|
234 Document doc = getDocument(); |
|
235 int offs0 = getStartOffset(); |
|
236 int offs1 = getEndOffset(); |
|
237 append(createZone(offs0, offs1)); |
|
238 handleInsert(offs0, offs1 - offs0); |
|
239 } |
|
240 |
|
241 /** |
|
242 * Returns the child view index representing the given position in |
|
243 * the model. |
|
244 * |
|
245 * @param pos the position >= 0 |
|
246 * @return index of the view representing the given position, or |
|
247 * -1 if no view represents that position |
|
248 */ |
|
249 protected int getViewIndexAtPosition(int pos) { |
|
250 // PENDING(prinz) this could be done as a binary |
|
251 // search, and probably should be. |
|
252 int n = getViewCount(); |
|
253 if (pos == getEndOffset()) { |
|
254 return n - 1; |
|
255 } |
|
256 for(int i = 0; i < n; i++) { |
|
257 View v = getView(i); |
|
258 if(pos >= v.getStartOffset() && |
|
259 pos < v.getEndOffset()) { |
|
260 return i; |
|
261 } |
|
262 } |
|
263 return -1; |
|
264 } |
|
265 |
|
266 void handleInsert(int pos, int length) { |
|
267 int index = getViewIndex(pos, Position.Bias.Forward); |
|
268 View v = getView(index); |
|
269 int offs0 = v.getStartOffset(); |
|
270 int offs1 = v.getEndOffset(); |
|
271 if ((offs1 - offs0) > maxZoneSize) { |
|
272 splitZone(index, offs0, offs1); |
|
273 } |
|
274 } |
|
275 |
|
276 void handleRemove(int pos, int length) { |
|
277 // IMPLEMENT |
|
278 } |
|
279 |
|
280 /** |
|
281 * Break up the zone at the given index into pieces |
|
282 * of an acceptable size. |
|
283 */ |
|
284 void splitZone(int index, int offs0, int offs1) { |
|
285 // divide the old zone into a new set of bins |
|
286 Element elem = getElement(); |
|
287 Document doc = elem.getDocument(); |
|
288 Vector zones = new Vector(); |
|
289 int offs = offs0; |
|
290 do { |
|
291 offs0 = offs; |
|
292 offs = Math.min(getDesiredZoneEnd(offs0), offs1); |
|
293 zones.addElement(createZone(offs0, offs)); |
|
294 } while (offs < offs1); |
|
295 View oldZone = getView(index); |
|
296 View[] newZones = new View[zones.size()]; |
|
297 zones.copyInto(newZones); |
|
298 replace(index, 1, newZones); |
|
299 } |
|
300 |
|
301 /** |
|
302 * Returns the zone position to use for the |
|
303 * end of a zone that starts at the given |
|
304 * position. By default this returns something |
|
305 * close to half the max zone size. |
|
306 */ |
|
307 int getDesiredZoneEnd(int pos) { |
|
308 Element elem = getElement(); |
|
309 int index = elem.getElementIndex(pos + (maxZoneSize / 2)); |
|
310 Element child = elem.getElement(index); |
|
311 int offs0 = child.getStartOffset(); |
|
312 int offs1 = child.getEndOffset(); |
|
313 if ((offs1 - pos) > maxZoneSize) { |
|
314 if (offs0 > pos) { |
|
315 return offs0; |
|
316 } |
|
317 } |
|
318 return offs1; |
|
319 } |
|
320 |
|
321 // ---- View methods ---------------------------------------------------- |
|
322 |
|
323 /** |
|
324 * The superclass behavior will try to update the child views |
|
325 * which is not desired in this case, since the children are |
|
326 * zones and not directly effected by the changes to the |
|
327 * associated element. This is reimplemented to do nothing |
|
328 * and return false. |
|
329 */ |
|
330 protected boolean updateChildren(DocumentEvent.ElementChange ec, |
|
331 DocumentEvent e, ViewFactory f) { |
|
332 return false; |
|
333 } |
|
334 |
|
335 /** |
|
336 * Gives notification that something was inserted into the document |
|
337 * in a location that this view is responsible for. This is largely |
|
338 * delegated to the superclass, but is reimplemented to update the |
|
339 * relevant zone (i.e. determine if a zone needs to be split into a |
|
340 * set of 2 or more zones). |
|
341 * |
|
342 * @param changes the change information from the associated document |
|
343 * @param a the current allocation of the view |
|
344 * @param f the factory to use to rebuild if the view has children |
|
345 * @see View#insertUpdate |
|
346 */ |
|
347 public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) { |
|
348 handleInsert(changes.getOffset(), changes.getLength()); |
|
349 super.insertUpdate(changes, a, f); |
|
350 } |
|
351 |
|
352 /** |
|
353 * Gives notification that something was removed from the document |
|
354 * in a location that this view is responsible for. This is largely |
|
355 * delegated to the superclass, but is reimplemented to update the |
|
356 * relevant zones (i.e. determine if zones need to be removed or |
|
357 * joined with another zone). |
|
358 * |
|
359 * @param changes the change information from the associated document |
|
360 * @param a the current allocation of the view |
|
361 * @param f the factory to use to rebuild if the view has children |
|
362 * @see View#removeUpdate |
|
363 */ |
|
364 public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) { |
|
365 handleRemove(changes.getOffset(), changes.getLength()); |
|
366 super.removeUpdate(changes, a, f); |
|
367 } |
|
368 |
|
369 /** |
|
370 * Internally created view that has the purpose of holding |
|
371 * the views that represent the children of the ZoneView |
|
372 * that have been arranged in a zone. |
|
373 */ |
|
374 class Zone extends AsyncBoxView { |
|
375 |
|
376 private Position start; |
|
377 private Position end; |
|
378 |
|
379 public Zone(Element elem, Position start, Position end) { |
|
380 super(elem, ZoneView.this.getAxis()); |
|
381 this.start = start; |
|
382 this.end = end; |
|
383 } |
|
384 |
|
385 /** |
|
386 * Creates the child views and populates the |
|
387 * zone with them. This is done by translating |
|
388 * the positions to child element index locations |
|
389 * and building views to those elements. If the |
|
390 * zone is already loaded, this does nothing. |
|
391 */ |
|
392 public void load() { |
|
393 if (! isLoaded()) { |
|
394 setEstimatedMajorSpan(true); |
|
395 Element e = getElement(); |
|
396 ViewFactory f = getViewFactory(); |
|
397 int index0 = e.getElementIndex(getStartOffset()); |
|
398 int index1 = e.getElementIndex(getEndOffset()); |
|
399 View[] added = new View[index1 - index0 + 1]; |
|
400 for (int i = index0; i <= index1; i++) { |
|
401 added[i - index0] = f.create(e.getElement(i)); |
|
402 } |
|
403 replace(0, 0, added); |
|
404 |
|
405 zoneWasLoaded(this); |
|
406 } |
|
407 } |
|
408 |
|
409 /** |
|
410 * Removes the child views and returns to a |
|
411 * state of unloaded. |
|
412 */ |
|
413 public void unload() { |
|
414 setEstimatedMajorSpan(true); |
|
415 removeAll(); |
|
416 } |
|
417 |
|
418 /** |
|
419 * Determines if the zone is in the loaded state |
|
420 * or not. |
|
421 */ |
|
422 public boolean isLoaded() { |
|
423 return (getViewCount() != 0); |
|
424 } |
|
425 |
|
426 /** |
|
427 * This method is reimplemented to not build the children |
|
428 * since the children are created when the zone is loaded |
|
429 * rather then when it is placed in the view hierarchy. |
|
430 * The major span is estimated at this point by building |
|
431 * the first child (but not storing it), and calling |
|
432 * setEstimatedMajorSpan(true) followed by setSpan for |
|
433 * the major axis with the estimated span. |
|
434 */ |
|
435 protected void loadChildren(ViewFactory f) { |
|
436 // mark the major span as estimated |
|
437 setEstimatedMajorSpan(true); |
|
438 |
|
439 // estimate the span |
|
440 Element elem = getElement(); |
|
441 int index0 = elem.getElementIndex(getStartOffset()); |
|
442 int index1 = elem.getElementIndex(getEndOffset()); |
|
443 int nChildren = index1 - index0; |
|
444 |
|
445 // replace this with something real |
|
446 //setSpan(getMajorAxis(), nChildren * 10); |
|
447 |
|
448 View first = f.create(elem.getElement(index0)); |
|
449 first.setParent(this); |
|
450 float w = first.getPreferredSpan(X_AXIS); |
|
451 float h = first.getPreferredSpan(Y_AXIS); |
|
452 if (getMajorAxis() == X_AXIS) { |
|
453 w *= nChildren; |
|
454 } else { |
|
455 h += nChildren; |
|
456 } |
|
457 |
|
458 setSize(w, h); |
|
459 } |
|
460 |
|
461 /** |
|
462 * Publish the changes in preferences upward to the parent |
|
463 * view. |
|
464 * <p> |
|
465 * This is reimplemented to stop the superclass behavior |
|
466 * if the zone has not yet been loaded. If the zone is |
|
467 * unloaded for example, the last seen major span is the |
|
468 * best estimate and a calculated span for no children |
|
469 * is undesirable. |
|
470 */ |
|
471 protected void flushRequirementChanges() { |
|
472 if (isLoaded()) { |
|
473 super.flushRequirementChanges(); |
|
474 } |
|
475 } |
|
476 |
|
477 /** |
|
478 * Returns the child view index representing the given position in |
|
479 * the model. Since the zone contains a cluster of the overall |
|
480 * set of child elements, we can determine the index fairly |
|
481 * quickly from the model by subtracting the index of the |
|
482 * start offset from the index of the position given. |
|
483 * |
|
484 * @param pos the position >= 0 |
|
485 * @return index of the view representing the given position, or |
|
486 * -1 if no view represents that position |
|
487 * @since 1.3 |
|
488 */ |
|
489 public int getViewIndex(int pos, Position.Bias b) { |
|
490 boolean isBackward = (b == Position.Bias.Backward); |
|
491 pos = (isBackward) ? Math.max(0, pos - 1) : pos; |
|
492 Element elem = getElement(); |
|
493 int index1 = elem.getElementIndex(pos); |
|
494 int index0 = elem.getElementIndex(getStartOffset()); |
|
495 return index1 - index0; |
|
496 } |
|
497 |
|
498 protected boolean updateChildren(DocumentEvent.ElementChange ec, |
|
499 DocumentEvent e, ViewFactory f) { |
|
500 // the structure of this element changed. |
|
501 Element[] removedElems = ec.getChildrenRemoved(); |
|
502 Element[] addedElems = ec.getChildrenAdded(); |
|
503 Element elem = getElement(); |
|
504 int index0 = elem.getElementIndex(getStartOffset()); |
|
505 int index1 = elem.getElementIndex(getEndOffset()-1); |
|
506 int index = ec.getIndex(); |
|
507 if ((index >= index0) && (index <= index1)) { |
|
508 // The change is in this zone |
|
509 int replaceIndex = index - index0; |
|
510 int nadd = Math.min(index1 - index0 + 1, addedElems.length); |
|
511 int nremove = Math.min(index1 - index0 + 1, removedElems.length); |
|
512 View[] added = new View[nadd]; |
|
513 for (int i = 0; i < nadd; i++) { |
|
514 added[i] = f.create(addedElems[i]); |
|
515 } |
|
516 replace(replaceIndex, nremove, added); |
|
517 } |
|
518 return true; |
|
519 } |
|
520 |
|
521 // --- View methods ---------------------------------- |
|
522 |
|
523 /** |
|
524 * Fetches the attributes to use when rendering. This view |
|
525 * isn't directly responsible for an element so it returns |
|
526 * the outer classes attributes. |
|
527 */ |
|
528 public AttributeSet getAttributes() { |
|
529 return ZoneView.this.getAttributes(); |
|
530 } |
|
531 |
|
532 /** |
|
533 * Renders using the given rendering surface and area on that |
|
534 * surface. This is implemented to load the zone if its not |
|
535 * already loaded, and then perform the superclass behavior. |
|
536 * |
|
537 * @param g the rendering surface to use |
|
538 * @param a the allocated region to render into |
|
539 * @see View#paint |
|
540 */ |
|
541 public void paint(Graphics g, Shape a) { |
|
542 load(); |
|
543 super.paint(g, a); |
|
544 } |
|
545 |
|
546 /** |
|
547 * Provides a mapping from the view coordinate space to the logical |
|
548 * coordinate space of the model. This is implemented to first |
|
549 * make sure the zone is loaded before providing the superclass |
|
550 * behavior. |
|
551 * |
|
552 * @param x x coordinate of the view location to convert >= 0 |
|
553 * @param y y coordinate of the view location to convert >= 0 |
|
554 * @param a the allocated region to render into |
|
555 * @return the location within the model that best represents the |
|
556 * given point in the view >= 0 |
|
557 * @see View#viewToModel |
|
558 */ |
|
559 public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { |
|
560 load(); |
|
561 return super.viewToModel(x, y, a, bias); |
|
562 } |
|
563 |
|
564 /** |
|
565 * Provides a mapping from the document model coordinate space |
|
566 * to the coordinate space of the view mapped to it. This is |
|
567 * implemented to provide the superclass behavior after first |
|
568 * making sure the zone is loaded (The zone must be loaded to |
|
569 * make this calculation). |
|
570 * |
|
571 * @param pos the position to convert |
|
572 * @param a the allocated region to render into |
|
573 * @return the bounding box of the given position |
|
574 * @exception BadLocationException if the given position does not represent a |
|
575 * valid location in the associated document |
|
576 * @see View#modelToView |
|
577 */ |
|
578 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { |
|
579 load(); |
|
580 return super.modelToView(pos, a, b); |
|
581 } |
|
582 |
|
583 /** |
|
584 * Start of the zones range. |
|
585 * |
|
586 * @see View#getStartOffset |
|
587 */ |
|
588 public int getStartOffset() { |
|
589 return start.getOffset(); |
|
590 } |
|
591 |
|
592 /** |
|
593 * End of the zones range. |
|
594 */ |
|
595 public int getEndOffset() { |
|
596 return end.getOffset(); |
|
597 } |
|
598 |
|
599 /** |
|
600 * Gives notification that something was inserted into |
|
601 * the document in a location that this view is responsible for. |
|
602 * If the zone has been loaded, the superclass behavior is |
|
603 * invoked, otherwise this does nothing. |
|
604 * |
|
605 * @param e the change information from the associated document |
|
606 * @param a the current allocation of the view |
|
607 * @param f the factory to use to rebuild if the view has children |
|
608 * @see View#insertUpdate |
|
609 */ |
|
610 public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { |
|
611 if (isLoaded()) { |
|
612 super.insertUpdate(e, a, f); |
|
613 } |
|
614 } |
|
615 |
|
616 /** |
|
617 * Gives notification that something was removed from the document |
|
618 * in a location that this view is responsible for. |
|
619 * If the zone has been loaded, the superclass behavior is |
|
620 * invoked, otherwise this does nothing. |
|
621 * |
|
622 * @param e the change information from the associated document |
|
623 * @param a the current allocation of the view |
|
624 * @param f the factory to use to rebuild if the view has children |
|
625 * @see View#removeUpdate |
|
626 */ |
|
627 public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { |
|
628 if (isLoaded()) { |
|
629 super.removeUpdate(e, a, f); |
|
630 } |
|
631 } |
|
632 |
|
633 /** |
|
634 * Gives notification from the document that attributes were changed |
|
635 * in a location that this view is responsible for. |
|
636 * If the zone has been loaded, the superclass behavior is |
|
637 * invoked, otherwise this does nothing. |
|
638 * |
|
639 * @param e the change information from the associated document |
|
640 * @param a the current allocation of the view |
|
641 * @param f the factory to use to rebuild if the view has children |
|
642 * @see View#removeUpdate |
|
643 */ |
|
644 public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { |
|
645 if (isLoaded()) { |
|
646 super.changedUpdate(e, a, f); |
|
647 } |
|
648 } |
|
649 |
|
650 } |
|
651 } |