| 1 7 package javax.swing; 8 9 import java.awt.Component ; 10 import java.awt.Container ; 11 import java.awt.Dimension ; 12 import java.awt.Insets ; 13 import java.awt.LayoutManager2 ; 14 import java.util.*; 15 import static java.awt.Component.BaselineResizeBehavior ; 16 import static javax.swing.LayoutStyle.ComponentPlacement ; 17 import static javax.swing.SwingConstants.HORIZONTAL ; 18 import static javax.swing.SwingConstants.VERTICAL ; 19 20 191 public class GroupLayout implements LayoutManager2 { 192 private static final int MIN_SIZE = 0; 194 195 private static final int PREF_SIZE = 1; 196 197 private static final int MAX_SIZE = 2; 198 199 private static final int SPECIFIC_SIZE = 3; 201 202 private static final int UNSET = Integer.MIN_VALUE; 203 204 210 public static final int DEFAULT_SIZE = -1; 211 212 218 public static final int PREFERRED_SIZE = -2; 219 220 private boolean autocreatePadding; 223 224 private boolean autocreateContainerPadding; 228 229 233 private Group horizontalGroup; 234 235 239 private Group verticalGroup; 240 241 private Map<Component ,ComponentInfo> componentInfos; 244 245 private Container host; 247 248 private Set<Spring > tmpParallelSet; 250 251 private boolean springsChanged; 253 254 private boolean isValid; 256 257 private boolean hasPreferredPaddingSprings; 260 261 264 private LayoutStyle layoutStyle; 265 266 270 private boolean honorsVisibility; 271 272 273 280 public enum Alignment { 281 289 LEADING, 290 291 299 TRAILING, 300 301 307 CENTER, 308 309 316 BASELINE 317 } 318 319 320 private static void checkSize(int min, int pref, int max, 321 boolean isComponentSpring) { 322 checkResizeType(min, isComponentSpring); 323 if (!isComponentSpring && pref < 0) { 324 throw new IllegalArgumentException ("Pref must be >= 0"); 325 } else if (isComponentSpring) { 326 checkResizeType(pref, true); 327 } 328 checkResizeType(max, isComponentSpring); 329 checkLessThan(min, pref); 330 checkLessThan(pref, max); 331 } 332 333 private static void checkResizeType(int type, boolean isComponentSpring) { 334 if (type < 0 && ((isComponentSpring && type != DEFAULT_SIZE && 335 type != PREFERRED_SIZE) || 336 (!isComponentSpring && type != PREFERRED_SIZE))) { 337 throw new IllegalArgumentException ("Invalid size"); 338 } 339 } 340 341 private static void checkLessThan(int min, int max) { 342 if (min >= 0 && max >= 0 && min > max) { 343 throw new IllegalArgumentException ( 344 "Following is not met: min<=pref<=max"); 345 } 346 } 347 348 355 public GroupLayout(Container host) { 356 if (host == null) { 357 throw new IllegalArgumentException ("Container must be non-null"); 358 } 359 honorsVisibility = true; 360 this.host = host; 361 setHorizontalGroup(createParallelGroup(Alignment.LEADING, true)); 362 setVerticalGroup(createParallelGroup(Alignment.LEADING, true)); 363 componentInfos = new HashMap<Component ,ComponentInfo>(); 364 tmpParallelSet = new HashSet<Spring >(); 365 } 366 367 387 public void setHonorsVisibility(boolean honorsVisibility) { 388 if (this.honorsVisibility != honorsVisibility) { 389 this.honorsVisibility = honorsVisibility; 390 springsChanged = true; 391 isValid = false; 392 invalidateHost(); 393 } 394 } 395 396 403 public boolean getHonorsVisibility() { 404 return honorsVisibility; 405 } 406 407 427 public void setHonorsVisibility(Component component, 428 Boolean honorsVisibility) { 429 if (component == null) { 430 throw new IllegalArgumentException ("Component must be non-null"); 431 } 432 getComponentInfo(component).setHonorsVisibility(honorsVisibility); 433 springsChanged = true; 434 isValid = false; 435 invalidateHost(); 436 } 437 438 448 public void setAutoCreateGaps(boolean autoCreatePadding) { 449 if (this.autocreatePadding != autoCreatePadding) { 450 this.autocreatePadding = autoCreatePadding; 451 invalidateHost(); 452 } 453 } 454 455 462 public boolean getAutoCreateGaps() { 463 return autocreatePadding; 464 } 465 466 475 public void setAutoCreateContainerGaps(boolean autoCreateContainerPadding){ 476 if (this.autocreateContainerPadding != autoCreateContainerPadding) { 477 this.autocreateContainerPadding = autoCreateContainerPadding; 478 horizontalGroup = createTopLevelGroup(getHorizontalGroup()); 479 verticalGroup = createTopLevelGroup(getVerticalGroup()); 480 invalidateHost(); 481 } 482 } 483 484 491 public boolean getAutoCreateContainerGaps() { 492 return autocreateContainerPadding; 493 } 494 495 503 public void setHorizontalGroup(Group group) { 504 if (group == null) { 505 throw new IllegalArgumentException ("Group must be non-null"); 506 } 507 horizontalGroup = createTopLevelGroup(group); 508 invalidateHost(); 509 } 510 511 518 private Group getHorizontalGroup() { 519 int index = 0; 520 if (horizontalGroup.springs.size() > 1) { 521 index = 1; 522 } 523 return (Group)horizontalGroup.springs.get(index); 524 } 525 526 534 public void setVerticalGroup(Group group) { 535 if (group == null) { 536 throw new IllegalArgumentException ("Group must be non-null"); 537 } 538 verticalGroup = createTopLevelGroup(group); 539 invalidateHost(); 540 } 541 542 549 private Group getVerticalGroup() { 550 int index = 0; 551 if (verticalGroup.springs.size() > 1) { 552 index = 1; 553 } 554 return (Group)verticalGroup.springs.get(index); 555 } 556 557 562 private Group createTopLevelGroup(Group specifiedGroup) { 563 SequentialGroup group = createSequentialGroup(); 564 if (getAutoCreateContainerGaps()) { 565 group.addSpring(new ContainerAutoPreferredGapSpring()); 566 group.addGroup(specifiedGroup); 567 group.addSpring(new ContainerAutoPreferredGapSpring()); 568 } else { 569 group.addGroup(specifiedGroup); 570 } 571 return group; 572 } 573 574 579 public SequentialGroup createSequentialGroup() { 580 return new SequentialGroup(); 581 } 582 583 591 public ParallelGroup createParallelGroup() { 592 return createParallelGroup(Alignment.LEADING); 593 } 594 595 607 public ParallelGroup createParallelGroup(Alignment alignment) { 608 return createParallelGroup(alignment, true); 609 } 610 611 637 public ParallelGroup createParallelGroup(Alignment alignment, 638 boolean resizable){ 639 if (alignment == Alignment.BASELINE) { 640 return new BaselineGroup(resizable); 641 } 642 return new ParallelGroup(alignment, resizable); 643 } 644 645 655 public ParallelGroup createBaselineGroup(boolean resizable, 656 boolean anchorBaselineToTop) { 657 return new BaselineGroup(resizable, anchorBaselineToTop); 658 } 659 660 677 public void linkSize(Component ... components) { 678 linkSize(SwingConstants.HORIZONTAL, components); 679 linkSize(SwingConstants.VERTICAL, components); 680 } 681 682 705 public void linkSize(int axis, Component ... components) { 706 if (components == null) { 707 throw new IllegalArgumentException ("Components must be non-null"); 708 } 709 for (int counter = components.length - 1; counter >= 0; counter--) { 710 Component c = components[counter]; 711 if (components[counter] == null) { 712 throw new IllegalArgumentException ( 713 "Components must be non-null"); 714 } 715 getComponentInfo(c); 717 } 718 int glAxis; 719 if (axis == SwingConstants.HORIZONTAL) { 720 glAxis = HORIZONTAL; 721 } else if (axis == SwingConstants.VERTICAL) { 722 glAxis = VERTICAL; 723 } else { 724 throw new IllegalArgumentException ("Axis must be one of " + 725 "SwingConstants.HORIZONTAL or SwingConstants.VERTICAL"); 726 } 727 LinkInfo master = getComponentInfo( 728 components[components.length - 1]).getLinkInfo(glAxis); 729 for (int counter = components.length - 2; counter >= 0; counter--) { 730 master.add(getComponentInfo(components[counter])); 731 } 732 invalidateHost(); 733 } 734 735 746 public void replace(Component existingComponent, Component newComponent) { 747 if (existingComponent == null || newComponent == null) { 748 throw new IllegalArgumentException ("Components must be non-null"); 749 } 750 if (springsChanged) { 753 registerComponents(horizontalGroup, HORIZONTAL); 754 registerComponents(verticalGroup, VERTICAL); 755 } 756 ComponentInfo info = componentInfos.remove(existingComponent); 757 if (info == null) { 758 throw new IllegalArgumentException ("Component must already exist"); 759 } 760 host.remove(existingComponent); 761 if (newComponent.getParent() != host) { 762 host.add(newComponent); 763 } 764 info.setComponent(newComponent); 765 componentInfos.put(newComponent, info); 766 invalidateHost(); 767 } 768 769 777 public void setLayoutStyle(LayoutStyle layoutStyle) { 778 this.layoutStyle = layoutStyle; 779 invalidateHost(); 780 } 781 782 790 public LayoutStyle getLayoutStyle() { 791 return layoutStyle; 792 } 793 794 private LayoutStyle getLayoutStyle0() { 795 LayoutStyle layoutStyle = getLayoutStyle(); 796 if (layoutStyle == null) { 797 layoutStyle = LayoutStyle.getInstance(); 798 } 799 return layoutStyle; 800 } 801 802 private void invalidateHost() { 803 if (host instanceof JComponent ) { 804 ((JComponent )host).revalidate(); 805 } else { 806 host.invalidate(); 807 } 808 host.repaint(); 809 } 810 811 823 public void addLayoutComponent(String name, Component component) { 824 } 825 826 835 public void removeLayoutComponent(Component component) { 836 ComponentInfo info = componentInfos.remove(component); 837 if (info != null) { 838 info.dispose(); 839 springsChanged = true; 840 isValid = false; 841 } 842 } 843 844 855 public Dimension preferredLayoutSize(Container parent) { 856 checkParent(parent); 857 prepare(PREF_SIZE); 858 return adjustSize(horizontalGroup.getPreferredSize(HORIZONTAL), 859 verticalGroup.getPreferredSize(VERTICAL)); 860 } 861 862 873 public Dimension minimumLayoutSize(Container parent) { 874 checkParent(parent); 875 prepare(MIN_SIZE); 876 return adjustSize(horizontalGroup.getMinimumSize(HORIZONTAL), 877 verticalGroup.getMinimumSize(VERTICAL)); 878 } 879 880 887 public void layoutContainer(Container parent) { 888 prepare(SPECIFIC_SIZE); 890 Insets insets = parent.getInsets(); 891 int width = parent.getWidth() - insets.left - insets.right; 892 int height = parent.getHeight() - insets.top - insets.bottom; 893 boolean ltr = isLeftToRight(); 894 if (getAutoCreateGaps() || getAutoCreateContainerGaps() || 895 hasPreferredPaddingSprings) { 896 calculateAutopadding(horizontalGroup, HORIZONTAL, SPECIFIC_SIZE, 0, 898 width); 899 calculateAutopadding(verticalGroup, VERTICAL, SPECIFIC_SIZE, 0, 900 height); 901 } 902 horizontalGroup.setSize(HORIZONTAL, 0, width); 904 verticalGroup.setSize(VERTICAL, 0, height); 905 for (ComponentInfo info : componentInfos.values()) { 907 info.setBounds(insets, width, ltr); 908 } 909 } 910 911 923 public void addLayoutComponent(Component component, Object constraints) { 924 } 925 926 937 public Dimension maximumLayoutSize(Container parent) { 938 checkParent(parent); 939 prepare(MAX_SIZE); 940 return adjustSize(horizontalGroup.getMaximumSize(HORIZONTAL), 941 verticalGroup.getMaximumSize(VERTICAL)); 942 } 943 944 956 public float getLayoutAlignmentX(Container parent) { 957 checkParent(parent); 958 return .5f; 959 } 960 961 973 public float getLayoutAlignmentY(Container parent) { 974 checkParent(parent); 975 return .5f; 976 } 977 978 |