1 7 8 package javax.swing; 9 10 import java.awt.*; 11 import java.awt.event.*; 12 import java.awt.image.VolatileImage ; 13 import java.awt.peer.ComponentPeer; 14 import java.applet.Applet ; 15 import javax.swing.plaf.ViewportUI ; 16 17 import javax.swing.event.*; 18 import javax.swing.border.*; 19 import javax.accessibility.*; 20 21 22 import java.io.Serializable ; 23 24 25 82 public class JViewport extends JComponent implements Accessible 83 { 84 88 private static final String uiClassID = "ViewportUI"; 89 90 92 static final Object EnableWindowBlit = "EnableWindowBlit"; 93 94 98 protected boolean isViewSizeSet = false; 99 100 104 protected Point lastPaintPosition = null; 105 106 115 @Deprecated 116 protected boolean backingStore = false; 117 118 119 transient protected Image backingStoreImage = null; 120 121 137 protected boolean scrollUnderway = false; 138 139 142 private ComponentListener viewListener = null; 143 144 149 private transient ChangeEvent changeEvent = null; 150 151 158 public static final int BLIT_SCROLL_MODE = 1; 159 160 169 public static final int BACKINGSTORE_SCROLL_MODE = 2; 170 171 181 public static final int SIMPLE_SCROLL_MODE = 0; 182 183 187 private int scrollMode = BLIT_SCROLL_MODE; 188 189 213 214 218 private transient boolean repaintAll; 219 220 227 private transient boolean waitingForRepaint; 228 229 233 private transient Timer repaintTimer; 234 235 238 private boolean hasHadValidView; 239 240 241 public JViewport() { 242 super(); 243 setLayout(createLayoutManager()); 244 setOpaque(true); 245 updateUI(); 246 } 247 248 249 250 255 public ViewportUI getUI() { 256 return (ViewportUI )ui; 257 } 258 259 260 271 public void setUI(ViewportUI ui) { 272 super.setUI(ui); 273 } 274 275 276 281 public void updateUI() { 282 setUI((ViewportUI )UIManager.getUI(this)); 283 } 284 285 286 295 public String getUIClassID() { 296 return uiClassID; 297 } 298 299 300 312 protected void addImpl(Component child, Object constraints, int index) { 313 setView(child); 314 } 315 316 317 322 public void remove(Component child) { 323 child.removeComponentListener(viewListener); 324 super.remove(child); 325 } 326 327 328 349 public void scrollRectToVisible(Rectangle contentRect) { 350 Component view = getView(); 351 352 if (view == null) { 353 return; 354 } else { 355 if (!view.isValid()) { 356 validateView(); 360 } 361 int dx = 0, dy = 0; 362 363 dx = positionAdjustment(getWidth(), contentRect.width, contentRect.x); 364 dy = positionAdjustment(getHeight(), contentRect.height, contentRect.y); 365 366 if (dx != 0 || dy != 0) { 367 Point viewPosition = getViewPosition(); 368 Dimension viewSize = view.getSize(); 369 int startX = viewPosition.x; 370 int startY = viewPosition.y; 371 Dimension extent = getExtentSize(); 372 373 viewPosition.x -= dx; 374 viewPosition.y -= dy; 375 if (view.isValid()) { 380 if (getParent().getComponentOrientation().isLeftToRight()) { 381 if (viewPosition.x + extent.width > viewSize.width) { 382 viewPosition.x = Math.max(0, viewSize.width - extent.width); 383 } else if (viewPosition.x < 0) { 384 viewPosition.x = 0; 385 } 386 } else { 387 if (extent.width > viewSize.width) { 388 viewPosition.x = viewSize.width - extent.width; 389 } else { 390 viewPosition.x = Math.max(0, Math.min(viewSize.width - extent.width, viewPosition.x)); 391 } 392 } 393 if (viewPosition.y + extent.height > viewSize.height) { 394 viewPosition.y = Math.max(0, viewSize.height - 395 extent.height); 396 } 397 else if (viewPosition.y < 0) { 398 viewPosition.y = 0; 399 } 400 } 401 if (viewPosition.x != startX || viewPosition.y != startY) { 402 setViewPosition(viewPosition); 403 scrollUnderway = false; 425 } 426 } 427 } 428 } 429 430 440 private void validateView() { 441 Component validateRoot = null; 442 443 446 for(Component c = this; c != null; c = c.getParent()) { 447 if ((c instanceof CellRendererPane ) || (c.getPeer() == null)) { 448 return; 449 } 450 if ((c instanceof JComponent ) && 451 (((JComponent )c).isValidateRoot())) { 452 validateRoot = c; 453 break; 454 } 455 } 456 457 if (validateRoot == null) { 459 return; 460 } 461 462 Component root = null; 464 465 for(Component c = validateRoot; c != null; c = c.getParent()) { 466 if (c.getPeer() == null) { 471 return; 472 } 473 if ((c instanceof Window) || (c instanceof Applet )) { 474 root = c; 475 break; 476 } 477 } 478 479 if (root == null) { 481 return; 482 } 483 484 validateRoot.validate(); 486 487 RepaintManager rm = RepaintManager.currentManager(this); 490 491 if (rm != null) { 492 rm.removeInvalidComponent((JComponent )validateRoot); 493 } 494 } 495 496 501 private int positionAdjustment(int parentWidth, int childWidth, int childAt) { 502 503 if (childAt >= 0 && childWidth + childAt <= parentWidth) { 507 return 0; 508 } 509 510 if (childAt <= 0 && childWidth + childAt >= parentWidth) { 514 return 0; 515 } 516 517 if (childAt > 0 && childWidth <= parentWidth) { 521 return -childAt + parentWidth - childWidth; 522 } 523 524 if (childAt >= 0 && childWidth >= parentWidth) { 528 return -childAt; 529 } 530 531 if (childAt <= 0 && childWidth <= parentWidth) { 535 return -childAt; 536 } 537 538 if (childAt < 0 && childWidth >= parentWidth) { 542 return -childAt + parentWidth - childWidth; 543 } 544 545 return 0; 546 } 547 548 549 564 public final void setBorder(Border border) { 565 if (border != null) { 566 throw new IllegalArgumentException ("JViewport.setBorder() not supported"); 567 } 568 } 569 570 571 578 public final Insets getInsets() { 579 return new Insets(0, 0, 0, 0); 580 } 581 582 594 public final Insets getInsets(Insets insets) { 595 insets.left = insets.top = insets.right = insets.bottom = 0; 596 return insets; 597 } 598 599 600 private Graphics getBackingStoreGraphics(Graphics g) { 601 Graphics bsg = backingStoreImage.getGraphics(); 602 bsg.setColor(g.getColor()); 603 bsg.setFont(g.getFont()); 604 bsg.setClip(g.getClipBounds()); 605 return bsg; 606 } 607 608 609 private void paintViaBackingStore(Graphics g) { 610 Graphics bsg = getBackingStoreGraphics(g); 611 try { 612 super.paint(bsg); 613 g.drawImage(backingStoreImage, 0, 0, this); 614 } finally { 615 bsg.dispose(); 616 } 617 } 618 619 private void paintViaBackingStore(Graphics g, Rectangle oClip) { 620 Graphics bsg = getBackingStoreGraphics(g); 621 try { 622 super.paint(bsg); 623 g.setClip(oClip); 624 g.drawImage(backingStoreImage, 0, 0, this); 625 } finally { 626 bsg.dispose(); 627 } 628 } 629 630 641 public boolean isOptimizedDrawingEnabled() { 642 return false; 643 } 644 645 653 boolean isPaintingOrigin() { 654 if (scrollMode == BACKINGSTORE_SCROLL_MODE) { 655 return true; 656 } 657 return false; 658 } 659 660 661 664 private Point getViewLocation() { 665 Component view = getView(); 666 if (view != null) { 667 return view.getLocation(); 668 } 669 else { 670 return new Point(0,0); 671 } 672 } 673 674 687 public void paint(Graphics g) 688 { 689 int width = getWidth(); 690 int height = getHeight(); 691 692 if ((width <= 0) || (height <= 0)) { 693 return; 694 } 695 696 if (repaintAll) { 697 repaintAll = false; 698 Rectangle clipB = g.getClipBounds(); 699 if (clipB.width < getWidth() || 700 clipB.height < getHeight()) { 701 waitingForRepaint = true; 702 if (repaintTimer == null) { 703 repaintTimer = createRepaintTimer(); 704 } 705 repaintTimer.stop(); 706 repaintTimer.start(); 707 } 710 else { 711 if (repaintTimer != null) { 712 repaintTimer.stop(); 713 } 714 waitingForRepaint = false; 715 } 716 } 717 else if (waitingForRepaint) { 718 Rectangle clipB = g.getClipBounds(); 720 if (clipB.width >= getWidth() && 721 clipB.height >= getHeight()) { 722 waitingForRepaint = false; 723 repaintTimer.stop(); 724 } 725 } 726 727 if (!backingStore || isBlitting() || getView() == null) { 728 super.paint(g); 729 lastPaintPosition = getViewLocation(); 730 return; 731 } 732 733 Rectangle viewBounds = getView().getBounds(); 738 if (!isOpaque()) { 739 g.clipRect(0, 0, viewBounds.width, viewBounds.height); 740 } 741 742 if (backingStoreImage == null) { 743 backingStoreImage = createImage(width, height); 751 Rectangle clip = g.getClipBounds(); 752 if (clip.width != width || clip.height != height) { 753 if (!isOpaque()) { 754 g.setClip(0, 0, Math.min(viewBounds.width, width), 755 Math.min(viewBounds.height, height)); 756 } 757 else { 758 g.setClip(0, 0, width, height); 759 } 760 paintViaBackingStore(g, clip); 761 } 762 else { 763 paintViaBackingStore(g); 764 } 765 } 766 else { 767 if (!scrollUnderway || lastPaintPosition.equals(getViewLocation())) { 768 paintViaBackingStore(g); 770 } else { 771 Point blitFrom = new Point(); 773 Point blitTo = new Point(); 774 Dimension blitSize = new Dimension(); 775 Rectangle blitPaint = new Rectangle(); 776 777 Point newLocation = getViewLocation(); 778 int dx = newLocation.x - lastPaintPosition.x; 779 int dy = newLocation.y - lastPaintPosition.y; 780 boolean canBlit = computeBlit(dx, dy, blitFrom, blitTo, blitSize, blitPaint); 781 if (!canBlit) { 782 paintViaBackingStore(g); 785 } else { 786 int bdx = blitTo.x - blitFrom.x; 787 int bdy = blitTo.y - blitFrom.y; 788 789 Rectangle clip = g.getClipBounds(); 791 g.setClip(0, 0, width, height); 796 Graphics bsg = getBackingStoreGraphics(g); 797 try { 798 bsg.copyArea(blitFrom.x, blitFrom.y, blitSize.width, blitSize.height, bdx, bdy); 799 800 g.setClip(clip.x, clip.y, clip.width, clip.height); 801 Rectangle r = viewBounds.intersection(blitPaint); 803 bsg.setClip(r); 804 super.paint(bsg); 805 806 g.drawImage(backingStoreImage, 0, 0, this); 808 } finally { 809 bsg.dispose(); 810 } 811 } 812 } 813 } 814 lastPaintPosition = getViewLocation(); 815 scrollUnderway = false; 816 } 817 818 819 830 public void reshape(int x, int y, int w, int h) { 831 boolean sizeChanged = (getWidth() != w) || (getHeight() != h); 832 if (sizeChanged) { 833 backingStoreImage = null; 834 } 835 super.reshape(x, y, w, h); 836 if (sizeChanged) { 837 fireStateChanged(); 838 } 839 } 840 841 842 867 public void setScrollMode(int mode) { 868 scrollMode = mode; 869 if (mode == BACKINGSTORE_SCROLL_MODE) { 870 backingStore = true; 871 } else { 872 backingStore = false; 873 } 874 } 875 876 883 public int getScrollMode() { 884 return scrollMode; 885 } 886 887 897 @Deprecated 898 public boolean isBackingStoreEnabled() { 899 return scrollMode == BACKINGSTORE_SCROLL_MODE; 900 } 901 902 903 915 @Deprecated 916 public void setBackingStoreEnabled(boolean enabled) { 917 if (enabled) { 918 setScrollMode(BACKINGSTORE_SCROLL_MODE); 919 } else { 920 setScrollMode(BLIT_SCROLL_MODE); 921 } 922 } 923 924 private final boolean isBlitting() { 925 Component view = getView(); 926 return (scrollMode == BLIT_SCROLL_MODE) && 927 (view instanceof JComponent ) && ((JComponent )view).isOpaque(); 928 } 929 930 931 938 public Component getView() { 939 try { 940 return getComponent(0); 941 } catch (ArrayIndexOutOfBoundsException e) { 942 return null; 943 } 944 } 945 946 954 public void setView(Component view) { 955 956 960 int n = getComponentCount(); 961 for(int i = n - 1; i >= 0; i--) { 962 remove(getComponent(i)); 963 } 964 965 isViewSizeSet = false; 966 967 if (view != null) { 968 super.addImpl(view, null, -1); 969 viewListener = createViewListener(); 970 view.addComponentListener(viewListener); 971 } 972 973 if (hasHadValidView) { 974 fireStateChanged(); 976 } 977 else if (view != null) { 978 hasHadValidView = true; 979 } 980 981 revalidate(); 982 repaint(); 983 } 984 985 986 993 public Dimension getViewSize() { 994 Component view = getView(); 995 996 if (view == null) { 997 return new Dimension(0,0); 998 } 999 else if (isViewSizeSet) { 1000 return view.getSize(); 1001 } 1002 else { 1003 return view.getPreferredSize(); 1004 } 1005 } 1006 1007 1008 1014 public void setViewSize(Dimension newSize) { 1015 Component view = getView(); 1016 if (view != null) { 1017 Dimension oldSize = view.getSize(); 1018 if (!newSize.equals(oldSize)) { 1019 scrollUnderway = false; 1023 view.setSize(newSize); 1024 isViewSizeSet = true; 1025 fireStateChanged(); 1026 } 1027 } 1028 } 1029 1030 1036 public Point getViewPosition() { 1037 Component view = getView(); 1038 if (view != null) { 1039 Point p = view.getLocation(); 1040 p.x = -p.x; 1041 p.y = -p.y; 1042 return p; 1043 } 1044 else { 1045 return new Point(0,0); 1046 } 1047 } 1048 1049 1050 1056 public void setViewPosition(Point p) 1057 { 1058 Component view = getView(); 1059 if (view == null) { 1060 return; 1061 } 1062 1063 int oldX, oldY, x = p.x, y = p.y; 1064 1065 1069 if (view instanceof JComponent ) { 1070 JComponent c = (JComponent )view; 1071 oldX = c.getX(); 1072 oldY = c.getY(); 1073 } 1074 else { 1075 Rectangle r = view.getBounds(); 1076 oldX = r.x; 1077 oldY = r.y; 1078 } 1079 1080 1083 int newX = -x; 1084 int newY = -y; 1085 1086 if ((oldX != newX) || (oldY != newY)) { 1087 if (!waitingForRepaint && isBlitting() && canUseWindowBlitter()) { 1088 Graphics g = getGraphics(); 1089 flushViewDirtyRegion(g); 1090 view.setLocation(newX, newY); 1092 g.setClip(0,0,getWidth(), Math.min(getHeight(), 1095 ((JComponent )view).getHeight())); 1096 repaintAll = (windowBlitPaint(g) && 1099 needsRepaintAfterBlit()); 1100 g.dispose(); 1101 RepaintManager rm = RepaintManager.currentManager(this); 1102 rm.markCompletelyClean((JComponent )getParent()); 1103 rm.markCompletelyClean(this); 1104 rm.markCompletelyClean((JComponent )view); 1105 } 1106 else { 1107 scrollUnderway = true; 1108 view.setLocation(newX, newY); 1110 repaintAll = false; 1111 } 1112 fireStateChanged(); 1113 } 1114 } 1115 1116 1117 1125 public Rectangle getViewRect() { 1126 return new Rectangle(getViewPosition(), getExtentSize()); 1127 } 1128 1129 1130 1146 protected boolean computeBlit( 1147 int dx, 1148 int dy, 1149 Point blitFrom, 1150 Point blitTo, 1151 Dimension blitSize, 1152 Rectangle blitPaint) 1153 { 1154 int dxAbs = Math.abs(dx); 1155 int dyAbs = Math.abs(dy); 1156 Dimension extentSize = getExtentSize(); 1157 1158 if ((dx == 0) && (dy != 0) && (dyAbs < extentSize.height)) { 1159 if (dy < 0) { 1160 blitFrom.y = -dy; 1161 blitTo.y = 0; 1162 blitPaint.y = extentSize.height + dy; 1163 } 1164 else { 1165 blitFrom.y = 0; 1166 blitTo.y = dy; 1167 blitPaint.y = 0; 1168 } 1169 1170 blitPaint.x = blitFrom.x = blitTo.x = 0; 1171 1172 blitSize.width = extentSize.width; 1173 blitSize.height = extentSize.height - dyAbs; 1174 1175 blitPaint.width = extentSize.width; 1176 blitPaint.height = dyAbs; 1177 1178 return true; 1179 } 1180 1181 else if ((dy == 0) && (dx != 0) && (dxAbs < extentSize.width)) { 1182 if (dx < 0) { 1183 blitFrom.x = -dx; 1184 blitTo.x = 0; 1185 blitPaint.x = extentSize.width + dx; 1186 } 1187 else { 1188 blitFrom.x = 0; 1189 blitTo.x = dx; 1190 blitPaint.x = 0; 1191 } 1192 1193 blitPaint.y = blitFrom.y = blitTo.y = 0; 1194 1195 blitSize.width = extentSize.width - dxAbs; 1196 blitSize.height = extentSize.height; 1197 1198 blitPaint.y = 0; 1199 blitPaint.width = dxAbs; 1200 blitPaint.height = extentSize.height; 1201 1202 return true; 1203 } 1204 1205 else { 1206 return false; 1207 } 1208 } 1209 1210 1211 1216 public Dimension getExtentSize() { 1217 return getSize(); 1218 } 1219 1220 1221 1229 public Dimension toViewCoordinates(Dimension size) { 1230 return new Dimension(size); 1231 } 1232 1233 1241 public Point toViewCoordinates(Point p) { 1242 return new Point(p); 1243 } 1244 1245 1246 1252 public void setExtentSize(Dimension newExtent) { 1253 Dimension oldExtent = getExtentSize(); 1254 if (!newExtent.equals(oldExtent)) { 1255 setSize(newExtent); 1256 fireStateChanged(); 1257 } 1258 } 1259 1260 1272 protected class ViewListener extends ComponentAdapter implements Serializable 1273 { 1274 public void componentResized(ComponentEvent e) { 1275 fireStateChanged(); 1276 revalidate(); 1277 } 1278 } 1279 1280 1284 protected ViewListener createViewListener() { 1285 return new ViewListener(); 1286 } 1287 1288 1289 1296 protected LayoutManager createLayoutManager() { 1297 return ViewportLayout.SHARED_INSTANCE; 1298 } 1299 1300 1301 1312 public void addChangeListener(ChangeListener l) { 1313 listenerList.add(ChangeListener.class, l); 1314 } 1315 1316 1324 public void removeChangeListener(ChangeListener l) { 1325 listenerList.remove(ChangeListener.class, l); 1326 } 1327 1328 1336 public ChangeListener[] getChangeListeners() { 1337 return (ChangeListener[])listenerList.getListeners( 1338 ChangeListener.class); 1339 } 1340 1341 1349 protected void fireStateChanged() 1350 { 1351 Object [] listeners = listenerList.getListenerList(); 1352 for (int i = listeners.length - 2; i >= 0; i -= 2) { 1353 if (listeners[i] == ChangeListener.class) { 1354 if (changeEvent == null) { 1355 changeEvent = new ChangeEvent(this); 1356 } 1357 ((ChangeListener)listeners[i + 1]).stateChanged(changeEvent); 1358 } 1359 } 1360 } 1361 1362 1373 public void repaint(long tm, int x, int y, int w, int h) { 1374 Container parent = getParent(); 1375 if(parent != null) 1376 parent.repaint(tm,x+getX(),y+getY(),w,h); 1377 else 1378 super.repaint(tm,x,y,w,h); 1379 } 1380 1381 1382 1392 protected String paramString() { 1393 String isViewSizeSetString = (isViewSizeSet ? 1394 "true" : "false"); 1395 String lastPaintPositionString = (lastPaintPosition != null ? 1396 lastPaintPosition.toString() : ""); 1397 String scrollUnderwayString = (scrollUnderway ? 1398 "true" : "false"); 1399 1400 return super.paramString() + 1401 ",isViewSizeSet=" + isViewSizeSetString + 1402 ",lastPaintPosition=" + lastPaintPositionString + 1403 ",scrollUnderway=" + scrollUnderwayString; 1404 } 1405 1406 1410 1419 protected void firePropertyChange(String propertyName, Object oldValue, 1420 Object newValue) { 1421 super.firePropertyChange(propertyName, oldValue, newValue); 1422 if (propertyName.equals(EnableWindowBlit)) { 1423 if (newValue != null) { 1424 setScrollMode(BLIT_SCROLL_MODE); 1425 } else { 1426 setScrollMode(SIMPLE_SCROLL_MODE); 1427 } 1428 } 1429 } 1430 1431 1435 private boolean needsRepaintAfterBlit() { 1436 Component heavyParent = getParent(); 1439 1440 while (heavyParent != null && heavyParent.isLightweight()) { 1441 heavyParent = heavyParent.getParent(); 1442 } 1443 1444 if (heavyParent != null) { 1445 ComponentPeer peer = heavyParent.getPeer(); 1446 1447 if (peer != null && peer.canDetermineObscurity() && 1448 !peer.isObscured()) { 1449 return false; 1456 } 1457 } 1458 return true; 1459 } 1460 1461 private Timer createRepaintTimer() { 1462 Timer timer = new Timer (300, new ActionListener() { 1463 public void actionPerformed(ActionEvent ae) { 1464 if (waitingForRepaint) { 1468 repaint(); 1469 } 1470 } 1471 }); 1472 timer.setRepeats(false); 1473 return timer; 1474 } 1475 1476 1482 private void flushViewDirtyRegion(Graphics g) { 1483 RepaintManager rm = RepaintManager.currentManager(this); 1484 JComponent view = (JComponent ) getView(); 1485 Rectangle dirty; 1486 1487 dirty = rm.getDirtyRegion(view); 1488 if(dirty != null && dirty.width > 0 && dirty.height > 0) { 1489 dirty.x += view.getX(); 1490 dirty.y += view.getY(); 1491 Rectangle clip = g.getClipBounds(); 1492 if (clip == null) { 1493 g.setClip(0, 0, getWidth(), getHeight()); 1495 } 1496 g.clipRect(dirty.x, dirty.y, dirty.width, dirty.height); 1497 clip = g.getClipBounds(); 1498 if (clip.width > 0 && clip.height > 0) { 1500 paintView(g); 1501 } 1502 } 1503 } 1504 1505 1511 private boolean windowBlitPaint(Graphics g) { 1512 int width = getWidth(); 1513 int height = getHeight(); 1514 1515 if ((width == 0) || (height == 0)) { 1516 return false; 1517 } 1518 1519 boolean retValue; 1520 RepaintManager rm = RepaintManager.currentManager(this); 1521 JComponent view = (JComponent ) getView(); 1522 1523 if (lastPaintPosition == null || 1524 lastPaintPosition.equals(getViewLocation())) { 1525 paintView(g); 1526 retValue = false; 1527 } else { 1528 Point blitFrom = new Point(); 1531 Point blitTo = new Point(); 1532 Dimension blitSize = new Dimension(); 1533 Rectangle blitPaint = new Rectangle(); 1534 1535 Point newLocation = getViewLocation(); 1536 int dx = newLocation.x - lastPaintPosition.x; 1537 int dy = newLocation.y - lastPaintPosition.y; 1538 boolean canBlit = computeBlit(dx, dy, blitFrom, blitTo, blitSize, 1539 blitPaint); 1540 if (!canBlit) { 1541 paintView(g); 1542 retValue = false; 1543 } else { 1544 Rectangle r = view.getBounds().intersection(blitPaint); 1547 r.x -= view.getX(); 1548 r.y -= view.getY(); 1549 1550 boolean paintCompleted = false; 1555 Image off = null; 1556 if (rm.useVolatileDoubleBuffer() && 1557 (off = rm.getVolatileOffscreenBuffer(this,getWidth(),getHeight())) != null) { 1558 VolatileImage vImage = (java.awt.image.VolatileImage )off; 1559 GraphicsConfiguration gc = view.getGraphicsConfiguration(); 1560 for(int i = 0; !paintCompleted && i < RepaintManager.VOLATILE_LOOP_MAX; i++) { 1561 if (vImage.validate(gc) == 1562 VolatileImage.IMAGE_INCOMPATIBLE) 1563 { 1564 rm.resetVolatileDoubleBuffer(gc); 1565 off = rm.getVolatileOffscreenBuffer(this,getWidth(),getHeight()); 1566 vImage = (java.awt.image.VolatileImage )off; 1567 } 1568 blitDoubleBuffered(view, g, r.x, r.y, r.width, r.height, 1569 blitFrom.x, blitFrom.y, blitTo.x, blitTo.y, 1570 blitSize.width, blitSize.height, off); 1571 1572 paintCompleted = !(vImage.contentsLost()); 1573 } 1574 } 1575 if (!paintCompleted) { 1576 off = rm.getOffscreenBuffer(this, getWidth(), getHeight()); 1577 blitDoubleBuffered(view, g, r.x, r.y, r.width, r.height, 1578 blitFrom.x, blitFrom.y, blitTo.x, blitTo.y, 1579 blitSize.width, blitSize.height, off); 1580 paintCompleted = true; 1581 } 1582 retValue = true; 1583 } 1584 } 1585 lastPaintPosition = getViewLocation(); 1586 return retValue; 1587 } 1588 1589 private void blitDoubleBuffered(JComponent view, Graphics g, 1590 int clipX, int clipY, int clipW, int clipH, 1591 int blitFromX, int blitFromY, int blitToX, int blitToY, 1592 int blitW, int blitH, Image off) { 1593 RepaintManager rm = RepaintManager.currentManager(this); 1594 boolean isDBE = rm.isDoubleBufferingEnabled(); 1595 int bdx = blitToX - blitFromX; 1596 int bdy = blitToY - blitFromY; 1597 1598 Graphics og = off.getGraphics(); 1599 og.translate(-clipX,-clipY); 1600 og.setClip(clipX,clipY,clipW,clipH); 1601 rm.setDoubleBufferingEnabled(false); 1602 view.paint(og); 1603 rm.setDoubleBufferingEnabled(isDBE); 1604 1605 blitWindowGraphics(blitFromX, blitFromY, blitW, blitH, bdx, bdy); 1607 1608 clipX += view.getX(); 1609 clipY += view.getY(); 1610 g.setClip(clipX,clipY,clipW,clipH); 1611 g.drawImage(off,clipX,clipY,null); 1612 og.dispose(); 1613 } 1614 1615 1621 private void paintView(Graphics g) { 1622 Rectangle r = g.getClipBounds(); 1623 RepaintManager rm = RepaintManager.currentManager(this); 1624 JComponent view = (JComponent ) getView(); 1625 r.x -= view.getX(); 1626 r.y -= view.getY(); 1627 1628 boolean paintCompleted = false; 1633 Image off = null; 1634 if (rm.useVolatileDoubleBuffer() && 1635 (off = rm.getVolatileOffscreenBuffer(this,r.width,r.height)) != null) { 1636 VolatileImage vImage = (java.awt.image.VolatileImage )off; 1637 GraphicsConfiguration gc = view.getGraphicsConfiguration(); 1638 for(int i=0; !paintCompleted && i < RepaintManager.VOLATILE_LOOP_MAX; i++) { 1639 if (vImage.validate(gc) == 1640 VolatileImage.IMAGE_INCOMPATIBLE) 1641 { 1642 rm.resetVolatileDoubleBuffer(gc); 1643 off = rm.getVolatileOffscreenBuffer(this,getWidth(),getHeight()); 1644 vImage = (java.awt.image.VolatileImage )off; 1645 } 1646 paintViewDoubleBuffered(view, g, r.x, r.y, r.width, r.height, off); 1647 paintCompleted = !(vImage.contentsLost()); 1648 } 1649 } 1650 if (!paintCompleted) { 1651 off = rm.getOffscreenBuffer(this,r.width,r.height); 1652 paintViewDoubleBuffered(view, g, r.x, r.y, r.width, r.height, off); 1653 paintCompleted = true; 1654 } 1655 } 1656 1657 private void paintViewDoubleBuffered(JComponent view, Graphics g, 1658 int clipX, int clipY, int clipW, int clipH, Image off) { 1659 RepaintManager rm = RepaintManager.currentManager(this); 1660 boolean isDBE = rm.isDoubleBufferingEnabled(); 1661 1662 Graphics og = off.getGraphics(); 1663 if (view.getWidth() < clipW) { 1664 og.setColor(getBackground()); 1665 og.fillRect(0,0,clipW,clipH); 1666 } 1667 og.translate(-clipX, -clipY); 1668 og.setClip(clipX, clipY, clipW, clipH); 1669 rm.setDoubleBufferingEnabled(false); 1670 view.paint(og); 1671 rm.setDoubleBufferingEnabled(isDBE); 1672 g.drawImage(off, clipX + view.getX(), clipY + view.getY(), null); 1673 og.dispose(); 1674 } 1675 1676 1680 private void blitWindowGraphics(int x, int y, int w, int h, int ox, 1681 int oy) { 1682 Container parent; 1683 for(parent = getParent() ; isLightweightComponent(parent) ; 1684 parent = parent.getParent()); 1685 Graphics wg = parent.getGraphics(); 1686 Rectangle r = new Rectangle(x,y,w,h); 1687 r = SwingUtilities.convertRectangle(this, r, parent); 1688 wg.copyArea(r.x,r.y,r.width,r.height, ox, oy); 1689 wg.dispose(); 1690 } 1691 1692 1699 private boolean canUseWindowBlitter() { 1700 if (!isShowing() || (!(getParent() instanceof JComponent ) && 1701 !(getView() instanceof JComponent ))) { 1702 return false; 1703 } 1704 if (isPainting()) { 1705 return false; 1709 } 1710 1711 Rectangle dirtyRegion = RepaintManager.currentManager(this). 1712 getDirtyRegion((JComponent )getParent()); 1713 1714 if (dirtyRegion != null && dirtyRegion.width > 0 && 1715 dirtyRegion.height > 0) { 1716 return false; 1718 } 1719 1720 Rectangle clip = new Rectangle(0,0,getWidth(),getHeight()); 1721 Rectangle oldClip = new Rectangle(); 1722 Rectangle tmp2 = null; 1723 Container parent; 1724 Component lastParent = null; 1725 int x, y, w, h; 1726 1727 for(parent = this; parent != null && isLightweightComponent(parent); parent = parent.getParent()) { 1728 x = parent.getX(); 1729 y = parent.getY(); 1730 w = parent.getWidth(); 1731 h = parent.getHeight(); 1732 1733 oldClip.setBounds(clip); 1734 SwingUtilities.computeIntersection(0, 0, w, h, clip); 1735 if(!clip.equals(oldClip)) 1736 return false; 1737 1738 if(lastParent != null && parent instanceof JComponent && 1739 !((JComponent )parent).isOptimizedDrawingEnabled()) { 1740 Component comps[] = parent.getComponents(); 1741 int index = 0; 1742 1743 for(int i = comps.length - 1 ;i >= 0; i--) { 1744 if(comps[i] == lastParent) { 1745 index = i - 1; 1746 break; 1747 } 1748 } 1749 1750 while(index >= 0) { 1751 tmp2 = comps[index].getBounds(tmp2); 1752 1753 if(tmp2.intersects(clip)) 1754 return false; 1755 index--; 1756 } 1757 } 1758 clip.x += x; 1759 clip.y += y; 1760 lastParent = parent; 1761 } 1762 if (parent == null) { 1763 return false; 1765 } 1766 return true; 1767 } 1768 1769 1770 1774 1783 public AccessibleContext getAccessibleContext() { 1784 if (accessibleContext == null) { 1785 accessibleContext = new AccessibleJViewport(); 1786 } 1787 return accessibleContext; 1788 } 1789 1790 1804 protected class AccessibleJViewport extends AccessibleJComponent { 1805 1811 public AccessibleRole getAccessibleRole() { 1812 return AccessibleRole.VIEWPORT; 1813 } 1814 } } 1816 | Popular Tags |