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 986 public void invalidateLayout(Container parent) { 987 checkParent(parent); 988 synchronized(parent.getTreeLock()) { 993 isValid = false; 994 } 995 } 996 997 private void prepare(int sizeType) { 998 boolean visChanged = false; 999 if (!isValid) { 1001 isValid = true; 1002 horizontalGroup.setSize(HORIZONTAL, UNSET, UNSET); 1003 verticalGroup.setSize(VERTICAL, UNSET, UNSET); 1004 for (ComponentInfo ci : componentInfos.values()) { 1005 if (ci.updateVisibility()) { 1006 visChanged = true; 1007 } 1008 ci.clearCachedSize(); 1009 } 1010 } 1011 if (springsChanged) { 1013 registerComponents(horizontalGroup, HORIZONTAL); 1014 registerComponents(verticalGroup, VERTICAL); 1015 } 1016 if (springsChanged || visChanged) { 1019 checkComponents(); 1020 horizontalGroup.removeAutopadding(); 1021 verticalGroup.removeAutopadding(); 1022 if (getAutoCreateGaps()) { 1023 insertAutopadding(true); 1024 } else if (hasPreferredPaddingSprings || 1025 getAutoCreateContainerGaps()) { 1026 insertAutopadding(false); 1027 } 1028 springsChanged = false; 1029 } 1030 if (sizeType != SPECIFIC_SIZE && (getAutoCreateGaps() || 1036 getAutoCreateContainerGaps() || hasPreferredPaddingSprings)) { 1037 calculateAutopadding(horizontalGroup, HORIZONTAL, sizeType, 0, 0); 1038 calculateAutopadding(verticalGroup, VERTICAL, sizeType, 0, 0); 1039 } 1040 } 1041 1042 private void calculateAutopadding(Group group, int axis, int sizeType, 1043 int origin, int size) { 1044 group.unsetAutopadding(); 1045 switch(sizeType) { 1046 case MIN_SIZE: 1047 size = group.getMinimumSize(axis); 1048 break; 1049 case PREF_SIZE: 1050 size = group.getPreferredSize(axis); 1051 break; 1052 case MAX_SIZE: 1053 size = group.getMaximumSize(axis); 1054 break; 1055 default: 1056 break; 1057 } 1058 group.setSize(axis, origin, size); 1059 group.calculateAutopadding(axis); 1060 } 1061 1062 private void checkComponents() { 1063 for (ComponentInfo info : componentInfos.values()) { 1064 if (info.horizontalSpring == null) { 1065 throw new IllegalStateException (info.component + 1066 " is not attached to a horizontal group"); 1067 } 1068 if (info.verticalSpring == null) { 1069 throw new IllegalStateException (info.component + 1070 " is not attached to a vertical group"); 1071 } 1072 } 1073 } 1074 1075 private void registerComponents(Group group, int axis) { 1076 List<Spring > springs = group.springs; 1077 for (int counter = springs.size() - 1; counter >= 0; counter--) { 1078 Spring spring = springs.get(counter); 1079 if (spring instanceof ComponentSpring) { 1080 ((ComponentSpring)spring).installIfNecessary(axis); 1081 } else if (spring instanceof Group) { 1082 registerComponents((Group)spring, axis); 1083 } 1084 } 1085 } 1086 1087 private Dimension adjustSize(int width, int height) { 1088 Insets insets = host.getInsets(); 1089 return new Dimension (width + insets.left + insets.right, 1090 height + insets.top + insets.bottom); 1091 } 1092 1093 private void checkParent(Container parent) { 1094 if (parent != host) { 1095 throw new IllegalArgumentException ( 1096 "GroupLayout can only be used with one Container at a time"); 1097 } 1098 } 1099 1100 1104 private ComponentInfo getComponentInfo(Component component) { 1105 ComponentInfo info = (ComponentInfo)componentInfos.get(component); 1106 if (info == null) { 1107 info = new ComponentInfo(component); 1108 componentInfos.put(component, info); 1109 if (component.getParent() != host) { 1110 host.add(component); 1111 } 1112 } 1113 return info; 1114 } 1115 1116 1122 private void insertAutopadding(boolean insert) { 1123 horizontalGroup.insertAutopadding(HORIZONTAL, 1124 new ArrayList<AutoPreferredGapSpring>(1), 1125 new ArrayList<AutoPreferredGapSpring>(1), 1126 new ArrayList<ComponentSpring>(1), 1127 new ArrayList<ComponentSpring>(1), insert); 1128 verticalGroup.insertAutopadding(VERTICAL, 1129 new ArrayList<AutoPreferredGapSpring>(1), 1130 new ArrayList<AutoPreferredGapSpring>(1), 1131 new ArrayList<ComponentSpring>(1), 1132 new ArrayList<ComponentSpring>(1), insert); 1133 } 1134 1135 1139 private boolean areParallelSiblings(Component source, Component target, 1140 int axis) { 1141 ComponentInfo sourceInfo = getComponentInfo(source); 1142 ComponentInfo targetInfo = getComponentInfo(target); 1143 Spring sourceSpring; 1144 Spring targetSpring; 1145 if (axis == HORIZONTAL) { 1146 sourceSpring = sourceInfo.horizontalSpring; 1147 targetSpring = targetInfo.horizontalSpring; 1148 } else { 1149 sourceSpring = sourceInfo.verticalSpring; 1150 targetSpring = targetInfo.verticalSpring; 1151 } 1152 Set<Spring > sourcePath = tmpParallelSet; 1153 sourcePath.clear(); 1154 Spring spring = sourceSpring.getParent(); 1155 while (spring != null) { 1156 sourcePath.add(spring); 1157 spring = spring.getParent(); 1158 } 1159 spring = targetSpring.getParent(); 1160 while (spring != null) { 1161 if (sourcePath.contains(spring)) { 1162 sourcePath.clear(); 1163 while (spring != null) { 1164 if (spring instanceof ParallelGroup) { 1165 return true; 1166 } 1167 spring = spring.getParent(); 1168 } 1169 return false; 1170 } 1171 spring = spring.getParent(); 1172 } 1173 sourcePath.clear(); 1174 return false; 1175 } 1176 1177 private boolean isLeftToRight() { 1178 return host.getComponentOrientation().isLeftToRight(); 1179 } 1180 1181 1189 public String toString() { 1190 if (springsChanged) { 1191 registerComponents(horizontalGroup, HORIZONTAL); 1192 registerComponents(verticalGroup, VERTICAL); 1193 } 1194 StringBuffer buffer = new StringBuffer (); 1195 buffer.append("HORIZONTAL\n"); 1196 createSpringDescription(buffer, horizontalGroup, " ", HORIZONTAL); 1197 buffer.append("\nVERTICAL\n"); 1198 createSpringDescription(buffer, verticalGroup, " ", VERTICAL); 1199 return buffer.toString(); 1200 } 1201 1202 private void createSpringDescription(StringBuffer buffer, Spring spring, 1203 String indent, int axis) { 1204 String origin = ""; 1205 String padding = ""; 1206 if (spring instanceof ComponentSpring) { 1207 ComponentSpring cSpring = (ComponentSpring)spring; 1208 origin = Integer.toString(cSpring.getOrigin()) + " "; 1209 String name = cSpring.getComponent().getName(); 1210 if (name != null) { 1211 origin = "name=" + name + ", "; 1212 } 1213 } 1214 if (spring instanceof AutoPreferredGapSpring) { 1215 AutoPreferredGapSpring paddingSpring = 1216 (AutoPreferredGapSpring)spring; 1217 padding = ", userCreated=" + paddingSpring.getUserCreated() + 1218 ", matches=" + paddingSpring.getMatchDescription(); 1219 } 1220 buffer.append(indent + spring.getClass().getName() + " " + 1221 Integer.toHexString(spring.hashCode()) + " " + 1222 origin + 1223 ", size=" + spring.getSize() + 1224 ", alignment=" + spring.getAlignment() + 1225 " prefs=[" + spring.getMinimumSize(axis) + 1226 " " + spring.getPreferredSize(axis) + 1227 " " + spring.getMaximumSize(axis) + 1228 padding + "]\n"); 1229 if (spring instanceof Group) { 1230 List<Spring > springs = ((Group)spring).springs; 1231 indent += " "; 1232 for (int counter = 0; counter < springs.size(); counter++) { 1233 createSpringDescription(buffer, springs.get(counter), indent, 1234 axis); 1235 } 1236 } 1237 } 1238 1239 1240 1246 private abstract class Spring { 1247 private int size; 1248 private int min; 1249 private int max; 1250 private int pref; 1251 private Spring parent; 1252 1253 private Alignment alignment; 1254 1255 Spring() { 1256 min = pref = max = UNSET; 1257 } 1258 1259 1265 abstract int calculateMinimumSize(int axis); 1266 1267 1273 abstract int calculatePreferredSize(int axis); 1274 1275 1281 abstract int calculateMaximumSize(int axis); 1282 1283 1286 void setParent(Spring parent) { 1287 this.parent = parent; 1288 } 1289 1290 1293 Spring getParent() { 1294 return parent; 1295 } 1296 1297 void setAlignment(Alignment alignment) { 1300 this.alignment = alignment; 1301 } 1302 1303 1306 Alignment getAlignment() { 1307 return alignment; 1308 } 1309 1310 1313 final int getMinimumSize(int axis) { 1314 if (min == UNSET) { 1315 min = constrain(calculateMinimumSize(axis)); 1316 } 1317 return min; 1318 } 1319 1320 1323 final int getPreferredSize(int axis) { 1324 if (pref == UNSET) { 1325 pref = constrain(calculatePreferredSize(axis)); 1326 } 1327 return pref; 1328 } 1329 1330 1333 final int getMaximumSize(int axis) { 1334 if (max == UNSET) { 1335 max = constrain(calculateMaximumSize(axis)); 1336 } 1337 return max; 1338 } 1339 1340 1349 void setSize(int axis, int origin, int size) { 1350 this.size = size; 1351 if (size == UNSET) { 1352 unset(); 1353 } 1354 } 1355 1356 1359 void unset() { 1360 size = min = pref = max = UNSET; 1361 } 1362 1363 1366 int getSize() { 1367 return size; 1368 } 1369 1370 int constrain(int value) { 1371 return Math.min(value, Short.MAX_VALUE); 1372 } 1373 1374 int getBaseline() { 1375 return -1; 1376 } 1377 1378 BaselineResizeBehavior getBaselineResizeBehavior() { 1379 return BaselineResizeBehavior.OTHER; 1380 } 1381 1382 final boolean isResizable(int axis) { 1383 int min = getMinimumSize(axis); 1384 int pref = getPreferredSize(axis); 1385 return (min != pref || pref != getMaximumSize(axis)); 1386 } 1387 } 1388 1389 1445 public abstract class Group extends Spring { 1446 List<Spring > springs; 1449 1450 Group() { 1451 springs = new ArrayList<Spring >(); 1452 } 1453 1454 1460 public Group addGroup(Group group) { 1461 return addSpring(group); 1462 } 1463 1464 1470 public Group addComponent(Component component) { 1471 return addComponent(component, DEFAULT_SIZE, DEFAULT_SIZE, 1472 DEFAULT_SIZE); 1473 } 1474 1475 1488 public Group addComponent(Component component, int min, int pref, 1489 int max) { 1490 return addSpring(new ComponentSpring(component, min, pref, max)); 1491 } 1492 1493 1501 public Group addGap(int size) { 1502 return addGap(size, size, size); 1503 } 1504 1505 1515 public Group addGap(int min, int pref, int max) { 1516 return addSpring(new GapSpring(min, pref, max)); 1517 } 1518 1519 Spring getSpring(int index) { 1520 return springs.get(index); 1521 } 1522 1523 int indexOf(Spring spring) { 1524 return springs.indexOf(spring); 1525 } 1526 1527 1531 Group addSpring(Spring spring) { 1532 springs.add(spring); 1533 spring.setParent(this); 1534 if (!(spring instanceof AutoPreferredGapSpring) || 1535 !((AutoPreferredGapSpring)spring).getUserCreated()) { 1536 springsChanged = true; 1537 } 1538 return this; 1539 } 1540 1541 1545 void setSize(int axis, int origin, int size) { 1546 super.setSize(axis, origin, size); 1547 if (size == UNSET) { 1548 for (int counter = springs.size() - 1; counter >= 0; 1549 counter--) { 1550 getSpring(counter).setSize(axis, origin, size); 1551 } 1552 } else { 1553 setValidSize(axis, origin, size); 1554 } 1555 } 1556 1557 1561 abstract void setValidSize(int axis, int origin, int size); 1562 1563 int calculateMinimumSize(int axis) { 1564 return calculateSize(axis, MIN_SIZE); 1565 } 1566 1567 int calculatePreferredSize(int axis) { 1568 return calculateSize(axis, PREF_SIZE); 1569 } 1570 1571 int calculateMaximumSize(int axis) { 1572 return calculateSize(axis, MAX_SIZE); 1573 } 1574 1575 1582 int calculateSize(int axis, int type) { 1583 int count = springs.size(); 1584 if (count == 0) { 1585 return 0; 1586 } 1587 if (count == 1) { 1588 return getSpringSize(getSpring(0), axis, type); 1589 } 1590 int size = constrain(operator(getSpringSize(getSpring(0), axis, 1591 type), getSpringSize(getSpring(1), axis, type))); 1592 for (int counter = 2; counter < count; counter++) { 1593 size = constrain(operator(size, getSpringSize( 1594 getSpring(counter), axis, type))); 1595 } 1596 return size; 1597 } 1598 1599 int getSpringSize(Spring spring, int axis, int type) { 1600 switch(type) { 1601 case MIN_SIZE: 1602 return spring.getMinimumSize(axis); 1603 case PREF_SIZE: 1604 return spring.getPreferredSize(axis); 1605 case MAX_SIZE: 1606 return spring.getMaximumSize(axis); 1607 } 1608 assert false; 1609 return 0; 1610 } 1611 1612 1617 abstract int operator(int a, int b); 1618 1619 1623 1640 abstract void insertAutopadding(int axis, 1641 List<AutoPreferredGapSpring> leadingPadding, 1642 List<AutoPreferredGapSpring> trailingPadding, 1643 List<ComponentSpring> leading, List<ComponentSpring> trailing, 1644 boolean insert); 1645 1646 1649 void removeAutopadding() { 1650 unset(); 1651 for (int counter = springs.size() - 1; counter >= 0; counter--) { 1652 Spring spring = springs.get(counter); 1653 if (spring instanceof AutoPreferredGapSpring) { 1654 if (((AutoPreferredGapSpring)spring).getUserCreated()) { 1655 ((AutoPreferredGapSpring)spring).reset(); 1656 } else { 1657 springs.remove(counter); 1658 } 1659 } else if (spring instanceof Group) { 1660 ((Group)spring).removeAutopadding(); 1661 } 1662 } 1663 } 1664 1665 void unsetAutopadding() { 1666 unset(); 1668 for (int counter = springs.size() - 1; counter >= 0; counter--) { 1669 Spring spring = springs.get(counter); 1670 if (spring instanceof AutoPreferredGapSpring) { 1671 ((AutoPreferredGapSpring)spring).unset(); 1672 } else if (spring instanceof Group) { 1673 ((Group)spring).unsetAutopadding(); 1674 } 1675 } 1676 } 1677 1678 void calculateAutopadding(int axis) { 1679 for (int counter = springs.size() - 1; counter >= 0; counter--) { 1680 Spring spring = springs.get(counter); 1681 if (spring instanceof AutoPreferredGapSpring) { 1682 spring.unset(); 1684 ((AutoPreferredGapSpring)spring).calculatePadding(axis); 1685 } else if (spring instanceof Group) { 1686 ((Group)spring).calculateAutopadding(axis); 1687 } 1688 } 1689 unset(); 1691 } 1692 } 1693 1694 1695 1713 public class SequentialGroup extends Group { 1714 private Spring baselineSpring; 1715 1716 SequentialGroup() { 1717 } 1718 1719 1722 public SequentialGroup addGroup(Group group) { 1723 return (SequentialGroup)super.addGroup(group); 1724 } 1725 1726 1734 public SequentialGroup addGroup(boolean useAsBaseline, Group group) { 1735 super.addGroup(group); 1736 if (useAsBaseline) { 1737 baselineSpring = group; 1738 } 1739 return this; 1740 } 1741 1742 1745 public SequentialGroup addComponent(Component component) { 1746 return (SequentialGroup)super.addComponent(component); 1747 } 1748 1749 1757 public SequentialGroup addComponent(boolean useAsBaseline, 1758 Component component) { 1759 super.addComponent(component); 1760 if (useAsBaseline) { 1761 baselineSpring = springs.get(springs.size() - 1); 1762 } 1763 return this; 1764 } 1765 1766 1769 public SequentialGroup addComponent(Component component, int min, 1770 int pref, int max) { 1771 return (SequentialGroup)super.addComponent( 1772 component, min, pref, max); 1773 } 1774 1775 1790 public SequentialGroup addComponent(boolean useAsBaseline, 1791 Component component, int min, int pref, int max) { 1792 super.addComponent(component, min, pref, max); 1793 if (useAsBaseline) { 1794 baselineSpring = springs.get(springs.size() - 1); 1795 } 1796 return this; 1797 } 1798 1799 1802 public SequentialGroup addGap(int size) { 1803 return (SequentialGroup)super.addGap(size); 1804 } 1805 1806 1809 public SequentialGroup addGap(int min, int pref, int max) { 1810 return (SequentialGroup)super.addGap(min, pref, max); 1811 } 1812 1813 1827 public SequentialGroup addPreferredGap(JComponent comp1, 1828 JComponent comp2, ComponentPlacement type) { 1829 return addPreferredGap(comp1, comp2, type, DEFAULT_SIZE, 1830 PREFERRED_SIZE); 1831 } 1832 1833 1850 public SequentialGroup addPreferredGap(JComponent comp1, 1851 JComponent comp2, ComponentPlacement type, int pref, 1852 int max) { 1853 if (type == null) { 1854 throw new IllegalArgumentException ("Type must be non-null"); 1855 } 1856 if (comp1 == null || comp2 == null) { 1857 throw new IllegalArgumentException ( 1858 "Components must be non-null"); 1859 } 1860 checkPreferredGapValues(pref, max); 1861 return (SequentialGroup)addSpring(new PreferredGapSpring( 1862 comp1, comp2, type, pref, max)); 1863 } 1864 1865 1884 public SequentialGroup addPreferredGap(ComponentPlacement type) { 1885 return addPreferredGap(type, DEFAULT_SIZE, DEFAULT_SIZE); 1886 } 1887 1888 1910 public SequentialGroup addPreferredGap(ComponentPlacement type, 1911 int pref, int max) { 1912 if (type != ComponentPlacement.RELATED && 1913 type != ComponentPlacement.UNRELATED) { 1914 throw new IllegalArgumentException ( 1915 "Type must be one of " + 1916 "LayoutStyle.ComponentPlacement.RELATED or " + 1917 "LayoutStyle.ComponentPlacement.UNRELATED"); 1918 } 1919 checkPreferredGapValues(pref, max); 1920 hasPreferredPaddingSprings = true; 1921 return (SequentialGroup)addSpring(new AutoPreferredGapSpring( 1922 type, pref, max)); 1923 } 1924 1925 1936 public SequentialGroup addContainerGap() { 1937 return addContainerGap(DEFAULT_SIZE, DEFAULT_SIZE); 1938 } 1939 1940 1954 public SequentialGroup addContainerGap(int pref, int max) { 1955 if ((pref < 0 && pref != DEFAULT_SIZE) || 1956 (max < 0 && max != DEFAULT_SIZE && max != PREFERRED_SIZE)|| 1957 (pref >= 0 && max >= 0 && pref > max)) { 1958 throw new IllegalArgumentException ( 1959 "Pref and max must be either DEFAULT_VALUE " + 1960 "or >= 0 and pref <= max"); 1961 } 1962 hasPreferredPaddingSprings = true; 1963 return (SequentialGroup)addSpring( 1964 new ContainerAutoPreferredGapSpring(pref, max)); 1965 } 1966 1967 int operator(int a, int b) { 1968 return constrain(a) + constrain(b); 1969 } 1970 1971 void setValidSize(int axis, int origin, int size) { 1972 int pref = getPreferredSize(axis); 1973 if (size == pref) { 1974 for (Spring spring : springs) { 1976 int springPref = spring.getPreferredSize(axis); 1977 spring.setSize(axis, origin, springPref); 1978 origin += springPref; 1979 } 1980 } else if (springs.size() == 1) { 1981 Spring spring = getSpring(0); 1982 spring.setSize(axis, origin, Math.min( 1983 Math.max(size, spring.getMinimumSize(axis)), 1984 spring.getMaximumSize(axis))); 1985 } else if (springs.size() > 1) { 1986 setValidSizeNotPreferred(axis, origin, size); 1988 } 1989 } 1990 1991 private void setValidSizeNotPreferred(int axis, int origin, int size) { 1992 int delta = size - getPreferredSize(axis); 1993 assert delta != 0; 1994 boolean useMin = (delta < 0); 1995 int springCount = springs.size(); 1996 if (useMin) { 1997 delta *= -1; 1998 } 1999 2000 2011 List<SpringDelta> resizable = buildResizableList(axis, useMin); 2013 int resizableCount = resizable.size(); 2014 2015 if (resizableCount > 0) { 2016 int sDelta = delta / resizableCount; 2018 int slop = delta - sDelta * resizableCount; 2020 int[] sizes = new int[springCount]; 2021 int sign = useMin ? -1 : 1; 2022 for (int counter = 0; counter < resizableCount; counter++) { 2025 SpringDelta springDelta = resizable.get(counter); 2026 if ((counter + 1) == resizableCount) { 2027 sDelta += slop; 2028 } 2029 springDelta.delta = Math.min(sDelta, springDelta.delta); 2030 delta -= springDelta.delta; 2031 if (springDelta.delta != sDelta && counter + 1 < 2032 resizableCount) { 2033 sDelta = delta / (resizableCount - counter - 1); 2036 slop = delta - sDelta * (resizableCount - counter - 1); 2037 } 2038 sizes[springDelta.index] = sign * springDelta.delta; 2039 } 2040 2041 for (int counter = 0; counter < springCount; counter++) { 2043 Spring spring = getSpring(counter); 2044 int sSize = spring.getPreferredSize(axis) + sizes[counter]; 2045 spring.setSize(axis, origin, sSize); 2046 origin += sSize; 2047 } 2048 } else { 2049 for (int counter = 0; counter < springCount; counter++) { 2052 Spring spring = getSpring(counter); 2053 int sSize; 2054 if (useMin) { 2055 sSize = spring.getMinimumSize(axis); 2056 } else { 2057 sSize = spring.getMaximumSize(axis); 2058 } 2059 spring.setSize(axis, origin, sSize); 2060 origin += sSize; 2061 } 2062 } 2063 } 2064 2065 2070 private List<SpringDelta> buildResizableList(int axis, 2071 boolean useMin) { 2072 int size = springs.size(); 2074 List<SpringDelta> sorted = new ArrayList<SpringDelta>(size); 2075 for (int counter = 0; counter < size; counter++) { 2076 Spring spring = getSpring(counter); 2077 int sDelta; 2078 if (useMin) { 2079 sDelta = spring.getPreferredSize(axis) - 2080 spring.getMinimumSize(axis); 2081 } else { 2082 sDelta = spring.getMaximumSize(axis) - 2083 spring.getPreferredSize(axis); 2084 } 2085 if (sDelta > 0) { 2086 sorted.add(new SpringDelta(counter, sDelta)); 2087 } 2088 } 2089 Collections.sort(sorted); 2090 return sorted; 2091 } 2092 2093 void insertAutopadding(int axis, 2094 List<AutoPreferredGapSpring> leadingPadding, 2095 List<AutoPreferredGapSpring> trailingPadding, 2096 List<ComponentSpring> leading, List<ComponentSpring> trailing, 2097 boolean insert) { 2098 List<AutoPreferredGapSpring> newLeadingPadding = 2099 new ArrayList<AutoPreferredGapSpring>(leadingPadding); 2100 List<AutoPreferredGapSpring> newTrailingPadding = 2101 new ArrayList<AutoPreferredGapSpring>(1); 2102 List<ComponentSpring> newLeading = 2103 new ArrayList<ComponentSpring>(leading); 2104 List<ComponentSpring> newTrailing = null; 2105 for (int counter = 0; counter < springs.size(); counter++) { 2108 Spring spring = getSpring(counter); 2109 if (spring instanceof AutoPreferredGapSpring) { 2110 AutoPreferredGapSpring padding = 2113 (AutoPreferredGapSpring)spring; 2114 padding.setSources(newLeading); 2115 newLeading.clear(); 2116 if (counter + 1 == springs.size()) { 2117 if (!(padding instanceof 2119 ContainerAutoPreferredGapSpring)) { 2120 trailingPadding.add(padding); 2121 } 2122 } else { 2123 newLeadingPadding.clear(); 2124 newLeadingPadding.add(padding); 2125 } 2126 } else { 2127 if (newLeading.size() > 0 && insert) { 2129 AutoPreferredGapSpring padding = 2132 new AutoPreferredGapSpring(); 2133 springs.add(counter--, padding); 2136 continue; 2137 } 2138 if (spring instanceof ComponentSpring) { 2139 ComponentSpring cSpring = (ComponentSpring)spring; 2142 if (!cSpring.isVisible()) { 2143 continue; 2144 } 2145 for (AutoPreferredGapSpring gapSpring : newLeadingPadding) { 2146 gapSpring.addTarget(cSpring, axis); 2147 } 2148 newLeading.clear(); 2149 newLeadingPadding.clear(); 2150 if (counter + 1 == springs.size()) { 2151 trailing.add(cSpring); 2153 } else { 2154 newLeading.add(cSpring); 2156 } 2157 } else if (spring instanceof Group) { 2158 if (newTrailing == null) { 2160 newTrailing = new ArrayList<ComponentSpring>(1); 2161 } else { 2162 newTrailing.clear(); 2163 } 2164 newTrailingPadding.clear(); 2165 ((Group)spring).insertAutopadding(axis, 2166 newLeadingPadding, newTrailingPadding, 2167 newLeading, newTrailing, insert); 2168 newLeading.clear(); 2169 newLeadingPadding.clear(); 2170 if (counter + 1 == springs.size()) { 2171 trailing.addAll(newTrailing); 2172 trailingPadding.addAll(newTrailingPadding); 2173 } else { 2174 newLeading.addAll(newTrailing); 2175 newLeadingPadding.addAll(newTrailingPadding); 2176 } 2177 } else { 2178 newLeadingPadding.clear(); 2180 newLeading.clear(); 2181 } 2182 } 2183 } 2184 } 2185 2186 int getBaseline() { 2187 if (baselineSpring != null) { 2188 int baseline = baselineSpring.getBaseline(); 2189 if (baseline >= 0) { 2190 int size = 0; 2191 for (Spring spring : springs) { 2192 if (spring == baselineSpring) { 2193 return size + baseline; 2194 } else { 2195 size += spring.getPreferredSize(VERTICAL); 2196 } 2197 } 2198 } 2199 } 2200 return -1; 2201 } 2202 2203 BaselineResizeBehavior getBaselineResizeBehavior() { 2204 if (isResizable(VERTICAL)) { 2205 if (!baselineSpring.isResizable(VERTICAL)) { 2206 boolean leadingResizable = false; 2210 for (Spring spring : springs) { 2211 if (spring == baselineSpring) { 2212 break; 2213 } else if (spring.isResizable(VERTICAL)) { 2214 leadingResizable = true; 2215 break; 2216 } 2217 } 2218 boolean trailingResizable = false; 2219 for (int i = springs.size() - 1; i >= 0; i--) { 2220 Spring spring = springs.get(i); 2221 if (spring == baselineSpring) { 2222 break; 2223 } 2224 if (spring.isResizable(VERTICAL)) { 2225 trailingResizable = true; 2226 break; 2227 } 2228 } 2229 if (leadingResizable && !trailingResizable) { 2230 return BaselineResizeBehavior.CONSTANT_DESCENT; 2231 } else if (!leadingResizable && trailingResizable) { 2232 return BaselineResizeBehavior.CONSTANT_ASCENT; 2233 } 2234 } else { 2237 BaselineResizeBehavior brb = baselineSpring.getBaselineResizeBehavior(); 2238 if (brb == BaselineResizeBehavior.CONSTANT_ASCENT) { 2239 for (Spring spring : springs) { 2240 if (spring == baselineSpring) { 2241 return BaselineResizeBehavior.CONSTANT_ASCENT; 2242 } 2243 if (spring.isResizable(VERTICAL)) { 2244 return BaselineResizeBehavior.OTHER; 2245 } 2246 } 2247 } else if (brb == BaselineResizeBehavior.CONSTANT_DESCENT) { 2248 for (int i = springs.size() - 1; i >= 0; i--) { 2249 Spring spring = springs.get(i); 2250 if (spring == baselineSpring) { 2251 return BaselineResizeBehavior.CONSTANT_DESCENT; 2252 } 2253 if (spring.isResizable(VERTICAL)) { 2254 return BaselineResizeBehavior.OTHER; 2255 } 2256 } 2257 } 2258 } 2259 return BaselineResizeBehavior.OTHER; 2260 } 2261 return BaselineResizeBehavior.CONSTANT_ASCENT; 2263 } 2264 2265 private void checkPreferredGapValues(int pref, int max) { 2266 if ((pref < 0 && pref != DEFAULT_SIZE && pref != PREFERRED_SIZE) || 2267 (max < 0 && max != DEFAULT_SIZE && max != PREFERRED_SIZE)|| 2268 (pref >= 0 && max >= 0 && pref > max)) { 2269 throw new IllegalArgumentException ( 2270 "Pref and max must be either DEFAULT_SIZE, " + 2271 "PREFERRED_SIZE, or >= 0 and pref <= max"); 2272 } 2273 } 2274 } 2275 2276 2277 2280 private static final class SpringDelta implements Comparable <SpringDelta> { 2281 public final int index; 2283 public int delta; 2285 2286 public SpringDelta(int index, int delta) { 2287 this.index = index; 2288 this.delta = delta; 2289 } 2290 2291 public int compareTo(SpringDelta o) { 2292 return delta - o.delta; 2293 } 2294 2295 public String toString() { 2296 return super.toString() + "[index=" + index + ", delta=" + 2297 delta + "]"; 2298 } 2299 } 2300 2301 2302 2384 public class ParallelGroup extends Group { 2385 private final Alignment childAlignment; 2387 private final boolean resizable; 2389 2390 ParallelGroup(Alignment childAlignment, boolean resizable) { 2391 this.childAlignment = childAlignment; 2392 this.resizable = resizable; 2393 } 2394 2395 2398 public ParallelGroup addGroup(Group group) { 2399 return (ParallelGroup)super.addGroup(group); 2400 } 2401 2402 2405 public ParallelGroup addComponent(Component component) { 2406 return (ParallelGroup)super.addComponent(component); 2407 } 2408 2409 2412 public ParallelGroup addComponent(Component component, int min, int pref, 2413 int max) { 2414 return (ParallelGroup)super.addComponent(component, min, pref, max); 2415 } 2416 2417 2420 public ParallelGroup addGap(int pref) { 2421 return (ParallelGroup)super.addGap(pref); 2422 } 2423 2424 2427 public ParallelGroup addGap(int min, int pref, int max) { 2428 return (ParallelGroup)super.addGap(min, pref, max); 2429 } 2430 2431 2443 public ParallelGroup addGroup(Alignment alignment, Group group) { 2444 checkChildAlignment(alignment); 2445 group.setAlignment(alignment); 2446 return (ParallelGroup)addSpring(group); 2447 } 2448 2449 2459 public ParallelGroup addComponent(Component component, 2460 Alignment alignment) { 2461 return addComponent(component, alignment, DEFAULT_SIZE, DEFAULT_SIZE, 2462 DEFAULT_SIZE); 2463 } 2464 2465 2478 public ParallelGroup addComponent(Component component, 2479 Alignment alignment, int min, int pref, int max) { 2480 checkChildAlignment(alignment); 2481 ComponentSpring spring = new ComponentSpring(component, 2482 min, pref, max); 2483 spring.setAlignment(alignment); 2484 return (ParallelGroup)addSpring(spring); 2485 } 2486 2487 boolean isResizable() { 2488 return resizable; 2489 } 2490 2491 int operator(int a, int b) { 2492 return Math.max(a, b); 2493 } 2494 2495 int calculateMinimumSize(int axis) { 2496 if (!isResizable()) { 2497 return getPreferredSize(axis); 2498 } 2499 return super.calculateMinimumSize(axis); 2500 } 2501 2502 int calculateMaximumSize(int axis) { 2503 if (!isResizable()) { 2504 return getPreferredSize(axis); 2505 } 2506 return super.calculateMaximumSize(axis); 2507 } 2508 2509 void setValidSize(int axis, int origin, int size) { 2510 for (Spring spring : springs) { 2511 setChildSize(spring, axis, origin, size); 2512 } 2513 } 2514 2515 void setChildSize(Spring spring, int axis, int origin, int size) { 2516 Alignment alignment = spring.getAlignment(); 2517 int springSize = Math.min( 2518 Math.max(spring.getMinimumSize(axis), size), 2519 spring.getMaximumSize(axis)); 2520 if (alignment == null) { 2521 alignment = childAlignment; 2522 } 2523 switch (alignment) { 2524 case TRAILING: 2525 spring.setSize(axis, origin + size - springSize, 2526 springSize); 2527 break; 2528 case CENTER: 2529 spring.setSize(axis, origin + 2530 (size - springSize) / 2,springSize); 2531 break; 2532 default: spring.setSize(axis, origin, springSize); 2534 break; 2535 } 2536 } 2537 2538 void insertAutopadding(int axis, 2539 List<AutoPreferredGapSpring> leadingPadding, 2540 List<AutoPreferredGapSpring> trailingPadding, 2541 List<ComponentSpring> leading, List<ComponentSpring> trailing, 2542 boolean insert) { 2543 for (Spring spring : springs) { 2544 if (spring instanceof ComponentSpring) { 2545 for (AutoPreferredGapSpring gapSpring : leadingPadding) { 2546 gapSpring.addTarget((ComponentSpring)spring, axis); 2547 } 2548 trailing.add((ComponentSpring)spring); 2549 } else if (spring instanceof Group) { 2550 ((Group)spring).insertAutopadding(axis, leadingPadding, 2551 trailingPadding, leading, trailing, insert); 2552 } else if (spring instanceof AutoPreferredGapSpring) { 2553 trailingPadding.add((AutoPreferredGapSpring)spring); 2554 } 2555 } 2556 } 2557 2558 private void checkChildAlignment(Alignment alignment) { 2559 checkChildAlignment(alignment, (this instanceof BaselineGroup)); 2560 } 2561 2562 private void checkChildAlignment(Alignment alignment, 2563 boolean allowsBaseline) { 2564 if (alignment == null) { 2565 throw new IllegalArgumentException ("Alignment must be non-null"); 2566 } 2567 if (!allowsBaseline && alignment == Alignment.BASELINE) { 2568 throw new IllegalArgumentException ("Alignment must be one of:" + 2569 "LEADING, TRAILING or CENTER"); 2570 } 2571 } 2572 } 2573 2574 2575 2579 private class BaselineGroup extends ParallelGroup { 2580 private boolean allSpringsHaveBaseline; 2582 2583 private int prefAscent; 2586 2587 private int prefDescent; 2590 2591 private boolean baselineAnchorSet; 2593 2594 private boolean baselineAnchoredToTop; 2598 2599 private boolean calcedBaseline; 2601 2602 BaselineGroup(boolean resizable) { 2603 super(Alignment.LEADING, resizable); 2604 prefAscent = prefDescent = -1; 2605 calcedBaseline = false; 2606 } 2607 2608 BaselineGroup(boolean resizable, boolean baselineAnchoredToTop) { 2609 this(resizable); 2610 this.baselineAnchoredToTop = baselineAnchoredToTop; 2611 baselineAnchorSet = true; 2612 } 2613 2614 void unset() { 2615 super.unset(); 2616 prefAscent = prefDescent = -1; 2617 calcedBaseline = false; 2618 } 2619 2620 void setValidSize(int axis, int origin, int size) { 2621 checkAxis(axis); 2622 if (prefAscent == -1) { 2623 super.setValidSize(axis, origin, size); 2624 } else { 2625 baselineLayout(origin, size); 2627 } 2628 } 2629 2630 int calculateSize(int axis, int type) { 2631 checkAxis(axis); 2632 if (!calcedBaseline) { 2633 calculateBaselineAndResizeBehavior(); 2634 } 2635 if (type == MIN_SIZE) { 2636 return calculateMinSize(); 2637 } 2638 if (type == MAX_SIZE) { 2639 return calculateMaxSize(); 2640 } 2641 if (allSpringsHaveBaseline) { 2642 return prefAscent + prefDescent; 2643 } 2644 return Math.max(prefAscent + prefDescent, 2645 super.calculateSize(axis, type)); 2646 } 2647 2648 private void calculateBaselineAndResizeBehavior() { 2649 prefAscent = 0; 2651 prefDescent = 0; 2652 int baselineSpringCount = 0; 2653 BaselineResizeBehavior resizeBehavior = null; 2654 for (Spring spring : springs) { 2655 if (spring.getAlignment() == null || 2656 spring.getAlignment() == Alignment.BASELINE) { 2657 int baseline = spring.getBaseline(); 2658 if (baseline >= 0) { 2659 if (spring.isResizable(VERTICAL)) { 2660 BaselineResizeBehavior brb = spring. 2661 getBaselineResizeBehavior(); 2662 if (resizeBehavior == null) { 2663 resizeBehavior = brb; 2664 } else if (brb != resizeBehavior) { 2665 resizeBehavior = BaselineResizeBehavior. 2666 CONSTANT_ASCENT; 2667 } 2668 } 2669 prefAscent = Math.max(prefAscent, baseline); 2670 prefDescent = Math.max(prefDescent, spring. 2671 getPreferredSize(VERTICAL) - baseline); 2672 baselineSpringCount++; 2673 } 2674 } 2675 } 2676 if (!baselineAnchorSet) { 2677 if (resizeBehavior == BaselineResizeBehavior.CONSTANT_DESCENT){ 2678 this.baselineAnchoredToTop = false; 2679 } else { 2680 this.baselineAnchoredToTop = true; 2681 } 2682 } 2683 allSpringsHaveBaseline = (baselineSpringCount == springs.size()); 2684 calcedBaseline = true; 2685 } 2686 2687 private int calculateMaxSize() { 2688 int maxAscent = prefAscent; 2689 int maxDescent = prefDescent; 2690 int nonBaselineMax = 0; 2691 for (Spring spring : springs) { 2692 int baseline; 2693 int springMax = spring.getMaximumSize(VERTICAL); 2694 if ((spring.getAlignment() == null || 2695 spring.getAlignment() == Alignment.BASELINE) && 2696 (baseline = spring.getBaseline()) >= 0) { 2697 int springPref = spring.getPreferredSize(VERTICAL); 2698 if (springPref != springMax) { 2699 switch (spring.getBaselineResizeBehavior()) { 2700 case CONSTANT_ASCENT: 2701 if (baselineAnchoredToTop) { 2702 maxDescent = Math.max(maxDescent, 2703 springMax - baseline); 2704 } 2705 break; 2706 case CONSTANT_DESCENT: 2707 if (!baselineAnchoredToTop) { 2708 maxAscent = Math.max(maxAscent, 2709 springMax - springPref + baseline); 2710 } 2711 break; 2712 default: break; 2714 } 2715 } 2716 } else { 2717 nonBaselineMax = Math.max(nonBaselineMax, springMax); 2719 } 2720 } 2721 return Math.max(nonBaselineMax, maxAscent + maxDescent); 2722 } 2723 2724 private int calculateMinSize() { 2725 int minAscent = 0; 2726 int minDescent = 0; 2727 int nonBaselineMin = 0; 2728 if (baselineAnchoredToTop) { 2729 minAscent = prefAscent; 2730 } else { 2731 minDescent = prefDescent; 2732 } 2733 for (Spring spring : springs) { 2734 int springMin = spring.getMinimumSize(VERTICAL); 2735 int baseline; 2736 if ((spring.getAlignment() == null || 2737 spring.getAlignment() == Alignment.BASELINE) && 2738 (baseline = spring.getBaseline()) >= 0) { 2739 int springPref = spring.getPreferredSize(VERTICAL); 2740 BaselineResizeBehavior brb = spring. 2741 getBaselineResizeBehavior(); 2742 switch (brb) { 2743 case CONSTANT_ASCENT: 2744 if (baselineAnchoredToTop) { 2745 minDescent = Math.max(springMin - baseline, 2746 minDescent); 2747 } else { 2748 minAscent = Math.max(baseline, minAscent); 2749 } 2750 break; 2751 case CONSTANT_DESCENT: 2752 if (!baselineAnchoredToTop) { 2753 minAscent = Math.max( 2754 baseline - (springPref - springMin), 2755 minAscent); 2756 } else { 2757 minDescent = Math.max(springPref - baseline, 2758 minDescent); 2759 } 2760 break; 2761 default: 2762 minAscent = Math.max(baseline, minAscent); 2765 minDescent = Math.max(springPref - baseline, 2766 minDescent); 2767 break; 2768 } 2769 } else { 2770 nonBaselineMin = Math.max(nonBaselineMin, springMin); 2772 } 2773 } 2774 return Math.max(nonBaselineMin, minAscent + minDescent); 2775 } 2776 2777 2781 private void baselineLayout(int origin, int size) { 2782 int ascent; 2783 int descent; 2784 if (baselineAnchoredToTop) { 2785 ascent = prefAscent; 2786 descent = size - ascent; 2787 } else { 2788 ascent = size - prefDescent; 2789 descent = prefDescent; 2790 } 2791 for (Spring spring : springs) { 2792 Alignment alignment = spring.getAlignment(); 2793 if (alignment == null || alignment == Alignment.BASELINE) { 2794 int baseline = spring.getBaseline(); 2795 if (baseline >= 0) { 2796 int springMax = spring.getMaximumSize(VERTICAL); 2797 int springPref = spring.getPreferredSize(VERTICAL); 2798 int height = springPref; 2799 int y; 2800 switch(spring.getBaselineResizeBehavior()) { 2801 case CONSTANT_ASCENT: 2802 y = origin + ascent - baseline; 2803 height = Math.min(descent, springMax - 2804 baseline) + baseline; 2805 break; 2806 case CONSTANT_DESCENT: 2807 height = Math.min(ascent, springMax - 2808 springPref + baseline) + 2809 (springPref - baseline); 2810 y = origin + ascent + 2811 (springPref - baseline) - height; 2812 break; 2813 default: y = origin + ascent - baseline; 2815 break; 2816 } 2817 spring.setSize(VERTICAL, y, height); 2818 } else { 2819 setChildSize(spring, VERTICAL, origin, size); 2820 } 2821 } else { 2822 setChildSize(spring, VERTICAL, origin, size); 2823 } 2824 } 2825 } 2826 2827 int getBaseline() { 2828 if (springs.size() > 1) { 2829 getPreferredSize(VERTICAL); 2831 return prefAscent; 2832 } else if (springs.size() == 1) { 2833 return springs.get(0).getBaseline(); 2834 } 2835 return -1; 2836 } 2837 2838 BaselineResizeBehavior getBaselineResizeBehavior() { 2839 if (springs.size() == 1) { 2840 return springs.get(0).getBaselineResizeBehavior(); 2841 } 2842 if (baselineAnchoredToTop) { 2843 return BaselineResizeBehavior.CONSTANT_ASCENT; 2844 } 2845 return BaselineResizeBehavior.CONSTANT_DESCENT; 2846 } 2847 2848 private void checkAxis(int axis) { 2850 if (axis == HORIZONTAL) { 2851 throw new IllegalStateException ( 2852 "Baseline must be used along vertical axis"); 2853 } 2854 } 2855 } 2856 2857 2858 private final class ComponentSpring extends Spring { 2859 private Component component; 2860 private int origin; 2861 2862 private final int min; 2865 private final int pref; 2866 private final int max; 2867 2868 private int baseline = -1; 2870 2871 private boolean installed; 2873 2874 private ComponentSpring(Component component, int min, int pref, 2875 int max) { 2876 this.component = component; 2877 if (component == null) { 2878 throw new IllegalArgumentException ( 2879 "Component must be non-null"); 2880 } 2881 2882 checkSize(min, pref, max, true); 2883 2884 this.min = min; 2885 this.max = max; 2886 this.pref = pref; 2887 2888 getComponentInfo(component); 2891 } 2892 2893 int calculateMinimumSize(int axis) { 2894 if (isLinked(axis)) { 2895 return getLinkSize(axis, MIN_SIZE); 2896 } 2897 return calculateNonlinkedMinimumSize(axis); 2898 } 2899 2900 int calculatePreferredSize(int axis) { 2901 if (isLinked(axis)) { 2902 return getLinkSize(axis, PREF_SIZE); 2903 } 2904 int min = getMinimumSize(axis); 2905 int pref = calculateNonlinkedPreferredSize(axis); 2906 int max = getMaximumSize(axis); 2907 return Math.min(max, Math.max(min, pref)); 2908 } 2909 2910 int calculateMaximumSize(int axis) { 2911 if (isLinked(axis)) { 2912 return getLinkSize(axis, MAX_SIZE); 2913 } 2914 return Math.max(getMinimumSize(axis), 2915 calculateNonlinkedMaximumSize(axis)); 2916 } 2917 2918 boolean isVisible() { 2919 return getComponentInfo(getComponent()).isVisible(); 2920 } 2921 2922 int calculateNonlinkedMinimumSize(int axis) { 2923 if (!isVisible()) { 2924 return 0; 2925 } 2926 if (min >= 0) { 2927 return min; 2928 } 2929 if (min == PREFERRED_SIZE) { 2930 return calculateNonlinkedPreferredSize(axis); 2931 } 2932 assert (min == DEFAULT_SIZE); 2933 return getSizeAlongAxis(axis, component.getMinimumSize()); 2934 } 2935 2936 int calculateNonlinkedPreferredSize(int axis) { 2937 if (!isVisible()) { 2938 return 0; 2939 } 2940 if (pref >= 0) { 2941 return pref; 2942 } 2943 assert (pref == DEFAULT_SIZE || pref == PREFERRED_SIZE); 2944 return getSizeAlongAxis(axis, component.getPreferredSize()); 2945 } 2946 2947 int calculateNonlinkedMaximumSize(int axis) { 2948 if (!isVisible()) { 2949 return 0; 2950 } 2951 if (max >= 0) { 2952 return max; 2953 } 2954 if (max == PREFERRED_SIZE) { 2955 return calculateNonlinkedPreferredSize(axis); 2956 } 2957 assert (max == DEFAULT_SIZE); 2958 return getSizeAlongAxis(axis, component.getMaximumSize()); 2959 } 2960 2961 private int getSizeAlongAxis(int axis, Dimension size) { 2962 return (axis == HORIZONTAL) ? size.width : size.height; 2963 } 2964 2965 private int getLinkSize(int axis, int type) { 2966 if (!isVisible()) { 2967 return 0; 2968 } 2969 ComponentInfo ci = getComponentInfo(component); 2970 return ci.getLinkSize(axis, type); 2971 } 2972 2973 void setSize(int axis, int origin, int size) { 2974 super.setSize(axis, origin, size); 2975 this.origin = origin; 2976 if (size == UNSET) { 2977 baseline = -1; 2978 } 2979 } 2980 2981 int getOrigin() { 2982 return origin; 2983 } 2984 2985 void setComponent(Component component) { 2986 this.component = component; 2987 } 2988 2989 Component getComponent() { 2990 return component; 2991 } 2992 2993 int getBaseline() { 2994 if (baseline == -1) { 2995 Spring horizontalSpring = getComponentInfo(component). 2996 horizontalSpring; 2997 int width = horizontalSpring.getPreferredSize(HORIZONTAL); 2998 int height = getPreferredSize(VERTICAL); 2999 if (width > 0 && height > 0) { 3000 baseline = component.getBaseline(width, height); 3001 } 3002 } 3003 return baseline; 3004 } 3005 3006 BaselineResizeBehavior getBaselineResizeBehavior() { 3007 return getComponent().getBaselineResizeBehavior(); 3008 } 3009 3010 private boolean isLinked(int axis) { 3011 return getComponentInfo(component).isLinked(axis); 3012 } 3013 3014 void installIfNecessary(int axis) { 3015 if (!installed) { 3016 installed = true; 3017 if (axis == HORIZONTAL) { 3018 getComponentInfo(component).horizontalSpring = this; 3019 } else { 3020 getComponentInfo(component).verticalSpring = this; 3021 } 3022 } 3023 } 3024 } 3025 3026 3027 3030 private class PreferredGapSpring extends Spring { 3031 private final JComponent source; 3032 private final JComponent target; 3033 private final ComponentPlacement type; 3034 private final int pref; 3035 private final int max; 3036 3037 PreferredGapSpring(JComponent source, JComponent target, 3038 ComponentPlacement type, int pref, int max) { 3039 this.source = source; 3040 this.target = target; 3041 this.type = type; 3042 this.pref = pref; 3043 this.max = max; 3044 } 3045 3046 int calculateMinimumSize(int axis) { 3047 return getPadding(axis); 3048 } 3049 3050 int calculatePreferredSize(int axis) { 3051 if (pref == DEFAULT_SIZE || pref == PREFERRED_SIZE) { 3052 return getMinimumSize(axis); 3053 } 3054 int min = getMinimumSize(axis); 3055 int max = getMaximumSize(axis); 3056 return Math.min(max, Math.max(min, pref)); 3057 } 3058 3059 int calculateMaximumSize(int axis) { 3060 if (max == PREFERRED_SIZE || max == DEFAULT_SIZE) { 3061 return getPadding(axis); 3062 } 3063 return Math.max(getMinimumSize(axis), max); 3064 } 3065 3066 private int getPadding(int axis) { 3067 int position; 3068 if (axis == HORIZONTAL) { 3069 position = SwingConstants.EAST; 3070 } else { 3071 position = SwingConstants.SOUTH; 3072 } 3073 return getLayoutStyle0().getPreferredGap(source, 3074 target, type, position, host); 3075 } 3076 } 3077 3078 3079 3082 private class GapSpring extends Spring { 3083 private final int min; 3084 private final int pref; 3085 private final int max; 3086 3087 GapSpring(int min, int pref, int max) { 3088 checkSize(min, pref, max, false); 3089 this.min = min; 3090 this.pref = pref; 3091 this.max = max; 3092 } 3093 3094 int calculateMinimumSize(int axis) { 3095 if (min == PREFERRED_SIZE) { 3096 return getPreferredSize(axis); 3097 } 3098 return min; 3099 } 3100 3101 int calculatePreferredSize(int axis) { 3102 return pref; 3103 } 3104 3105 int calculateMaximumSize(int axis) { 3106 if (max == PREFERRED_SIZE) { 3107 return getPreferredSize(axis); 3108 } 3109 return max; 3110 } 3111 } 3112 3113 3114 3120 private class AutoPreferredGapSpring extends Spring { 3121 List<ComponentSpring> sources; 3122 ComponentSpring source; 3123 private List<AutoPreferredGapMatch> matches; 3124 int size; 3125 int lastSize; 3126 private final int pref; 3127 private final int max; 3128 private ComponentPlacement type; 3130 private boolean userCreated; 3131 3132 private AutoPreferredGapSpring() { 3133 this.pref = PREFERRED_SIZE; 3134 this.max = PREFERRED_SIZE; 3135 this.type = ComponentPlacement.RELATED; 3136 } 3137 3138 AutoPreferredGapSpring(int pref, int max) { 3139 this.pref = pref; 3140 this.max = max; 3141 } 3142 3143 AutoPreferredGapSpring(ComponentPlacement type, int pref, int max) { 3144 this.type = type; 3145 this.pref = pref; 3146 this.max = max; 3147 this.userCreated = true; 3148 } 3149 3150 public void setSource(ComponentSpring source) { 3151 this.source = source; 3152 } 3153 3154 public void setSources(List<ComponentSpring> sources) { 3155 this.sources = new ArrayList<ComponentSpring>(sources); 3156 } 3157 3158 public void setUserCreated(boolean userCreated) { 3159 this.userCreated = userCreated; 3160 } 3161 3162 public boolean getUserCreated() { 3163 return userCreated; 3164 } 3165 3166 void unset() { 3167 lastSize = getSize(); 3168 super.unset(); 3169 size = 0; 3170 } 3171 3172 public void reset() { 3173 size = 0; 3174 sources = null; 3175 source = null; 3176 matches = null; 3177 } 3178 3179 public void calculatePadding(int axis) { 3180 size = UNSET; 3181 int maxPadding = UNSET; 3182 if (matches != null) { 3183 LayoutStyle p = getLayoutStyle0(); 3184 int position; 3185 if (axis == HORIZONTAL) { 3186 if (isLeftToRight()) { 3187 position = SwingConstants.EAST; 3188 } else { 3189 position = SwingConstants.WEST; 3190 } 3191 } else { 3192 position = SwingConstants.SOUTH; 3193 } 3194 for (int i = matches.size() - 1; i >= 0; i--) { 3195 AutoPreferredGapMatch match = matches.get(i); 3196 maxPadding = Math.max(maxPadding, 3197 calculatePadding(p, position, match.source, 3198 match.target)); 3199 } 3200 } 3201 if (size == UNSET) { 3202 size = 0; 3203 } 3204 if (maxPadding == UNSET) { 3205 maxPadding = 0; 3206 } 3207 if (lastSize != UNSET) { 3208 size += Math.min(maxPadding, lastSize); 3209 } 3210 } 3211 3212 private int calculatePadding(LayoutStyle p, int position, 3213 ComponentSpring source, 3214 ComponentSpring target) { 3215 int delta = target.getOrigin() - (source.getOrigin() + 3216 source.getSize()); 3217 if (delta >= 0) { 3218 int padding; 3219 if ((source.getComponent() instanceof JComponent ) && 3220 (target.getComponent() instanceof JComponent )) { 3221 padding = p.getPreferredGap( 3222 (JComponent )source.getComponent(), 3223 (JComponent )target.getComponent(), type, position, 3224 host); 3225 } else { 3226 padding = 10; 3227 } 3228 if (padding > delta) { 3229 size = Math.max(size, padding - delta); 3230 } 3231 return padding; 3232 } 3233 return 0; 3234 } 3235 3236 public void addTarget(ComponentSpring spring, int axis) { 3237 int oAxis = (axis == HORIZONTAL) ? VERTICAL : HORIZONTAL; 3238 if (source != null) { 3239 if (areParallelSiblings(source.getComponent(), 3240 spring.getComponent(), oAxis)) { 3241 addValidTarget(source, spring); 3242 } 3243 } else { 3244 Component component = spring.getComponent(); 3245 for (int counter = sources.size() - 1; counter >= 0; 3246 counter--){ 3247 ComponentSpring source = sources.get(counter); 3248 if (areParallelSiblings(source.getComponent(), 3249 component, oAxis)) { 3250 addValidTarget(source, spring); 3251 } 3252 } 3253 } 3254 } 3255 3256 private void addValidTarget(ComponentSpring source, 3257 ComponentSpring target) { 3258 if (matches == null) { 3259 matches = new ArrayList<AutoPreferredGapMatch>(1); 3260 } 3261 matches.add(new AutoPreferredGapMatch(source, target)); 3262 } 3263 3264 int calculateMinimumSize(int axis) { 3265 return size; 3266 } 3267 3268 int calculatePreferredSize(int axis) { 3269 if (pref == PREFERRED_SIZE || pref == DEFAULT_SIZE) { 3270 return size; 3271 } 3272 return Math.max(size, pref); 3273 } 3274 3275 int calculateMaximumSize(int axis) { 3276 if (max >= 0) { 3277 return Math.max(getPreferredSize(axis), max); 3278 } 3279 return size; 3280 } 3281 3282 String getMatchDescription() { 3283 return (matches == null) ? "" : matches.toString(); 3284 } 3285 3286 public String toString() { 3287 return super.toString() + getMatchDescription(); 3288 } 3289 } 3290 3291 3292 3296 private final static class AutoPreferredGapMatch { 3297 public final ComponentSpring source; 3298 public final ComponentSpring target; 3299 3300 AutoPreferredGapMatch(ComponentSpring source, ComponentSpring target) { 3301 this.source = source; 3302 this.target = target; 3303 } 3304 3305 private String toString(ComponentSpring spring) { 3306 return spring.getComponent().getName(); 3307 } 3308 3309 public String toString() { 3310 return "[" + toString(source) + "-" + toString(target) + "]"; 3311 } 3312 } 3313 3314 3315 3318 private class ContainerAutoPreferredGapSpring extends 3319 AutoPreferredGapSpring { 3320 private List<ComponentSpring> targets; 3321 3322 ContainerAutoPreferredGapSpring() { 3323 super(); 3324 setUserCreated(true); 3325 } 3326 3327 ContainerAutoPreferredGapSpring(int pref, int max) { 3328 super(pref, max); 3329 setUserCreated(true); 3330 } 3331 3332 public void addTarget(ComponentSpring spring, int axis) { 3333 if (targets == null) { 3334 targets = new ArrayList<ComponentSpring>(1); 3335 } 3336 targets.add(spring); 3337 } 3338 3339 public void calculatePadding(int axis) { 3340 LayoutStyle p = getLayoutStyle0(); 3341 int maxPadding = 0; 3342 int position; 3343 size = 0; 3344 if (targets != null) { 3345 if (axis == HORIZONTAL) { 3347 if (isLeftToRight()) { 3348 position = SwingConstants.WEST; 3349 } else { 3350 position = SwingConstants.EAST; 3351 } 3352 } else { 3353 position = SwingConstants.SOUTH; 3354 } 3355 for (int i = targets.size() - 1; i >= 0; i--) { 3356 ComponentSpring targetSpring = targets.get(i); 3357 int padding = 10; 3358 if (targetSpring.getComponent() instanceof JComponent ) { 3359 padding = p.getContainerGap( 3360 (JComponent )targetSpring.getComponent(), 3361 position, host); 3362 maxPadding = Math.max(padding, maxPadding); 3363 padding -= targetSpring.getOrigin(); 3364 } else { 3365 maxPadding = Math.max(padding, maxPadding); 3366 } 3367 size = Math.max(size, padding); 3368 } 3369 } else { 3370 if (axis == HORIZONTAL) { 3372 if (isLeftToRight()) { 3373 position = SwingConstants.EAST; 3374 } else { 3375 position = SwingConstants.WEST; 3376 } 3377 } else { 3378 position = SwingConstants.SOUTH; 3379 } 3380 if (sources != null) { 3381 for (int i = sources.size() - 1; i >= 0; i--) { 3382 ComponentSpring sourceSpring = sources.get(i); 3383 maxPadding = Math.max(maxPadding, 3384 updateSize(p, sourceSpring, position)); 3385 } 3386 } else if (source != null) { 3387 maxPadding = updateSize(p, source, position); 3388 } 3389 } 3390 if (lastSize != UNSET) { 3391 size += Math.min(maxPadding, lastSize); 3392 } 3393 } 3394 3395 private int updateSize(LayoutStyle p, ComponentSpring sourceSpring, 3396 int position) { 3397 int padding = 10; 3398 if (sourceSpring.getComponent() instanceof JComponent ) { 3399 padding = p.getContainerGap( 3400 (JComponent )sourceSpring.getComponent(), position, 3401 host); 3402 } 3403 int delta = Math.max(0, getParent().getSize() - 3404 sourceSpring.getSize() - sourceSpring.getOrigin()); 3405 size = Math.max(size, padding - delta); 3406 return padding; 3407 } 3408 3409 String getMatchDescription() { 3410 if (targets != null) { 3411 return "leading: " + targets.toString(); 3412 } 3413 if (sources != null) { 3414 return "trailing: " + sources.toString(); 3415 } 3416 return "--"; 3417 } 3418 } 3419 3420 3421 private static class LinkInfo { 3424 private final int axis; 3425 private final List<ComponentInfo> linked; 3426 private int size; 3427 3428 LinkInfo(int axis) { 3429 linked = new ArrayList<ComponentInfo>(); 3430 size = UNSET; 3431 this.axis = axis; 3432 } 3433 3434 public void add(ComponentInfo child) { 3435 LinkInfo childMaster = child.getLinkInfo(axis, false); 3436 if (childMaster == null) { 3437 linked.add(child); 3438 child.setLinkInfo(axis, this); 3439 } else if (childMaster != this) { 3440 linked.addAll(childMaster.linked); 3441 for (ComponentInfo childInfo : childMaster.linked) { 3442 childInfo.setLinkInfo(axis, this); 3443 } 3444 } 3445 clearCachedSize(); 3446 } 3447 3448 public void remove(ComponentInfo info) { 3449 linked.remove(info); 3450 info.setLinkInfo(axis, null); 3451 if (linked.size() == 1) { 3452 linked.get(0).setLinkInfo(axis, null); 3453 } 3454 clearCachedSize(); 3455 } 3456 3457 public void clearCachedSize() { 3458 size = UNSET; 3459 } 3460 3461 public int getSize(int axis) { 3462 if (size == UNSET) { 3463 size = calculateLinkedSize(axis); 3464 } 3465 return size; 3466 } 3467 3468 private int calculateLinkedSize(int axis) { 3469 int size = 0; 3470 for (ComponentInfo info : linked) { 3471 ComponentSpring spring; 3472 if (axis == HORIZONTAL) { 3473 spring = info.horizontalSpring; 3474 } else { 3475 assert (axis == VERTICAL); 3476 spring = info.verticalSpring; 3477 } 3478 size = Math.max(size, 3479 spring.calculateNonlinkedPreferredSize(axis)); 3480 } 3481 return size; 3482 } 3483 } 3484 3485 3490 private class ComponentInfo { 3491 private Component component; 3493 3494 ComponentSpring horizontalSpring; 3495 ComponentSpring verticalSpring; 3496 3497 private LinkInfo horizontalMaster; 3501 private LinkInfo verticalMaster; 3502 3503 private boolean visible; 3504 private Boolean honorsVisibility; 3505 3506 ComponentInfo(Component component) { 3507 this.component = component; 3508 updateVisibility(); 3509 } 3510 3511 public void dispose() { 3512 removeSpring(horizontalSpring); 3514 horizontalSpring = null; 3515 removeSpring(verticalSpring); 3516 verticalSpring = null; 3517 if (horizontalMaster != null) { 3519 horizontalMaster.remove(this); 3520 } 3521 if (verticalMaster != null) { 3522 verticalMaster.remove(this); 3523 } 3524 } 3525 3526 void setHonorsVisibility(Boolean honorsVisibility) { 3527 this.honorsVisibility = honorsVisibility; 3528 } 3529 3530 private void removeSpring(Spring spring) { 3531 if (spring != null) { 3532 ((Group)spring.getParent()).springs.remove(spring); 3533 } 3534 } 3535 3536 public boolean isVisible() { 3537 return visible; 3538 } 3539 3540 3545 boolean updateVisibility() { 3546 boolean honorsVisibility; 3547 if (this.honorsVisibility == null) { 3548 honorsVisibility = GroupLayout.this.getHonorsVisibility(); 3549 } else { 3550 honorsVisibility = this.honorsVisibility; 3551 } 3552 boolean newVisible = (honorsVisibility) ? 3553 component.isVisible() : true; 3554 if (visible != newVisible) { 3555 visible = newVisible; 3556 return true; 3557 } 3558 return false; 3559 } 3560 3561 public void setBounds(Insets insets, int parentWidth, boolean ltr) { 3562 int x = horizontalSpring.getOrigin(); 3563 int w = horizontalSpring.getSize(); 3564 int y = verticalSpring.getOrigin(); 3565 int h = verticalSpring.getSize(); 3566 3567 if (!ltr) { 3568 x = parentWidth - x - w; 3569 } 3570 component.setBounds(x + insets.left, y + insets.top, w, h); 3571 } 3572 3573 public void setComponent(Component component) { 3574 this.component = component; 3575 if (horizontalSpring != null) { 3576 horizontalSpring.setComponent(component); 3577 } 3578 if (verticalSpring != null) { 3579 verticalSpring.setComponent(component); 3580 } 3581 } 3582 3583 public Component getComponent() { 3584 return component; 3585 } 3586 3587 3591 public boolean isLinked(int axis) { 3592 if (axis == HORIZONTAL) { 3593 return horizontalMaster != null; 3594 } 3595 assert (axis == VERTICAL); 3596 return (verticalMaster != null); 3597 } 3598 3599 private void setLinkInfo(int axis, LinkInfo linkInfo) { 3600 if (axis == HORIZONTAL) { 3601 horizontalMaster = linkInfo; 3602 } else { 3603 assert (axis == VERTICAL); 3604 verticalMaster = linkInfo; 3605 } 3606 } 3607 3608 public LinkInfo getLinkInfo(int axis) { 3609 return getLinkInfo(axis, true); 3610 } 3611 3612 private LinkInfo getLinkInfo(int axis, boolean create) { 3613 if (axis == HORIZONTAL) { 3614 if (horizontalMaster == null && create) { 3615 new LinkInfo(HORIZONTAL).add(this); 3618 } 3619 return horizontalMaster; 3620 } else { 3621 assert (axis == VERTICAL); 3622 if (verticalMaster == null && create) { 3623 new LinkInfo(VERTICAL).add(this); 3626 } 3627 return verticalMaster; 3628 } 3629 } 3630 3631 public void clearCachedSize() { 3632 if (horizontalMaster != null) { 3633 horizontalMaster.clearCachedSize(); 3634 } 3635 if (verticalMaster != null) { 3636 verticalMaster.clearCachedSize(); 3637 } 3638 } 3639 3640 int getLinkSize(int axis, int type) { 3641 if (axis == HORIZONTAL) { 3642 return horizontalMaster.getSize(axis); 3643 } else { 3644 assert (axis == VERTICAL); 3645 return verticalMaster.getSize(axis); 3646 } 3647 } 3648 3649 } 3650} 3651 | Popular Tags |