1 7 package javax.swing.text; 8 9 import java.util.Vector ; 10 import java.awt.*; 11 import javax.swing.event.*; 12 import javax.swing.SwingConstants ; 13 14 59 public abstract class CompositeView extends View { 60 61 66 public CompositeView(Element elem) { 67 super(elem); 68 children = new View [1]; 69 nchildren = 0; 70 childAlloc = new Rectangle(); 71 } 72 73 84 protected void loadChildren(ViewFactory f) { 85 if (f == null) { 86 return; 89 } 90 Element e = getElement(); 91 int n = e.getElementCount(); 92 if (n > 0) { 93 View [] added = new View [n]; 94 for (int i = 0; i < n; i++) { 95 added[i] = f.create(e.getElement(i)); 96 } 97 replace(0, 0, added); 98 } 99 } 100 101 103 118 public void setParent(View parent) { 119 super.setParent(parent); 120 if ((parent != null) && (nchildren == 0)) { 121 ViewFactory f = getViewFactory(); 122 loadChildren(f); 123 } 124 } 125 126 132 public int getViewCount() { 133 return nchildren; 134 } 135 136 142 public View getView(int n) { 143 return children[n]; 144 } 145 146 162 public void replace(int offset, int length, View [] views) { 163 if (views == null) { 165 views = ZERO; 166 } 167 168 for (int i = offset; i < offset + length; i++) { 170 if (children[i].getParent() == this) { 171 children[i].setParent(null); 174 } 175 children[i] = null; 176 } 177 178 int delta = views.length - length; 180 int src = offset + length; 181 int nmove = nchildren - src; 182 int dest = src + delta; 183 if ((nchildren + delta) >= children.length) { 184 int newLength = Math.max(2*children.length, nchildren + delta); 186 View [] newChildren = new View [newLength]; 187 System.arraycopy(children, 0, newChildren, 0, offset); 188 System.arraycopy(views, 0, newChildren, offset, views.length); 189 System.arraycopy(children, src, newChildren, dest, nmove); 190 children = newChildren; 191 } else { 192 System.arraycopy(children, src, children, dest, nmove); 194 System.arraycopy(views, 0, children, offset, views.length); 195 } 196 nchildren = nchildren + delta; 197 198 for (int i = 0; i < views.length; i++) { 200 views[i].setParent(this); 201 } 202 } 203 204 213 public Shape getChildAllocation(int index, Shape a) { 214 Rectangle alloc = getInsideAllocation(a); 215 childAllocation(index, alloc); 216 return alloc; 217 } 218 219 232 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 233 boolean isBackward = (b == Position.Bias.Backward); 234 int testPos = (isBackward) ? Math.max(0, pos - 1) : pos; 235 if(isBackward && testPos < getStartOffset()) { 236 return null; 237 } 238 int vIndex = getViewIndexAtPosition(testPos); 239 if ((vIndex != -1) && (vIndex < getViewCount())) { 240 View v = getView(vIndex); 241 if(v != null && testPos >= v.getStartOffset() && 242 testPos < v.getEndOffset()) { 243 Shape childShape = getChildAllocation(vIndex, a); 244 if (childShape == null) { 245 return null; 247 } 248 Shape retShape = v.modelToView(pos, childShape, b); 249 if(retShape == null && v.getEndOffset() == pos) { 250 if(++vIndex < getViewCount()) { 251 v = getView(vIndex); 252 retShape = v.modelToView(pos, getChildAllocation(vIndex, a), b); 253 } 254 } 255 return retShape; 256 } 257 } 258 throw new BadLocationException ("Position not represented by view", 259 pos); 260 } 261 262 283 public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, Shape a) throws BadLocationException { 284 if (p0 == getStartOffset() && p1 == getEndOffset()) { 285 return a; 286 } 287 Rectangle alloc = getInsideAllocation(a); 288 Rectangle r0 = new Rectangle(alloc); 289 View v0 = getViewAtPosition((b0 == Position.Bias.Backward) ? 290 Math.max(0, p0 - 1) : p0, r0); 291 Rectangle r1 = new Rectangle(alloc); 292 View v1 = getViewAtPosition((b1 == Position.Bias.Backward) ? 293 Math.max(0, p1 - 1) : p1, r1); 294 if (v0 == v1) { 295 if (v0 == null) { 296 return a; 297 } 298 return v0.modelToView(p0, b0, p1, b1, r0); 300 } 301 int viewCount = getViewCount(); 303 int counter = 0; 304 while (counter < viewCount) { 305 View v; 306 if ((v = getView(counter)) == v0 || v == v1) { 310 View endView; 311 Rectangle retRect; 312 Rectangle tempRect = new Rectangle(); 313 if (v == v0) { 314 retRect = v0.modelToView(p0, b0, v0.getEndOffset(), 315 Position.Bias.Backward, r0). 316 getBounds(); 317 endView = v1; 318 } 319 else { 320 retRect = v1.modelToView(v1.getStartOffset(), 321 Position.Bias.Forward, 322 p1, b1, r1).getBounds(); 323 endView = v0; 324 } 325 326 while (++counter < viewCount && 328 (v = getView(counter)) != endView) { 329 tempRect.setBounds(alloc); 330 childAllocation(counter, tempRect); 331 retRect.add(tempRect); 332 } 333 334 if (endView != null) { 336 Shape endShape; 337 if (endView == v1) { 338 endShape = v1.modelToView(v1.getStartOffset(), 339 Position.Bias.Forward, 340 p1, b1, r1); 341 } 342 else { 343 endShape = v0.modelToView(p0, b0, v0.getEndOffset(), 344 Position.Bias.Backward, r0); 345 } 346 if (endShape instanceof Rectangle) { 347 retRect.add((Rectangle)endShape); 348 } 349 else { 350 retRect.add(endShape.getBounds()); 351 } 352 } 353 return retRect; 354 } 355 counter++; 356 } 357 throw new BadLocationException ("Position not represented by view", p0); 358 } 359 360 373 public int viewToModel(float x, float y, Shape a, Position.Bias [] bias) { 374 Rectangle alloc = getInsideAllocation(a); 375 if (isBefore((int) x, (int) y, alloc)) { 376 int retValue = -1; 378 379 try { 380 retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, 381 a, EAST, bias); 382 } catch (BadLocationException ble) { } 383 catch (IllegalArgumentException iae) { } 384 if(retValue == -1) { 385 retValue = getStartOffset(); 386 bias[0] = Position.Bias.Forward; 387 } 388 return retValue; 389 } else if (isAfter((int) x, (int) y, alloc)) { 390 int retValue = -1; 392 try { 393 retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, 394 a, WEST, bias); 395 } catch (BadLocationException ble) { } 396 catch (IllegalArgumentException iae) { } 397 398 if(retValue == -1) { 399 retValue = getEndOffset() - 1; 401 bias[0] = Position.Bias.Forward; 402 } 403 return retValue; 404 } else { 405 View v = getViewAtPoint((int) x, (int) y, alloc); 407 if (v != null) { 408 return v.viewToModel(x, y, alloc, bias); 409 } 410 } 411 return -1; 412 } 413 414 441 public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, 442 int direction, Position.Bias [] biasRet) 443 throws BadLocationException { 444 Rectangle alloc = getInsideAllocation(a); 445 446 switch (direction) { 447 case NORTH: 448 return getNextNorthSouthVisualPositionFrom(pos, b, a, direction, 449 biasRet); 450 case SOUTH: 451 return getNextNorthSouthVisualPositionFrom(pos, b, a, direction, 452 biasRet); 453 case EAST: 454 return getNextEastWestVisualPositionFrom(pos, b, a, direction, 455 biasRet); 456 case WEST: 457 return getNextEastWestVisualPositionFrom(pos, b, a, direction, 458 biasRet); 459 default: 460 throw new IllegalArgumentException ("Bad direction: " + direction); 461 } 462 } 463 464 474 public int getViewIndex(int pos, Position.Bias b) { 475 if(b == Position.Bias.Backward) { 476 pos -= 1; 477 } 478 if ((pos >= getStartOffset()) && (pos < getEndOffset())) { 479 return getViewIndexAtPosition(pos); 480 } 481 return -1; 482 } 483 484 486 487 495 protected abstract boolean isBefore(int x, int y, Rectangle alloc); 496 497 505 protected abstract boolean isAfter(int x, int y, Rectangle alloc); 506 507 516 protected abstract View getViewAtPoint(int x, int y, Rectangle alloc); 517 518 525 protected abstract void childAllocation(int index, Rectangle a); 526 527 538 protected View getViewAtPosition(int pos, Rectangle a) { 539 int index = getViewIndexAtPosition(pos); 540 if ((index >= 0) && (index < getViewCount())) { 541 View v = getView(index); 542 if (a != null) { 543 childAllocation(index, a); 544 } 545 return v; 546 } 547 return null; 548 } 549 550 559 protected int getViewIndexAtPosition(int pos) { 560 Element elem = getElement(); 561 return elem.getElementIndex(pos); 562 } 563 564 582 protected Rectangle getInsideAllocation(Shape a) { 583 if (a != null) { 584 Rectangle alloc; 589 if (a instanceof Rectangle) { 590 alloc = (Rectangle) a; 591 } else { 592 alloc = a.getBounds(); 593 } 594 595 childAlloc.setBounds(alloc); 596 childAlloc.x += getLeftInset(); 597 childAlloc.y += getTopInset(); 598 childAlloc.width -= getLeftInset() + getRightInset(); 599 childAlloc.height -= getTopInset() + getBottomInset(); 600 return childAlloc; 601 } 602 return null; 603 } 604 605 611 protected void setParagraphInsets(AttributeSet attr) { 612 top = (short) StyleConstants.getSpaceAbove(attr); 616 left = (short) StyleConstants.getLeftIndent(attr); 617 bottom = (short) StyleConstants.getSpaceBelow(attr); 618 right = (short) StyleConstants.getRightIndent(attr); 619 } 620 621 629 protected void setInsets(short top, short left, short bottom, short right) { 630 this.top = top; 631 this.left = left; 632 this.right = right; 633 this.bottom = bottom; 634 } 635 636 641 protected short getLeftInset() { 642 return left; 643 } 644 645 650 protected short getRightInset() { 651 return right; 652 } 653 654 659 protected short getTopInset() { 660 return top; 661 } 662 663 668 protected short getBottomInset() { 669 return bottom; 670 } 671 672 696 protected int getNextNorthSouthVisualPositionFrom(int pos, Position.Bias b, 697 Shape a, int direction, 698 Position.Bias [] biasRet) 699 throws BadLocationException { 700 return Utilities.getNextVisualPositionFrom( 701 this, pos, b, a, direction, biasRet); 702 } 703 704 726 protected int getNextEastWestVisualPositionFrom(int pos, Position.Bias b, 727 Shape a, 728 int direction, 729 Position.Bias [] biasRet) 730 throws BadLocationException { 731 return Utilities.getNextVisualPositionFrom( 732 this, pos, b, a, direction, biasRet); 733 } 734 735 758 protected boolean flipEastAndWestAtEnds(int position, 759 Position.Bias bias) { 760 return false; 761 } 762 763 764 766 767 private static View [] ZERO = new View [0]; 768 769 private View [] children; 770 private int nchildren; 771 private short left; 772 private short right; 773 private short top; 774 private short bottom; 775 private Rectangle childAlloc; 776 } 777 | Popular Tags |