1 7 package javax.swing.text; 8 9 import java.util.Vector ; 10 import java.awt.*; 11 import javax.swing.event.*; 12 13 61 public class ZoneView extends BoxView { 62 63 int maxZoneSize = 8 * 1024; 64 int maxZonesLoaded = 3; 65 Vector loadedZones; 66 67 73 public ZoneView(Element elem, int axis) { 74 super(elem, axis); 75 loadedZones = new Vector (); 76 } 77 78 81 public int getMaximumZoneSize() { 82 return maxZoneSize; 83 } 84 85 96 public void setMaximumZoneSize(int size) { 97 maxZoneSize = size; 98 } 99 100 104 public int getMaxZonesLoaded() { 105 return maxZonesLoaded; 106 } 107 108 118 public void setMaxZonesLoaded(int mzl) { 119 if (mzl < 1) { 120 throw new IllegalArgumentException ("ZoneView.setMaxZonesLoaded must be greater than 0."); 121 } 122 maxZonesLoaded = mzl; 123 unloadOldZones(); 124 } 125 126 135 protected void zoneWasLoaded(View zone) { 136 loadedZones.addElement(zone); 138 unloadOldZones(); 139 } 140 141 void unloadOldZones() { 142 while (loadedZones.size() > getMaxZonesLoaded()) { 143 View zone = (View ) loadedZones.elementAt(0); 144 loadedZones.removeElementAt(0); 145 unloadZone(zone); 146 } 147 } 148 149 159 protected void unloadZone(View zone) { 160 zone.removeAll(); 162 } 163 164 171 protected boolean isZoneLoaded(View zone) { 172 return (zone.getViewCount() > 0); 173 } 174 175 190 protected View createZone(int p0, int p1) { 191 Document doc = getDocument(); 192 View zone = null; 193 try { 194 zone = new Zone(getElement(), 195 doc.createPosition(p0), 196 doc.createPosition(p1)); 197 } catch (BadLocationException ble) { 198 throw new StateInvariantError (ble.getMessage()); 200 } 201 return zone; 202 } 203 204 215 protected void loadChildren(ViewFactory f) { 216 Document doc = getDocument(); 218 int offs0 = getStartOffset(); 219 int offs1 = getEndOffset(); 220 append(createZone(offs0, offs1)); 221 handleInsert(offs0, offs1 - offs0); 222 } 223 224 232 protected int getViewIndexAtPosition(int pos) { 233 int n = getViewCount(); 236 if (pos == getEndOffset()) { 237 return n - 1; 238 } 239 for(int i = 0; i < n; i++) { 240 View v = getView(i); 241 if(pos >= v.getStartOffset() && 242 pos < v.getEndOffset()) { 243 return i; 244 } 245 } 246 return -1; 247 } 248 249 void handleInsert(int pos, int length) { 250 int index = getViewIndex(pos, Position.Bias.Forward); 251 View v = getView(index); 252 int offs0 = v.getStartOffset(); 253 int offs1 = v.getEndOffset(); 254 if ((offs1 - offs0) > maxZoneSize) { 255 splitZone(index, offs0, offs1); 256 } 257 } 258 259 void handleRemove(int pos, int length) { 260 } 262 263 267 void splitZone(int index, int offs0, int offs1) { 268 Element elem = getElement(); 270 Document doc = elem.getDocument(); 271 Vector zones = new Vector (); 272 int offs = offs0; 273 do { 274 offs0 = offs; 275 offs = Math.min(getDesiredZoneEnd(offs0), offs1); 276 zones.addElement(createZone(offs0, offs)); 277 } while (offs < offs1); 278 View oldZone = getView(index); 279 View [] newZones = new View [zones.size()]; 280 zones.copyInto(newZones); 281 replace(index, 1, newZones); 282 } 283 284 290 int getDesiredZoneEnd(int pos) { 291 Element elem = getElement(); 292 int index = elem.getElementIndex(pos + (maxZoneSize / 2)); 293 Element child = elem.getElement(index); 294 int offs0 = child.getStartOffset(); 295 int offs1 = child.getEndOffset(); 296 if ((offs1 - pos) > maxZoneSize) { 297 if (offs0 > pos) { 298 return offs0; 299 } 300 } 301 return offs1; 302 } 303 304 306 313 protected boolean updateChildren(DocumentEvent.ElementChange ec, 314 DocumentEvent e, ViewFactory f) { 315 return false; 316 } 317 318 330 public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) { 331 handleInsert(changes.getOffset(), changes.getLength()); 332 super.insertUpdate(changes, a, f); 333 } 334 335 347 public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) { 348 handleRemove(changes.getOffset(), changes.getLength()); 349 super.removeUpdate(changes, a, f); 350 } 351 352 357 class Zone extends AsyncBoxView { 358 359 private Position start; 360 private Position end; 361 362 public Zone(Element elem, Position start, Position end) { 363 super(elem, ZoneView.this.getAxis()); 364 this.start = start; 365 this.end = end; 366 } 367 368 375 public void load() { 376 if (! isLoaded()) { 377 setEstimatedMajorSpan(true); 378 Element e = getElement(); 379 ViewFactory f = getViewFactory(); 380 int index0 = e.getElementIndex(getStartOffset()); 381 int index1 = e.getElementIndex(getEndOffset()); 382 View [] added = new View [index1 - index0 + 1]; 383 for (int i = index0; i <= index1; i++) { 384 added[i - index0] = f.create(e.getElement(i)); 385 } 386 replace(0, 0, added); 387 388 zoneWasLoaded(this); 389 } 390 } 391 392 396 public void unload() { 397 setEstimatedMajorSpan(true); 398 removeAll(); 399 } 400 401 405 public boolean isLoaded() { 406 return (getViewCount() != 0); 407 } 408 409 418 protected void loadChildren(ViewFactory f) { 419 setEstimatedMajorSpan(true); 421 422 Element elem = getElement(); 424 int index0 = elem.getElementIndex(getStartOffset()); 425 int index1 = elem.getElementIndex(getEndOffset()); 426 int nChildren = index1 - index0; 427 428 431 View first = f.create(elem.getElement(index0)); 432 first.setParent(this); 433 float w = first.getPreferredSpan(X_AXIS); 434 float h = first.getPreferredSpan(Y_AXIS); 435 if (getMajorAxis() == X_AXIS) { 436 w *= nChildren; 437 } else { 438 h += nChildren; 439 } 440 441 setSize(w, h); 442 } 443 444 454 protected void flushRequirementChanges() { 455 if (isLoaded()) { 456 super.flushRequirementChanges(); 457 } 458 } 459 460 472 public int getViewIndex(int pos, Position.Bias b) { 473 boolean isBackward = (b == Position.Bias.Backward); 474 pos = (isBackward) ? Math.max(0, pos - 1) : pos; 475 Element elem = getElement(); 476 int index1 = elem.getElementIndex(pos); 477 int index0 = elem.getElementIndex(getStartOffset()); 478 return index1 - index0; 479 } 480 481 protected boolean updateChildren(DocumentEvent.ElementChange ec, 482 DocumentEvent e, ViewFactory f) { 483 Element [] removedElems = ec.getChildrenRemoved(); 485 Element [] addedElems = ec.getChildrenAdded(); 486 Element elem = getElement(); 487 int index0 = elem.getElementIndex(getStartOffset()); 488 int index1 = elem.getElementIndex(getEndOffset()-1); 489 int index = ec.getIndex(); 490 if ((index >= index0) && (index <= index1)) { 491 int replaceIndex = index - index0; 493 int nadd = Math.min(index1 - index0 + 1, addedElems.length); 494 int nremove = Math.min(index1 - index0 + 1, removedElems.length); 495 View [] added = new View [nadd]; 496 for (int i = 0; i < nadd; i++) { 497 added[i] = f.create(addedElems[i]); 498 } 499 replace(replaceIndex, nremove, added); 500 } 501 return true; 502 } 503 504 506 511 public AttributeSet getAttributes() { 512 return ZoneView.this.getAttributes(); 513 } 514 515 524 public void paint(Graphics g, Shape a) { 525 load(); 526 super.paint(g, a); 527 } 528 529 542 public int viewToModel(float x, float y, Shape a, Position.Bias [] bias) { 543 load(); 544 return super.viewToModel(x, y, a, bias); 545 } 546 547 561 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 562 load(); 563 return super.modelToView(pos, a, b); 564 } 565 566 571 public int getStartOffset() { 572 return start.getOffset(); 573 } 574 575 578 public int getEndOffset() { 579 return end.getOffset(); 580 } 581 582 593 public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { 594 if (isLoaded()) { 595 super.insertUpdate(e, a, f); 596 } 597 } 598 599 610 public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { 611 if (isLoaded()) { 612 super.removeUpdate(e, a, f); 613 } 614 } 615 616 627 public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { 628 if (isLoaded()) { 629 super.changedUpdate(e, a, f); 630 } 631 } 632 633 } 634 } 635 | Popular Tags |