1 7 package javax.swing; 8 9 import java.awt.*; 10 import java.util.*; 11 12 163 public class SpringLayout implements LayoutManager2 { 164 private Map componentConstraints = new HashMap(); 165 166 private Spring cyclicReference = Spring.constant(Spring.UNSET); 167 private Set cyclicSprings; 168 private Set acyclicSprings; 169 170 171 174 public static final String NORTH = "North"; 175 176 179 public static final String SOUTH = "South"; 180 181 184 public static final String EAST = "East"; 185 186 189 public static final String WEST = "West"; 190 191 192 298 public static class Constraints { 299 private Spring x; 300 private Spring y; 301 private Spring width; 302 private Spring height; 303 private Spring east; 304 private Spring south; 305 306 private Spring verticalDerived = null; 307 private Spring horizontalDerived = null; 308 309 312 public Constraints() { 313 this(null, null, null, null); 314 } 315 316 326 public Constraints(Spring x, Spring y) { 327 this(x, y, null, null); 328 } 329 330 345 public Constraints(Spring x, Spring y, Spring width, Spring height) { 346 this.x = x; 347 this.y = y; 348 this.width = width; 349 this.height = height; 350 } 351 352 368 public Constraints(Component c) { 369 this.x = Spring.constant(c.getX()); 370 this.y = Spring.constant(c.getY()); 371 this.width = Spring.width(c); 372 this.height = Spring.height(c); 373 } 374 375 private boolean overConstrainedHorizontally() { 376 return (x != null) && (width != null) && (east != null); 377 } 378 379 private boolean overConstrainedVertically() { 380 return (y != null) && (height != null) && (south != null); 381 } 382 383 private Spring sum(Spring s1, Spring s2) { 384 return (s1 == null || s2 == null) ? null : Spring.sum(s1, s2); 385 } 386 387 private Spring difference(Spring s1, Spring s2) { 388 return (s1 == null || s2 == null) ? null : Spring.difference(s1, s2); 389 } 390 391 402 public void setX(Spring x) { 403 this.x = x; 404 horizontalDerived = null; 405 if (overConstrainedHorizontally()) { 406 width = null; 407 } 408 } 409 410 419 public Spring getX() { 420 if (x != null) { 421 return x; 422 } 423 if (horizontalDerived == null) { 424 horizontalDerived = difference(east, width); 425 } 426 return horizontalDerived; 427 } 428 429 440 public void setY(Spring y) { 441 this.y = y; 442 verticalDerived = null; 443 if (overConstrainedVertically()) { 444 height = null; 445 } 446 } 447 448 457 public Spring getY() { 458 if (y != null) { 459 return y; 460 } 461 if (verticalDerived == null) { 462 verticalDerived = difference(south, height); 463 } 464 return verticalDerived; 465 } 466 467 477 public void setWidth(Spring width) { 478 this.width = width; 479 horizontalDerived = null; 480 if (overConstrainedHorizontally()) { 481 east = null; 482 } 483 } 484 485 493 public Spring getWidth() { 494 if (width != null) { 495 return width; 496 } 497 if (horizontalDerived == null) { 498 horizontalDerived = difference(east, x); 499 } 500 return horizontalDerived; 501 } 502 503 513 public void setHeight(Spring height) { 514 this.height = height; 515 verticalDerived = null; 516 if (overConstrainedVertically()) { 517 south = null; 518 } 519 } 520 521 529 public Spring getHeight() { 530 if (height != null) { 531 return height; 532 } 533 if (verticalDerived == null) { 534 verticalDerived = difference(south, y); 535 } 536 return verticalDerived; 537 } 538 539 private void setEast(Spring east) { 540 this.east = east; 541 horizontalDerived = null; 542 if (overConstrainedHorizontally()) { 543 x = null; 544 } 545 } 546 547 private Spring getEast() { 548 if (east != null) { 549 return east; 550 } 551 if (horizontalDerived == null) { 552 horizontalDerived = sum(x, width); 553 } 554 return horizontalDerived; 555 } 556 557 private void setSouth(Spring south) { 558 this.south = south; 559 verticalDerived = null; 560 if (overConstrainedVertically()) { 561 y = null; 562 } 563 } 564 565 private Spring getSouth() { 566 if (south != null) { 567 return south; 568 } 569 if (verticalDerived == null) { 570 verticalDerived = sum(y, height); 571 } 572 return verticalDerived; 573 } 574 575 591 public void setConstraint(String edgeName, Spring s) { 592 edgeName = edgeName.intern(); 593 if (edgeName == "West") { 594 setX(s); 595 } 596 else if (edgeName == "North") { 597 setY(s); 598 } 599 else if (edgeName == "East") { 600 setEast(s); 601 } 602 else if (edgeName == "South") { 603 setSouth(s); 604 } 605 } 606 607 625 public Spring getConstraint(String edgeName) { 626 edgeName = edgeName.intern(); 627 return (edgeName == "West") ? getX() : 628 (edgeName == "North") ? getY() : 629 (edgeName == "East") ? getEast() : 630 (edgeName == "South") ? getSouth() : 631 null; 632 } 633 634 void reset() { 635 if (x != null) x.setValue(Spring.UNSET); 636 if (y != null) y.setValue(Spring.UNSET); 637 if (width != null) width.setValue(Spring.UNSET); 638 if (height != null) height.setValue(Spring.UNSET); 639 if (east != null) east.setValue(Spring.UNSET); 640 if (south != null) south.setValue(Spring.UNSET); 641 if (horizontalDerived != null) horizontalDerived.setValue(Spring.UNSET); 642 if (verticalDerived != null) verticalDerived.setValue(Spring.UNSET); 643 } 644 } 645 646 private static class SpringProxy extends Spring { 647 private String edgeName; 648 private Component c; 649 private SpringLayout l; 650 651 public SpringProxy(String edgeName, Component c, SpringLayout l) { 652 this.edgeName = edgeName; 653 this.c = c; 654 this.l = l; 655 } 656 657 private Spring getConstraint() { 658 return l.getConstraints(c).getConstraint(edgeName); 659 } 660 661 public int getMinimumValue() { 662 return getConstraint().getMinimumValue(); 663 } 664 665 public int getPreferredValue() { 666 return getConstraint().getPreferredValue(); 667 } 668 669 public int getMaximumValue() { 670 return getConstraint().getMaximumValue(); 671 } 672 673 public int getValue() { 674 return getConstraint().getValue(); 675 } 676 677 public void setValue(int size) { 678 getConstraint().setValue(size); 679 } 680 681 boolean isCyclic(SpringLayout l) { 682 return l.isCyclic(getConstraint()); 683 } 684 685 public String toString() { 686 return "SpringProxy for " + edgeName + " edge of " + c.getName() + "."; 687 } 688 } 689 690 693 public SpringLayout() {} 694 695 private void resetCyclicStatuses() { 696 cyclicSprings = new HashSet(); 697 acyclicSprings = new HashSet(); 698 } 699 700 private void setParent(Container p) { 701 resetCyclicStatuses(); 702 Constraints pc = getConstraints(p); 703 704 pc.setX(Spring.constant(0)); 705 pc.setY(Spring.constant(0)); 706 Spring width = pc.getWidth(); 716 if (width instanceof Spring.WidthSpring && ((Spring.WidthSpring )width).c == p) { 717 pc.setWidth(Spring.constant(0, 0, Integer.MAX_VALUE)); 718 } 719 Spring height = pc.getHeight(); 720 if (height instanceof Spring.HeightSpring && ((Spring.HeightSpring )height).c == p) { 721 pc.setHeight(Spring.constant(0, 0, Integer.MAX_VALUE)); 722 } 723 } 724 725 boolean isCyclic(Spring s) { 726 if (s == null) { 727 return false; 728 } 729 if (cyclicSprings.contains(s)) { 730 return true; 731 } 732 if (acyclicSprings.contains(s)) { 733 return false; 734 } 735 cyclicSprings.add(s); 736 boolean result = s.isCyclic(this); 737 if (!result) { 738 acyclicSprings.add(s); 739 cyclicSprings.remove(s); 740 } 741 else { 742 System.err.println(s + " is cyclic. "); 743 } 744 return result; 745 } 746 747 private Spring abandonCycles(Spring s) { 748 return isCyclic(s) ? cyclicReference : s; 749 } 750 751 753 758 public void addLayoutComponent(String name, Component c) {} 759 760 765 public void removeLayoutComponent(Component c) { 766 componentConstraints.remove(c); 767 } 768 769 private static Dimension addInsets(int width, int height, Container p) { 770 Insets i = p.getInsets(); 771 return new Dimension(width + i.left + i.right, height + i.top + i.bottom); 772 } 773 774 public Dimension minimumLayoutSize(Container parent) { 775 setParent(parent); 776 Constraints pc = getConstraints(parent); 777 return addInsets(abandonCycles(pc.getWidth()).getMinimumValue(), 778 abandonCycles(pc.getHeight()).getMinimumValue(), 779 parent); 780 } 781 782 public Dimension preferredLayoutSize(Container parent) { 783 setParent(parent); 784 Constraints pc = getConstraints(parent); 785 return addInsets(abandonCycles(pc.getWidth()).getPreferredValue(), 786 abandonCycles(pc.getHeight()).getPreferredValue(), 787 parent); 788 } 789 790 792 public Dimension maximumLayoutSize(Container parent) { 793 setParent(parent); 794 Constraints pc = getConstraints(parent); 795 return addInsets(abandonCycles(pc.getWidth()).getMaximumValue(), 796 abandonCycles(pc.getHeight()).getMaximumValue(), 797 parent); 798 } 799 800 810 public void addLayoutComponent(Component component, Object constraints) { 811 if (constraints instanceof Constraints) { 812 putConstraints(component, (Constraints)constraints); 813 } 814 } 815 816 819 public float getLayoutAlignmentX(Container p) { 820 return 0.5f; 821 } 822 823 826 public float getLayoutAlignmentY(Container p) { 827 return 0.5f; 828 } 829 830 public void invalidateLayout(Container p) {} 831 832 834 851 public void putConstraint(String e1, Component c1, int pad, String e2, Component c2) { 852 putConstraint(e1, c1, Spring.constant(pad), e2, c2); 853 } 854 855 876 public void putConstraint(String e1, Component c1, Spring s, String e2, Component c2) { 877 putConstraint(e1, c1, Spring.sum(s, getConstraint(e2, c2))); 878 } 879 880 private void putConstraint(String e, Component c, Spring s) { 881 if (s != null) { 882 getConstraints(c).setConstraint(e, s); 883 } 884 } 885 886 private Constraints applyDefaults(Component c, Constraints constraints) { 887 if (constraints == null) { 888 constraints = new Constraints(); 889 } 890 if (constraints.getWidth() == null) { 891 constraints.setWidth(new Spring.WidthSpring (c)); 892 } 893 if (constraints.getHeight() == null) { 894 constraints.setHeight(new Spring.HeightSpring (c)); 895 } 896 if (constraints.getX() == null) { 897 constraints.setX(Spring.constant(0)); 898 } 899 if (constraints.getY() == null) { 900 constraints.setY(Spring.constant(0)); 901 } 902 return constraints; 903 } 904 905 private void putConstraints(Component component, Constraints constraints) { 906 componentConstraints.put(component, applyDefaults(component, constraints)); 907 } 908 909 931 public Constraints getConstraints(Component c) { 932 Constraints result = (Constraints)componentConstraints.get(c); 933 if (result == null) { 934 if (c instanceof javax.swing.JComponent ) { 935 Object cp = ((javax.swing.JComponent )c).getClientProperty(SpringLayout .class); 936 if (cp instanceof Constraints) { 937 return applyDefaults(c, (Constraints)cp); 938 } 939 } 940 result = new Constraints(); 941 putConstraints(c, result); 942 } 943 return result; 944 } 945 946 976 public Spring getConstraint(String edgeName, Component c) { 977 edgeName = edgeName.intern(); 979 return new SpringProxy(edgeName, c, this); 980 } 981 982 public void layoutContainer(Container parent) { 983 setParent(parent); 984 985 int n = parent.getComponentCount(); 986 getConstraints(parent).reset(); 987 for (int i = 0 ; i < n ; i++) { 988 getConstraints(parent.getComponent(i)).reset(); 989 } 990 991 Insets insets = parent.getInsets(); 992 Constraints pc = getConstraints(parent); 993 abandonCycles(pc.getX()).setValue(0); 994 abandonCycles(pc.getY()).setValue(0); 995 abandonCycles(pc.getWidth()).setValue(parent.getWidth() - 996 insets.left - insets.right); 997 abandonCycles(pc.getHeight()).setValue(parent.getHeight() - 998 insets.top - insets.bottom); 999 1000 for (int i = 0 ; i < n ; i++) { 1001 Component c = parent.getComponent(i); 1002 Constraints cc = getConstraints(c); 1003 int x = abandonCycles(cc.getX()).getValue(); 1004 int y = abandonCycles(cc.getY()).getValue(); 1005 int width = abandonCycles(cc.getWidth()).getValue(); 1006 int height = abandonCycles(cc.getHeight()).getValue(); 1007 c.setBounds(insets.left + x, insets.top + y, width, height); 1008 } 1009 } 1010} 1011 | Popular Tags |