1 7 8 package javax.swing; 9 10 11 import javax.swing.border.*; 12 13 import java.awt.LayoutManager ; 14 import java.awt.Component ; 15 import java.awt.Container ; 16 import java.awt.Rectangle ; 17 import java.awt.Dimension ; 18 import java.awt.Insets ; 19 import java.io.Serializable ; 20 21 22 43 public class ScrollPaneLayout 44 implements LayoutManager , ScrollPaneConstants , Serializable 45 { 46 47 52 protected JViewport viewport; 53 54 55 60 protected JScrollBar vsb; 61 62 63 68 protected JScrollBar hsb; 69 70 71 75 protected JViewport rowHead; 76 77 78 82 protected JViewport colHead; 83 84 85 90 protected Component lowerLeft; 91 92 93 98 protected Component lowerRight; 99 100 101 106 protected Component upperLeft; 107 108 109 114 protected Component upperRight; 115 116 117 125 protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED; 126 127 128 136 protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED; 137 138 139 154 public void syncWithScrollPane(JScrollPane sp) { 155 viewport = sp.getViewport(); 156 vsb = sp.getVerticalScrollBar(); 157 hsb = sp.getHorizontalScrollBar(); 158 rowHead = sp.getRowHeader(); 159 colHead = sp.getColumnHeader(); 160 lowerLeft = sp.getCorner(LOWER_LEFT_CORNER); 161 lowerRight = sp.getCorner(LOWER_RIGHT_CORNER); 162 upperLeft = sp.getCorner(UPPER_LEFT_CORNER); 163 upperRight = sp.getCorner(UPPER_RIGHT_CORNER); 164 vsbPolicy = sp.getVerticalScrollBarPolicy(); 165 hsbPolicy = sp.getHorizontalScrollBarPolicy(); 166 } 167 168 169 182 protected Component addSingletonComponent(Component oldC, Component newC) 183 { 184 if ((oldC != null) && (oldC != newC)) { 185 oldC.getParent().remove(oldC); 186 } 187 return newC; 188 } 189 190 191 210 public void addLayoutComponent(String s, Component c) 211 { 212 if (s.equals(VIEWPORT)) { 213 viewport = (JViewport )addSingletonComponent(viewport, c); 214 } 215 else if (s.equals(VERTICAL_SCROLLBAR)) { 216 vsb = (JScrollBar )addSingletonComponent(vsb, c); 217 } 218 else if (s.equals(HORIZONTAL_SCROLLBAR)) { 219 hsb = (JScrollBar )addSingletonComponent(hsb, c); 220 } 221 else if (s.equals(ROW_HEADER)) { 222 rowHead = (JViewport )addSingletonComponent(rowHead, c); 223 } 224 else if (s.equals(COLUMN_HEADER)) { 225 colHead = (JViewport )addSingletonComponent(colHead, c); 226 } 227 else if (s.equals(LOWER_LEFT_CORNER)) { 228 lowerLeft = addSingletonComponent(lowerLeft, c); 229 } 230 else if (s.equals(LOWER_RIGHT_CORNER)) { 231 lowerRight = addSingletonComponent(lowerRight, c); 232 } 233 else if (s.equals(UPPER_LEFT_CORNER)) { 234 upperLeft = addSingletonComponent(upperLeft, c); 235 } 236 else if (s.equals(UPPER_RIGHT_CORNER)) { 237 upperRight = addSingletonComponent(upperRight, c); 238 } 239 else { 240 throw new IllegalArgumentException ("invalid layout key " + s); 241 } 242 } 243 244 245 250 public void removeLayoutComponent(Component c) 251 { 252 if (c == viewport) { 253 viewport = null; 254 } 255 else if (c == vsb) { 256 vsb = null; 257 } 258 else if (c == hsb) { 259 hsb = null; 260 } 261 else if (c == rowHead) { 262 rowHead = null; 263 } 264 else if (c == colHead) { 265 colHead = null; 266 } 267 else if (c == lowerLeft) { 268 lowerLeft = null; 269 } 270 else if (c == lowerRight) { 271 lowerRight = null; 272 } 273 else if (c == upperLeft) { 274 upperLeft = null; 275 } 276 else if (c == upperRight) { 277 upperRight = null; 278 } 279 } 280 281 282 288 public int getVerticalScrollBarPolicy() { 289 return vsbPolicy; 290 } 291 292 293 309 public void setVerticalScrollBarPolicy(int x) { 310 switch (x) { 311 case VERTICAL_SCROLLBAR_AS_NEEDED: 312 case VERTICAL_SCROLLBAR_NEVER: 313 case VERTICAL_SCROLLBAR_ALWAYS: 314 vsbPolicy = x; 315 break; 316 default: 317 throw new IllegalArgumentException ("invalid verticalScrollBarPolicy"); 318 } 319 } 320 321 322 328 public int getHorizontalScrollBarPolicy() { 329 return hsbPolicy; 330 } 331 332 347 public void setHorizontalScrollBarPolicy(int x) { 348 switch (x) { 349 case HORIZONTAL_SCROLLBAR_AS_NEEDED: 350 case HORIZONTAL_SCROLLBAR_NEVER: 351 case HORIZONTAL_SCROLLBAR_ALWAYS: 352 hsbPolicy = x; 353 break; 354 default: 355 throw new IllegalArgumentException ("invalid horizontalScrollBarPolicy"); 356 } 357 } 358 359 360 366 public JViewport getViewport() { 367 return viewport; 368 } 369 370 371 376 public JScrollBar getHorizontalScrollBar() { 377 return hsb; 378 } 379 380 385 public JScrollBar getVerticalScrollBar() { 386 return vsb; 387 } 388 389 390 395 public JViewport getRowHeader() { 396 return rowHead; 397 } 398 399 400 405 public JViewport getColumnHeader() { 406 return colHead; 407 } 408 409 410 418 public Component getCorner(String key) { 419 if (key.equals(LOWER_LEFT_CORNER)) { 420 return lowerLeft; 421 } 422 else if (key.equals(LOWER_RIGHT_CORNER)) { 423 return lowerRight; 424 } 425 else if (key.equals(UPPER_LEFT_CORNER)) { 426 return upperLeft; 427 } 428 else if (key.equals(UPPER_RIGHT_CORNER)) { 429 return upperRight; 430 } 431 else { 432 return null; 433 } 434 } 435 436 437 452 public Dimension preferredLayoutSize(Container parent) 453 { 454 457 JScrollPane scrollPane = (JScrollPane )parent; 458 vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); 459 hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); 460 461 Insets insets = parent.getInsets(); 462 int prefWidth = insets.left + insets.right; 463 int prefHeight = insets.top + insets.bottom; 464 465 469 470 Dimension extentSize = null; 471 Dimension viewSize = null; 472 Component view = null; 473 474 if (viewport != null) { 475 extentSize = viewport.getPreferredSize(); 476 viewSize = viewport.getViewSize(); 477 view = viewport.getView(); 478 } 479 480 482 483 if (extentSize != null) { 484 prefWidth += extentSize.width; 485 prefHeight += extentSize.height; 486 } 487 488 490 491 Border viewportBorder = scrollPane.getViewportBorder(); 492 if (viewportBorder != null) { 493 Insets vpbInsets = viewportBorder.getBorderInsets(parent); 494 prefWidth += vpbInsets.left + vpbInsets.right; 495 prefHeight += vpbInsets.top + vpbInsets.bottom; 496 } 497 498 501 502 if ((rowHead != null) && rowHead.isVisible()) { 503 prefWidth += rowHead.getPreferredSize().width; 504 } 505 506 if ((colHead != null) && colHead.isVisible()) { 507 prefHeight += colHead.getPreferredSize().height; 508 } 509 510 526 527 if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { 528 if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { 529 prefWidth += vsb.getPreferredSize().width; 530 } 531 else if ((viewSize != null) && (extentSize != null)) { 532 boolean canScroll = true; 533 if (view instanceof Scrollable ) { 534 canScroll = !((Scrollable )view).getScrollableTracksViewportHeight(); 535 } 536 if (canScroll && (viewSize.height > extentSize.height)) { 537 prefWidth += vsb.getPreferredSize().width; 538 } 539 } 540 } 541 542 if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) { 543 if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { 544 prefHeight += hsb.getPreferredSize().height; 545 } 546 else if ((viewSize != null) && (extentSize != null)) { 547 boolean canScroll = true; 548 if (view instanceof Scrollable ) { 549 canScroll = !((Scrollable )view).getScrollableTracksViewportWidth(); 550 } 551 if (canScroll && (viewSize.width > extentSize.width)) { 552 prefHeight += hsb.getPreferredSize().height; 553 } 554 } 555 } 556 557 return new Dimension (prefWidth, prefHeight); 558 } 559 560 561 571 public Dimension minimumLayoutSize(Container parent) 572 { 573 576 JScrollPane scrollPane = (JScrollPane )parent; 577 vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); 578 hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); 579 580 Insets insets = parent.getInsets(); 581 int minWidth = insets.left + insets.right; 582 int minHeight = insets.top + insets.bottom; 583 584 586 587 if (viewport != null) { 588 Dimension size = viewport.getMinimumSize(); 589 minWidth += size.width; 590 minHeight += size.height; 591 } 592 593 595 596 Border viewportBorder = scrollPane.getViewportBorder(); 597 if (viewportBorder != null) { 598 Insets vpbInsets = viewportBorder.getBorderInsets(parent); 599 minWidth += vpbInsets.left + vpbInsets.right; 600 minHeight += vpbInsets.top + vpbInsets.bottom; 601 } 602 603 606 607 if ((rowHead != null) && rowHead.isVisible()) { 608 Dimension size = rowHead.getMinimumSize(); 609 minWidth += size.width; 610 minHeight = Math.max(minHeight, size.height); 611 } 612 613 if ((colHead != null) && colHead.isVisible()) { 614 Dimension size = colHead.getMinimumSize(); 615 minWidth = Math.max(minWidth, size.width); 616 minHeight += size.height; 617 } 618 619 622 623 if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { 624 Dimension size = vsb.getMinimumSize(); 625 minWidth += size.width; 626 minHeight = Math.max(minHeight, size.height); 627 } 628 629 if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) { 630 Dimension size = hsb.getMinimumSize(); 631 minWidth = Math.max(minWidth, size.width); 632 minHeight += size.height; 633 } 634 635 return new Dimension (minWidth, minHeight); 636 } 637 638 639 672 public void layoutContainer(Container parent) 673 { 674 677 JScrollPane scrollPane = (JScrollPane )parent; 678 vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); 679 hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); 680 681 Rectangle availR = scrollPane.getBounds(); 682 availR.x = availR.y = 0; 683 684 Insets insets = parent.getInsets(); 685 availR.x = insets.left; 686 availR.y = insets.top; 687 availR.width -= insets.left + insets.right; 688 availR.height -= insets.top + insets.bottom; 689 690 692 boolean leftToRight = SwingUtilities.isLeftToRight(scrollPane); 693 694 698 699 Rectangle colHeadR = new Rectangle (0, availR.y, 0, 0); 700 701 if ((colHead != null) && (colHead.isVisible())) { 702 int colHeadHeight = Math.min(availR.height, 703 colHead.getPreferredSize().height); 704 colHeadR.height = colHeadHeight; 705 availR.y += colHeadHeight; 706 availR.height -= colHeadHeight; 707 } 708 709 713 714 Rectangle rowHeadR = new Rectangle (0, 0, 0, 0); 715 716 if ((rowHead != null) && (rowHead.isVisible())) { 717 int rowHeadWidth = Math.min(availR.width, 718 rowHead.getPreferredSize().width); 719 rowHeadR.width = rowHeadWidth; 720 availR.width -= rowHeadWidth; 721 if ( leftToRight ) { 722 rowHeadR.x = availR.x; 723 availR.x += rowHeadWidth; 724 } else { 725 rowHeadR.x = availR.x + availR.width; 726 } 727 } 728 729 732 733 Border viewportBorder = scrollPane.getViewportBorder(); 734 Insets vpbInsets; 735 if (viewportBorder != null) { 736 vpbInsets = viewportBorder.getBorderInsets(parent); 737 availR.x += vpbInsets.left; 738 availR.y += vpbInsets.top; 739 availR.width -= vpbInsets.left + vpbInsets.right; 740 availR.height -= vpbInsets.top + vpbInsets.bottom; 741 } 742 else { 743 vpbInsets = new Insets (0,0,0,0); 744 } 745 746 747 767 768 Component view = (viewport != null) ? viewport.getView() : null; 769 Dimension viewPrefSize = 770 (view != null) ? view.getPreferredSize() 771 : new Dimension (0,0); 772 773 Dimension extentSize = 774 (viewport != null) ? viewport.toViewCoordinates(availR.getSize()) 775 : new Dimension (0,0); 776 777 boolean viewTracksViewportWidth = false; 778 boolean viewTracksViewportHeight = false; 779 boolean isEmpty = (availR.width < 0 || availR.height < 0); 780 Scrollable sv; 781 if (!isEmpty && view instanceof Scrollable ) { 785 sv = (Scrollable )view; 786 viewTracksViewportWidth = sv.getScrollableTracksViewportWidth(); 787 viewTracksViewportHeight = sv.getScrollableTracksViewportHeight(); 788 } 789 else { 790 sv = null; 791 } 792 793 797 798 Rectangle vsbR = new Rectangle (0, availR.y - vpbInsets.top, 0, 0); 799 800 boolean vsbNeeded; 801 if (isEmpty) { 802 vsbNeeded = false; 803 } 804 else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { 805 vsbNeeded = true; 806 } 807 else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) { 808 vsbNeeded = false; 809 } 810 else { vsbNeeded = !viewTracksViewportHeight && (viewPrefSize.height > extentSize.height); 812 } 813 814 815 if ((vsb != null) && vsbNeeded) { 816 adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); 817 extentSize = viewport.toViewCoordinates(availR.getSize()); 818 } 819 820 824 825 Rectangle hsbR = new Rectangle (availR.x - vpbInsets.left, 0, 0, 0); 826 boolean hsbNeeded; 827 if (isEmpty) { 828 hsbNeeded = false; 829 } 830 else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { 831 hsbNeeded = true; 832 } 833 else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) { 834 hsbNeeded = false; 835 } 836 else { hsbNeeded = !viewTracksViewportWidth && (viewPrefSize.width > extentSize.width); 838 } 839 840 if ((hsb != null) && hsbNeeded) { 841 adjustForHSB(true, availR, hsbR, vpbInsets); 842 843 849 if ((vsb != null) && !vsbNeeded && 850 (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { 851 852 extentSize = viewport.toViewCoordinates(availR.getSize()); 853 vsbNeeded = viewPrefSize.height > extentSize.height; 854 855 if (vsbNeeded) { 856 adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); 857 } 858 } 859 } 860 861 867 868 if (viewport != null) { 869 viewport.setBounds(availR); 870 871 if (sv != null) { 872 extentSize = viewport.toViewCoordinates(availR.getSize()); 873 874 boolean oldHSBNeeded = hsbNeeded; 875 boolean oldVSBNeeded = vsbNeeded; 876 viewTracksViewportWidth = sv. 877 getScrollableTracksViewportWidth(); 878 viewTracksViewportHeight = sv. 879 getScrollableTracksViewportHeight(); 880 if (vsb != null && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) { 881 boolean newVSBNeeded = !viewTracksViewportHeight && 882 (viewPrefSize.height > extentSize.height); 883 if (newVSBNeeded != vsbNeeded) { 884 vsbNeeded = newVSBNeeded; 885 adjustForVSB(vsbNeeded, availR, vsbR, vpbInsets, 886 leftToRight); 887 extentSize = viewport.toViewCoordinates 888 (availR.getSize()); 889 } 890 } 891 if (hsb != null && hsbPolicy ==HORIZONTAL_SCROLLBAR_AS_NEEDED){ 892 boolean newHSBbNeeded = !viewTracksViewportWidth && 893 (viewPrefSize.width > extentSize.width); 894 if (newHSBbNeeded != hsbNeeded) { 895 hsbNeeded = newHSBbNeeded; 896 adjustForHSB(hsbNeeded, availR, hsbR, vpbInsets); 897 if ((vsb != null) && !vsbNeeded && 898 (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { 899 900 extentSize = viewport.toViewCoordinates 901 (availR.getSize()); 902 vsbNeeded = viewPrefSize.height > 903 extentSize.height; 904 905 if (vsbNeeded) { 906 adjustForVSB(true, availR, vsbR, vpbInsets, 907 leftToRight); 908 } 909 } 910 } 911 } 912 if (oldHSBNeeded != hsbNeeded || 913 oldVSBNeeded != vsbNeeded) { 914 viewport.setBounds(availR); 915 } 920 } 921 } 922 923 926 vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom; 927 hsbR.width = availR.width + vpbInsets.left + vpbInsets.right; 928 rowHeadR.height = availR.height + vpbInsets.top + vpbInsets.bottom; 929 rowHeadR.y = availR.y - vpbInsets.top; 930 colHeadR.width = availR.width + vpbInsets.left + vpbInsets.right; 931 colHeadR.x = availR.x - vpbInsets.left; 932 933 936 937 if (rowHead != null) { 938 rowHead.setBounds(rowHeadR); 939 } 940 941 if (colHead != null) { 942 colHead.setBounds(colHeadR); 943 } 944 945 if (vsb != null) { 946 if (vsbNeeded) { 947 vsb.setVisible(true); 948 vsb.setBounds(vsbR); 949 } 950 else { 951 vsb.setVisible(false); 952 } 953 } 954 955 if (hsb != null) { 956 if (hsbNeeded) { 957 hsb.setVisible(true); 958 hsb.setBounds(hsbR); 959 } 960 else { 961 hsb.setVisible(false); 962 } 963 } 964 965 if (lowerLeft != null) { 966 lowerLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, 967 hsbR.y, 968 leftToRight ? rowHeadR.width : vsbR.width, 969 hsbR.height); 970 } 971 972 if (lowerRight != null) { 973 lowerRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, 974 hsbR.y, 975 leftToRight ? vsbR.width : rowHeadR.width, 976 hsbR.height); 977 } 978 979 if (upperLeft != null) { 980 upperLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, 981 colHeadR.y, 982 leftToRight ? rowHeadR.width : vsbR.width, 983 colHeadR.height); 984 } 985 986 if (upperRight != null) { 987 upperRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, 988 colHeadR.y, 989 leftToRight ? vsbR.width : rowHeadR.width, 990 colHeadR.height); 991 } 992 } 993 994 1002 private void adjustForVSB(boolean wantsVSB, Rectangle available, 1003 Rectangle vsbR, Insets vpbInsets, 1004 boolean leftToRight) { 1005 int oldWidth = vsbR.width; 1006 if (wantsVSB) { 1007 int vsbWidth = Math.max(0, Math.min(vsb.getPreferredSize().width, 1008 available.width)); 1009 1010 available.width -= vsbWidth; 1011 vsbR.width = vsbWidth; 1012 1013 if( leftToRight ) { 1014 vsbR.x = available.x + available.width + vpbInsets.right; 1015 } else { 1016 vsbR.x = available.x - vpbInsets.left; 1017 available.x += vsbWidth; 1018 } 1019 } 1020 else { 1021 available.width += oldWidth; 1022 } 1023 } 1024 1025 1033 private void adjustForHSB(boolean wantsHSB, Rectangle available, 1034 Rectangle hsbR, Insets vpbInsets) { 1035 int oldHeight = hsbR.height; 1036 if (wantsHSB) { 1037 int hsbHeight = Math.max(0, Math.min(available.height, 1038 hsb.getPreferredSize().height)); 1039 1040 available.height -= hsbHeight; 1041 hsbR.y = available.y + available.height + vpbInsets.bottom; 1042 hsbR.height = hsbHeight; 1043 } 1044 else { 1045 available.height += oldHeight; 1046 } 1047 } 1048 1049 1050 1051 1059 @Deprecated 1060 public Rectangle getViewportBorderBounds(JScrollPane scrollpane) { 1061 return scrollpane.getViewportBorderBounds(); 1062 } 1063 1064 1067 public static class UIResource extends ScrollPaneLayout implements javax.swing.plaf.UIResource {} 1068} 1069 | Popular Tags |