1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * @(#)GBLayout.java 1.23 97/09/03 Doug Stein 26 * 27 * Copyright (c) 1996, 2001 by Sun Microsystems, Inc. 28 * All rights reserved. 29 * 30 * Permission to use, copy, modify, and distribute this software 31 * and its documentation for NON-COMMERCIAL purposes and without 32 * fee is hereby granted provided that this copyright notice 33 * appears in all copies. Please refer to the file "copyright.html" 34 * for further important copyright and licensing information. 35 * 36 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF 37 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 38 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 39 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 40 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 41 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. 42 */ 43package sunsoft.jws.visual.rt.awt; 44 45import sunsoft.jws.visual.rt.base.Global; 46 47import java.awt.*; 48import java.util.Hashtable; 49 50class GBLayoutInfo { 51 int width, height; /* number of cells horizontally, vertically */ 52 int startx, starty; /* starting point for layout */ 53 int minWidth[]; /* largest minWidth in each column */ 54 int minHeight[]; /* largest minHeight in each row */ 55 double weightX[]; /* largest weight in each column */ 56 double weightY[]; /* largest weight in each row */ 57 58 GBLayoutInfo(int w, int h) { 59 width = w; 60 height = h; 61 minWidth = new int[w]; 62 minHeight = new int[h]; 63 weightX = new double[w]; 64 weightY = new double[h]; 65 } 66} 67 68/* BEGIN JSTYLED */ 69/** 70 GBLayout is a flexible layout manager 71 that aligns components vertically and horizontally, 72 without requiring that the components be the same size. 73 Each GBLayout uses a rectangular grid of cells, 74 with each component occupying one or more cells 75 (called its < em >display area</em>). 76 Each component managed by a GBLayout 77 is associated with a 78 < a href = java.awt.GBConstraints.html >GBConstraints</a> instance 79 that specifies how the component is laid out 80 within its display area. 81 How a GBLayout places a set of components 82 depends on each component's GBConstraints and minimum size, 83 as well as the preferred size of the components' container. 84 < p> 85 86 To use a GBLayout effectively, 87 you must customize one or more of its components' GBConstraints. 88 You customize a GBConstraints object by setting one or more 89 of its instance variables: 90 < dl> 91 < dt > <a href = java.awt.GBConstraints.html#gridx> gridx</a>, 92 < a href = java.awt.GBConstraints.html#gridy> gridy</a> 93 < dd> Specifies the cell at the upper left of the component's display area, 94 where the upper-left-most cell has address gridx = 0, gridy=0. 95 Use GBConstraints.RELATIVE(the default value) 96 to specify that the component be just placed 97 just to the right of(for gridx) 98 or just below(for gridy) 99 the component that was added to the container 100 just before this component was added. 101 < dt > <a href = java.awt.GBConstraints.html#gridwidth> gridwidth</a>, 102 < a href = java.awt.GBConstraints.html#gridheight> gridheight</a> 103 < dd> Specifies the number of cells in a row(for gridwidth) 104 or column(for gridheight) 105 in the component's display area. 106 The default value is 1. 107 Use GBConstraints.REMAINDER to specify 108 that the component be the last one in its row(for gridwidth) 109 or column(for gridheight). 110 Use GBConstraints.RELATIVE to specify 111 that the component be the next to last one 112 in its row(for gridwidth) or column (for gridheight). 113 < dt> <a href = java.awt.GBConstraints.html#fill>fill</a> 114 < dd> Used when the component's display area 115 is larger than the component's requested size 116 to determine whether(and how) to resize the component. 117 Valid values are 118 GBConstraints.NONE 119 (the default), 120 GBConstraints.HORIZONTAL 121 (make the component wide enough to fill its display area 122 horizontally, but don't change its height), 123 GBConstraints.VERTICAL 124 (make the component tall enough to fill its display area 125 vertically, but don't change its width), 126 and 127 GBConstraints.BOTH 128 (make the component fill its display area entirely). 129 < dt > <a href = java.awt.GBConstraints.html#ipadx> ipadx</a>, 130 < a href = java.awt.GBConstraints.html#ipady> ipady</a> 131 < dd> Specifies the internal padding: 132 how much to add to the minimum size of the component. 133 The width of the component will be at least 134 its minimum width plus ipadx*2 pixels 135 (since the padding applies to both sides of the component). 136 Similarly, the height of the component will be at least 137 the minimum height plus ipady*2 pixels. 138 < dt> <a href = java.awt.GBConstraints.html#insets>insets</a> 139 < dd> Specifies the external padding of the component -- 140 the minimum amount of space between the component 141 and the edges of its display area. 142 < dt> <a href = java.awt.GBConstraints.html#anchor>anchor</a> 143 < dd> Used when the component is smaller than its display area 144 to determine where(within the area) to place the component. 145 Valid values are 146 GBConstraints.CENTER(the default), 147 GBConstraints.NORTH, 148 GBConstraints.NORTHEAST, 149 GBConstraints.EAST, 150 GBConstraints.SOUTHEAST, 151 GBConstraints.SOUTH, 152 GBConstraints.SOUTHWEST, 153 GBConstraints.WEST, and 154 GBConstraints.NORTHWEST. 155 < dt > <a href = java.awt.GBConstraints.html#weightx> weightx</a>, 156 < a href = java.awt.GBConstraints.html#weighty> weighty</a> 157 < dd> Used to determine how to distribute space; 158 this is important for specifying resizing behavior. 159 Unless you specify a weight 160 for at least one component in a row(weightx) 161 and column(weighty), 162 all the components clump together in the center of 163 their container. 164 This is because when the weight is zero(the default), 165 the GBLayout puts any extra space 166 between its grid of cells and the edges of the container. 167 < /dl> 168 169 The following figure shows ten components(all buttons) 170 managed by a GBLayout: 171 < blockquote> 172 < img src = images/java.awt/GridBagEx.gif width=262 height=155> 173 < /blockquote> 174 175 All the components have fill = GBConstraints.BOTH. 176 In addition, the components have the following non-default constraints: 177 < ul> 178 < li >Button1, Button2, Button3: 179 weightx = 1.0 180 < li >Button4: 181 weightx = 1.0, 182 gridwidth = GBConstraints.REMAINDER 183 < li >Button5: 184 gridwidth = GBConstraints.REMAINDER 185 < li >Button6: 186 gridwidth = GBConstraints.RELATIVE 187 < li >Button7: 188 gridwidth = GBConstraints.REMAINDER 189 < li >Button8: 190 gridheight = 2, weighty=1.0, 191 < li >Button9, Button 10: 192 gridwidth = GBConstraints.REMAINDER 193 < /ul> 194 195 Here is the code that implements the example shown above: 196 < blockquote> 197 < pre> 198 import java.awt.*; 199 import java.util.*; 200 import java.applet.Applet; 201 202 public class GridBagEx1 extends Applet { 203 204 protected void makebutton(String name, 205 GBLayout gridbag, 206 GBConstraints c) { 207 Button button = new Button(name); 208 gridbag.setConstraints(button, c); 209 add(button); 210 } 211 212 public void init() { 213 GBLayout gridbag = new GBLayout(); 214 GBConstraints c = new GBConstraints(); 215 216 setFont(new Font("Sansserif", Font.PLAIN, 14)); 217 setLayout(gridbag); 218 219 c.fill = GBConstraints.BOTH; 220 c.weightx = 1.0; 221 makebutton("Button1", gridbag, c); 222 makebutton("Button2", gridbag, c); 223 makebutton("Button3", gridbag, c); 224 225 c.gridwidth = GBConstraints.REMAINDER; // end row 226 makebutton("Button4", gridbag, c); 227 228 c.weightx = 0.0; // reset to the default 229 makebutton("Button5", gridbag, c); // another row 230 231 c.gridwidth = GBConstraints.RELATIVE; // next-to-last in row 232 makebutton("Button6", gridbag, c); 233 234 c.gridwidth = GBConstraints.REMAINDER; // end row 235 makebutton("Button7", gridbag, c); 236 237 c.gridwidth = 1; // reset to the default 238 c.gridheight = 2; 239 c.weighty = 1.0; 240 makebutton("Button8", gridbag, c); 241 242 c.weighty = 0.0; // reset to the default 243 c.gridwidth = GBConstraints.REMAINDER; // end row 244 c.gridheight = 1; // reset to the default 245 makebutton("Button9", gridbag, c); 246 makebutton("Button10", gridbag, c); 247 248 resize(300, 100); 249 } 250 251 public static void main(String args[]) { 252 Frame f = new Frame("GridBag Layout Example"); 253 GridBagEx1 ex1 = new GridBagEx1(); 254 255 ex1.init(); 256 257 f.add("Center", ex1); 258 f.pack(); 259 f.resize(f.getPreferredSize()); 260 f.show(); 261 } 262 } 263 < /pre> 264 < /blockquote> 265 * 266 * @version 1.23, 08/06/97 267 * @author Doug Stein 268 */ 269/* END JSTYLED */ 270public class GBLayout implements LayoutManager { 271 272 /** 273 * Determines the minimum widths for the grid columns. 274 */ 275 public int columnWidths[]; 276 277 /** 278 * Determines the minimum heights for the grid rows. 279 */ 280 public int rowHeights[]; 281 282 /** 283 * Determines the minimum weights for the grid columns. 284 */ 285 public double columnWeights[]; 286 287 /** 288 * Determines the minimum weights for the grid rows. 289 */ 290 public double rowWeights[]; 291 292 protected static final int INITGRIDSIZE = 16; 293 protected static final int MINSIZE = 1; 294 protected static final int PREFERREDSIZE = 2; 295 protected static final int TINYSIZE = 3; 296 297 protected Hashtable comptable; 298 protected GBConstraints defaultConstraints; 299 protected GBLayoutInfo layoutInfo; 300 301 protected int anchor; 302 protected int clipAnchor; 303 304 private static boolean layoutDisabled = false; 305 private static int disableCount = 0; 306 private static Insets windowInsets = new Insets(0, 0, 0, 0); 307 308 /** 309 * Globally enable gridbag layout. The 310 * default is for gridbag layout to 311 * be enabled. 312 */ 313 public synchronized static void enable() { 314 disableCount--; 315 if (disableCount <= 0) 316 layoutDisabled = false; 317 } 318 319 /** 320 * Globally disable gridbag layout. This can be used to improve 321 * performance by temporarily disabling layout during 322 * spurious calls to validate. 323 */ 324 public synchronized static void disable() { 325 disableCount++; 326 if (disableCount > 0) 327 layoutDisabled = true; 328 } 329 330 /** 331 * Set the window insets. The window insets default to (0,0,0,0). 332 */ 333 public synchronized static void setWindowInsets(Insets insets) { 334 if (insets == null) 335 windowInsets = new Insets(0, 0, 0, 0); 336 else 337 windowInsets = (Insets)insets.clone(); 338 } 339 340 /** 341 * Get the window insets. 342 */ 343 public synchronized static Insets getWindowInsets() { 344 return (Insets)windowInsets.clone(); 345 } 346 347 /** 348 * Creates a gridbag layout. 349 */ 350 public GBLayout() { 351 comptable = new Hashtable(); 352 defaultConstraints = new GBConstraints(); 353 354 anchor = GBConstraints.CENTER; 355 clipAnchor = GBConstraints.NORTHWEST; 356 } 357 358 /** 359 * Sets the constraints for the specified component. 360 * @param comp the component to be modified 361 * @param constraints the constraints to be applied 362 */ 363 public void setConstraints(Component comp, 364 GBConstraints constraints) { 365 GBConstraints c = (GBConstraints)constraints.clone(); 366 if (c.insets == null) 367 c.insets = new Insets(0, 0, 0, 0); 368 if (c.hardinsets == null) 369 c.hardinsets = new Insets(0, 0, 0, 0); 370 371 comptable.put(comp, c); 372 } 373 374 /** 375 * Sets the constraints from an option string. 376 * Each option has the form key=value. Options are separated by 377 * semicolons (;). 378 * @param comp the component to be modified 379 * @param constraints the constraints string 380 */ 381 public void setConstraints(Component comp, String constraints) { 382 if (constraints == null) 383 return; 384 385 comptable.put(comp, new GBConstraints(constraints)); 386 } 387 388 /** 389 * Retrieves the constraints for the specified component. A copy of 390 * the constraints is returned. 391 * @param comp the component to be queried 392 */ 393 public GBConstraints getConstraints(Component comp) { 394 GBConstraints constraints = (GBConstraints)comptable.get(comp); 395 if (constraints == null) { 396 setConstraints(comp, defaultConstraints); 397 constraints = (GBConstraints)comptable.get(comp); 398 } 399 return (GBConstraints)constraints.clone(); 400 } 401 402 /** 403 * Retrieves the constraints for the specified 404 * component. The return 405 * value is not a copy, but is the actual constraints 406 * class used by the 407 * layout mechanism. 408 * @param comp the component to be queried 409 */ 410 protected GBConstraints lookupConstraints(Component comp) { 411 GBConstraints constraints = (GBConstraints)comptable.get(comp); 412 if (constraints == null) { 413 setConstraints(comp, defaultConstraints); 414 constraints = (GBConstraints)comptable.get(comp); 415 } 416 return constraints; 417 } 418 419 /** 420 * Returns the coordinates of the upper-left corner of the grid. 421 * The coordinates are based on the current layout of the grid. 422 */ 423 public Point getLayoutOrigin() { 424 Point origin = new Point(0, 0); 425 if (layoutInfo != null) { 426 origin.x = layoutInfo.startx; 427 origin.y = layoutInfo.starty; 428 } 429 return origin; 430 } 431 432 /** 433 * Returns the widths and heights of the grid columns and rows. 434 * The dimensions are based on the current layout of the grid. 435 */ 436 public int [][] getLayoutDimensions() { 437 if (layoutInfo == null) 438 return new int[2][0]; 439 440 int dim[][] = new int [2][]; 441 dim[0] = new int[layoutInfo.width]; 442 dim[1] = new int[layoutInfo.height]; 443 444 System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, 445 layoutInfo.width); 446 System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, 447 layoutInfo.height); 448 449 return dim; 450 } 451 452 /** 453 * Returns the minimum widths and heights of the 454 * grid columns and rows. 455 * This is how the grid would be arranged if the parent were 456 * to be reshaped to its minimum size. 457 */ 458 public int [][] getMinimumLayoutDimensions(Container parent) { 459 GBLayoutInfo info = GetLayoutInfo(parent, MINSIZE); 460 int dim[][] = new int[2][]; 461 dim[0] = new int[info.width]; 462 dim[1] = new int[info.height]; 463 464 System.arraycopy(info.minWidth, 0, dim[0], 0, info.width); 465 System.arraycopy(info.minHeight, 0, dim[1], 0, info.height); 466 467 return dim; 468 } 469 470 /** 471 * Returns the preferred widths and heights of the 472 * grid columns and rows. 473 * This is how the grid would be arranged if the parent were 474 * to be reshaped to its preferred size. 475 */ 476 public int [][] getPreferredLayoutDimensions(Container parent) { 477 GBLayoutInfo info = GetLayoutInfo(parent, PREFERREDSIZE); 478 int dim[][] = new int[2][]; 479 dim[0] = new int[info.width]; 480 dim[1] = new int[info.height]; 481 482 System.arraycopy(info.minWidth, 0, dim[0], 0, info.width); 483 System.arraycopy(info.minHeight, 0, dim[1], 0, info.height); 484 485 return dim; 486 } 487 /* BEGIN JSTYLED */ 488 /** 489 * Returns the current set of weights for the grid 490 * columns and rows. 491 * The return value reflects the effective weights for the columns 492 * and rows after taking into account the weight constraints that 493 * are set on the child components. 494 */ 495 /* END JSTYLED */ 496 public double [][] getLayoutWeights() { 497 if (layoutInfo == null) 498 return new double[2][0]; 499 500 double weights[][] = new double [2][]; 501 weights[0] = new double[layoutInfo.width]; 502 weights[1] = new double[layoutInfo.height]; 503 504 System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, 505 layoutInfo.width); 506 System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, 507 layoutInfo.height); 508 509 return weights; 510 } 511 512 /** 513 * Returns the coordinates of the grid cell corresponding 514 * to the given 515 * pixel coordinates. 516 */ 517 public Point location(int x, int y) { 518 Point loc = new Point(0, 0); 519 int i, d; 520 521 if (layoutInfo == null) 522 return loc; 523 524 d = layoutInfo.startx; 525 for (i = 0; i < layoutInfo.width; i++) { 526 d += layoutInfo.minWidth[i]; 527 if (d > x) 528 break; 529 } 530 loc.x = i; 531 532 d = layoutInfo.starty; 533 for (i = 0; i < layoutInfo.height; i++) { 534 d += layoutInfo.minHeight[i]; 535 if (d > y) 536 break; 537 } 538 loc.y = i; 539 540 return loc; 541 } 542 543 /** 544 * Sets the anchor for the gridbag. The anchor determines 545 * the placement 546 * for the child components when the container 547 * has extra space and none 548 * of the children have weights. The default anchor is CENTER. 549 */ 550 public void setAnchor(int anchor) { 551 this.anchor = anchor; 552 } 553 554 /** 555 * Returns the current anchor. 556 */ 557 public int getAnchor() { 558 return anchor; 559 } 560 561 /** 562 * Sets the clip anchor. The clip anchor determines 563 * which edge(s) of 564 * the container get clipped when there is not enough space. The 565 * default clip anchor is NORTHWEST. A clip anchor 566 * of NORTHWEST means 567 * that northwest corner is anchored, so the south 568 * and east edges will 569 * be clipped if there is not enough space. 570 */ 571 public void setClipAnchor(int clipAnchor) { 572 this.clipAnchor = clipAnchor; 573 } 574 575 /** 576 * Returns the current clip anchor. 577 */ 578 public int getClipAnchor() { 579 return clipAnchor; 580 } 581 582 /** 583 * If the parent is a Window, then adjust the insets according to 584 * the window insets. 585 */ 586 private Insets getInsets(Container parent) { 587 Insets parentInsets = parent.insets(); 588 Insets insets = null; 589 if (parentInsets != null) { 590 insets = (Insets) parentInsets.clone(); 591 } else { 592 insets = new Insets(0, 0, 0, 0); 593 } 594 if (parent instanceof Window) { 595 insets.top += windowInsets.top; 596 insets.bottom += windowInsets.bottom; 597 insets.left += windowInsets.left; 598 insets.right += windowInsets.right; 599 } 600 return insets; 601 } 602 603 /** 604 * Adds the specified component with the specified 605 * name to the layout. 606 * The name is converted to a set of GBConstraints. 607 * @param name the constraints string 608 * @param comp the component to be added 609 */ 610 public void addLayoutComponent(String name, Component comp) { 611 setConstraints(comp, name); 612 } 613 614 /** 615 * Removes the specified component from the layout. Does not apply. 616 * @param comp the component to be removed 617 */ 618 public void removeLayoutComponent(Component comp) { 619 } 620 621 /** 622 * Returns the preferred dimensions for this layout 623 * given the components 624 * in the specified panel. 625 * @param parent the component which needs to be laid out 626 * @see #minimumLayoutSize 627 */ 628 public Dimension preferredLayoutSize(Container parent) { 629 GBLayoutInfo info = GetLayoutInfo(parent, PREFERREDSIZE); 630 return GetMinSize(parent, info); 631 } 632 633 /** 634 * Returns the minimum dimensions needed to layout the components 635 * contained in the specified panel. 636 * @param parent the component which needs to be laid out 637 * @see #preferredLayoutSize 638 */ 639 public Dimension minimumLayoutSize(Container parent) { 640 GBLayoutInfo info = GetLayoutInfo(parent, MINSIZE); 641 return GetMinSize(parent, info); 642 } 643 644 /** 645 * Returns the smallest allowable size for the specified panel. 646 * This can be smaller than getMinimumSize if there are insets and 647 * pads set on any of the panel's children. 648 * @param parent the component which needs to be laid out 649 * @see #preferredLayoutSize 650 */ 651 public Dimension tinyLayoutSize(Container parent) { 652 GBLayoutInfo info = GetLayoutInfo(parent, TINYSIZE); 653 return GetMinSize(parent, info); 654 } 655 656 /** 657 * Lays out the container in the specified panel. 658 * @param parent the specified component being laid out 659 * @see Container 660 */ 661 public void layoutContainer(Container parent) { 662 if (!layoutDisabled) 663 ArrangeGrid(parent, true); 664 } 665 666 /** 667 * Does everything that layout normally does, except the components 668 * aren't actually reshaped. This has the useful side effect of 669 * setting the location and size variables in the constraints 670 * for each component. 671 * @param parent the specified component being laid out 672 * @see Container 673 */ 674 public void layoutContainerNoReshape(Container parent) { 675 if (!layoutDisabled) 676 ArrangeGrid(parent, false); 677 } 678 679 /** 680 * Returns the String representation of this GBLayout's values. 681 */ 682 public String toString() { 683 return getClass().getName(); 684 } 685 /* BEGIN JSTYLED */ 686 /** 687 * Print the layout information. Useful for debugging. 688 */ 689 690 /* DEBUG 691 * 692 * protected void DumpLayoutInfo(GBLayoutInfo s) { 693 * int x; 694 * 695 * System.out.println("Col\tWidth\tWeight"); 696 * for (x=0; x<s.width; x++) { 697 * System.out.println(x + "\t" + 698 * s.minWidth[x] + "\t" + 699 * s.weightX[x]); 700 * } 701 * System.out.println("Row\tHeight\tWeight"); 702 * for (x=0; x<s.height; x++) { 703 * System.out.println(x + "\t" + 704 * s.minHeight[x] + "\t" + 705 * s.weightY[x]); 706 * } 707 * } 708 */ 709 710 /** 711 * Print the layout constraints. Useful for debugging. 712 */ 713 714 /* DEBUG 715 * 716 * protected void DumpConstraints(GBConstraints constraints) { 717 * System.out.println( 718 * "wt " + 719 * constraints.weightx + 720 * " " + 721 * constraints.weighty + 722 * ", " + 723 * 724 * "box " + 725 * constraints.gridx + 726 * " " + 727 * constraints.gridy + 728 * " " + 729 * constraints.gridwidth + 730 * " " + 731 * constraints.gridheight + 732 * ", " + 733 * 734 * "min " + 735 * constraints.minWidth + 736 * " " + 737 * constraints.minHeight + 738 * ", " + 739 * 740 * "pad " + 741 * constraints.insets.bottom + 742 * " " + 743 * constraints.insets.left + 744 * " " + 745 * constraints.insets.right + 746 * " " + 747 * constraints.insets.top + 748 * " " + 749 * constraints.ipadx + 750 * " " + 751 * constraints.ipady); 752 * } 753 */ 754 755 /** 756 * Fill in an instance of the GBLayoutInfo structure for the 757 * current set of managed children. This requires four passes 758 * through the child components: 759 *<pre> 760 * 1) Figure out the dimensions of the layout grid. 761 * 2) Determine which cells the components occupy. 762 * 3) Distribute the weights among the rows/columns. 763 * 4) Distribute the minimum sizes among the rows/columns. 764 *</pre> 765 * This also caches the minsizes for all the children when they are 766 * first encountered (so subsequent loops don't need to ask again). 767 */ 768 769 /* END JSTYLED */ 770 protected GBLayoutInfo GetLayoutInfo(Container parent, 771 int sizeflag) { 772 Component comp; 773 GBConstraints constraints; 774 Dimension d; 775 Component components[] = parent.getComponents(); 776 777 int compindex, width, height, i, j, k, px, py; 778 int limit, pixels_diff, nextSize; 779 int curX, curY, curWidth, curHeight, curRow, curCol; 780 double weight_diff, weight, start, size; 781 int xMax[], yMax[]; 782 783 /* BEGIN JSTYLED */ 784 /* 785 * Pass #1 786 * 787 * Figure out the dimensions of the layout 788 * grid (use a value of 1 for 789 * zero or negative widths and heights). 790 */ 791 /* END JSTYLED */ 792 793 width = height = 0; 794 curRow = curCol = -1; 795 xMax = new int[INITGRIDSIZE]; 796 yMax = new int[INITGRIDSIZE]; 797 798 for (compindex = 0; compindex < components.length; compindex++) { 799 comp = components[compindex]; 800 if (!comp.isVisible()) 801 continue; 802 constraints = lookupConstraints(comp); 803 804 curX = constraints.gridx; 805 curY = constraints.gridy; 806 curWidth = constraints.gridwidth; 807 if (curWidth <= 0) 808 curWidth = 1; 809 curHeight = constraints.gridheight; 810 if (curHeight <= 0) 811 curHeight = 1; 812 813 /* If x or y is negative, then use relative positioning: */ 814 if (curX < 0 && curY < 0) { 815 if (curRow >= 0) 816 curY = curRow; 817 else if (curCol >= 0) 818 curX = curCol; 819 else 820 curY = 0; 821 } 822 if (curX < 0) { 823 px = 0; 824 limit = curY + curHeight; 825 xMax = ensureCapacity(xMax, limit); 826 for (i = curY; i < limit; i++) 827 px = Math.max(px, xMax[i]); 828 829 curX = px - curX - 1; 830 if (curX < 0) 831 curX = 0; 832 } else if (curY < 0) { 833 py = 0; 834 limit = curX + curWidth; 835 yMax = ensureCapacity(yMax, limit); 836 for (i = curX; i < limit; i++) 837 py = Math.max(py, yMax[i]); 838 839 curY = py - curY - 1; 840 if (curY < 0) 841 curY = 0; 842 } 843 844 /* Adjust the grid width and height */ 845 for (px = curX + curWidth; width < px; width++); 846 for (py = curY + curHeight; height < py; height++); 847 848 /* Adjust the xMax and yMax arrays */ 849 yMax = ensureCapacity(yMax, px); 850 xMax = ensureCapacity(xMax, py); 851 for (i = curX; i < px; i++) { yMax[i] = py; } 852 for (i = curY; i < py; i++) { xMax[i] = px; } 853 854 /* Cache the current slave's size. */ 855 if (sizeflag == TINYSIZE) { 856 if (comp instanceof Container) { 857 Container cntr = (Container)comp; 858 if (cntr.getLayout() instanceof GBLayout) 859 d = ((GBLayout)cntr.getLayout()).tinyLayoutSize(cntr); 860 else 861 d = comp.getMinimumSize(); 862 } 863 else 864 d = comp.getMinimumSize(); 865 866 constraints.tinyWidth = d.width; 867 constraints.tinyHeight = d.height; 868 869 if (constraints.shrinkx) 870 constraints.tinyWidth = 0; 871 if (constraints.shrinky) 872 constraints.tinyHeight = 0; 873 874 if (constraints.minsize == null) { 875 d = comp.getMinimumSize(); 876 constraints.minsize = new Dimension(d.width, 877 d.height); 878 } 879 } else { 880 if (sizeflag == PREFERREDSIZE) { 881 d = comp.getPreferredSize(); 882 if (d.width <= 1 && d.height <= 1) { 883 // If the preferred size is not reasonable 884 // then try the minumum size 885 d = comp.getMinimumSize(); 886 if (d.width <= 1 && d.height <= 1) { 887 // Both preferred and minimun size 888 // are small so use the actual size 889 // that was set for the component. 890 d = comp.getSize(); 891 } 892 } 893 constraints.minsize = new Dimension(d.width, 894 d.height); 895 } else { 896 d = comp.getMinimumSize(); 897 // If the component is less than 1,1 minumum 898 // size then 899 // use getPreferredSize instead. This is 900 // a workaround for 901 // Beans that do not have getMinimumSize 902 // implemented. 903 if (d.width <= 1 && d.height <= 1) { 904 d = comp.getPreferredSize(); 905 if (d.width <= 1 && d.height <= 1) { 906 d = comp.getSize(); 907 } 908 } 909 constraints.minsize = new Dimension(d.width, 910 d.height); 911 } 912 } 913 /* BEGIN JSTYLED */ 914 /* 915 * Zero width and height must mean that this is 916 * the last item (or 917 * else something is wrong). 918 */ 919 if (constraints.gridheight == 0 && 920 constraints.gridwidth == 0) 921 curRow = curCol = -1; 922 923 /* Zero width starts a new row */ 924 if (constraints.gridheight == 0 && curRow < 0) 925 curCol = curX + curWidth; 926 927 /* Zero height starts a new column */ 928 else if (constraints.gridwidth == 0 && curCol < 0) 929 curRow = curY + curHeight; 930 } 931 932 /* 933 * Apply minimum row/column dimensions 934 */ 935 /* END JSTYLED */ 936 if (columnWidths != null && width < columnWidths.length) 937 width = columnWidths.length; 938 if (rowHeights != null && height < rowHeights.length) 939 height = rowHeights.length; 940 941 GBLayoutInfo r = new GBLayoutInfo(width, height); 942 943 /* 944 * Pass #2 945 * 946 * Negative values for gridX are filled in with 947 * the current x value. 948 * Negative values for gridY are filled in with 949 * the current y value. 950 * Negative or zero values for gridWidth and 951 * gridHeight end the current 952 * row or column, respectively. 953 * 954 * Pass #1 figures out the grid dimensions. 955 * Pass #2 replaces the 956 * negative and zero values for gridWidth and gridHeight with 957 * real values that are based on the grid dimensions determined 958 * in pass #1. 959 */ 960 961 curRow = curCol = -1; 962 xMax = new int[height]; 963 yMax = new int[width]; 964 965 for (compindex = 0; compindex < components.length; 966 compindex++) { 967 comp = components[compindex]; 968 if (!comp.isVisible()) 969 continue; 970 constraints = lookupConstraints(comp); 971 972 curX = constraints.gridx; 973 curY = constraints.gridy; 974 curWidth = constraints.gridwidth; 975 curHeight = constraints.gridheight; 976 977 /* If x or y is negative, then use relative positioning: */ 978 if (curX < 0 && curY < 0) { 979 if (curRow >= 0) 980 curY = curRow; 981 else if (curCol >= 0) 982 curX = curCol; 983 else 984 curY = 0; 985 } 986 987 if (curX < 0) { 988 if (curHeight <= 0) { 989 curHeight += r.height - curY; 990 if (curHeight < 1) 991 curHeight = 1; 992 } 993 994 px = 0; 995 for (i = curY; i < (curY + curHeight); i++) 996 px = Math.max(px, xMax[i]); 997 998 curX = px - curX - 1; 999 if (curX < 0) 1000 curX = 0; 1001 } else if (curY < 0) { 1002 if (curWidth <= 0) { 1003 curWidth += r.width - curX; 1004 if (curWidth < 1) 1005 curWidth = 1; 1006 } 1007 1008 py = 0; 1009 for (i = curX; i < (curX + curWidth); i++) 1010 py = Math.max(py, yMax[i]); 1011 1012 curY = py - curY - 1; 1013 if (curY < 0) 1014 curY = 0; 1015 } 1016 1017 if (curWidth <= 0) { 1018 curWidth += r.width - curX; 1019 if (curWidth < 1) 1020 curWidth = 1; 1021 } 1022 1023 if (curHeight <= 0) { 1024 curHeight += r.height - curY; 1025 if (curHeight < 1) 1026 curHeight = 1; 1027 } 1028 1029 px = curX + curWidth; 1030 py = curY + curHeight; 1031 1032 for (i = curX; i < px; i++) { yMax[i] = py; } 1033 for (i = curY; i < py; i++) { xMax[i] = px; } 1034 1035 /* Make negative sizes start a new row/column */ 1036 if (constraints.gridheight == 0 && 1037 constraints.gridwidth == 0) 1038 curRow = curCol = -1; 1039 if (constraints.gridheight == 0 && curRow < 0) 1040 curCol = curX + curWidth; 1041 else if (constraints.gridwidth == 0 && curCol < 0) 1042 curRow = curY + curHeight; 1043 1044 /* Assign the new values to the gridbag slave */ 1045 constraints.tempX = curX; 1046 constraints.tempY = curY; 1047 constraints.tempWidth = curWidth; 1048 constraints.tempHeight = curHeight; 1049 } 1050 1051 /* 1052 * Apply row/column weights. 1053 */ 1054 1055 if (columnWeights != null) 1056 System.arraycopy(columnWeights, 0, r.weightX, 0, 1057 Math.min(columnWeights.length, r.weightX.length)); 1058 if (rowWeights != null) 1059 System.arraycopy(rowWeights, 0, r.weightY, 0, 1060 Math.min(rowWeights.length, r.weightY.length)); 1061 1062 /* 1063 * Pass #3 1064 * 1065 * Distribute the weights. 1066 */ 1067 1068 nextSize = Integer.MAX_VALUE; 1069 1070 for (i = 1; 1071 i != Integer.MAX_VALUE; 1072 i = nextSize, nextSize = Integer.MAX_VALUE) { 1073 for (compindex = 0; compindex < components.length; 1074 compindex++) { 1075 comp = components[compindex]; 1076 if (!comp.isVisible()) 1077 continue; 1078 constraints = lookupConstraints(comp); 1079 1080 if (constraints.tempWidth == i) { 1081 px = constraints.tempX + constraints.tempWidth; 1082 /* right column */ 1083 1084 /* 1085 * Figure out if we should use this slave\'s 1086 * weight. If the weight 1087 * is less than the total weight spanned 1088 * by the width of the cell, 1089 * then discard the weight. Otherwise 1090 * split the difference 1091 * according to the existing weights. 1092 */ 1093 1094 weight_diff = constraints.weightx; 1095 for (k = constraints.tempX; k < px; k++) 1096 weight_diff -= r.weightX[k]; 1097 if (weight_diff > 0.0) { 1098 weight = 0.0; 1099 for (k = constraints.tempX; k < px; k++) 1100 weight += r.weightX[k]; 1101 for (k = constraints.tempX; weight > 0.0 1102 && k < px; k++) { 1103 double wt = r.weightX[k]; 1104 double dx = (wt * weight_diff) / weight; 1105 r.weightX[k] += dx; 1106 weight_diff -= dx; 1107 weight -= wt; 1108 } 1109 /* BEGIN JSTYLED */ 1110 /* Assign the remainder to the 1111 * rightmost cell */ 1112 /* END JSTYLED */ 1113 r.weightX[px-1] += weight_diff; 1114 } 1115 } else if (constraints.tempWidth > i && 1116 constraints.tempWidth < nextSize) 1117 nextSize = constraints.tempWidth; 1118 1119 1120 if (constraints.tempHeight == i) { 1121 py = constraints.tempY + constraints.tempHeight; 1122 /* bottom row */ 1123 1124 /* 1125 * Figure out if we should use this slave\'s 1126 * weight. If the weight 1127 * is less than the total weight spanned by 1128 * the height of the cell, 1129 * then discard the weight. Otherwise split 1130 * it the difference 1131 * according to the existing weights. 1132 */ 1133 1134 weight_diff = constraints.weighty; 1135 for (k = constraints.tempY; k < py; k++) 1136 weight_diff -= r.weightY[k]; 1137 if (weight_diff > 0.0) { 1138 weight = 0.0; 1139 for (k = constraints.tempY; k < py; k++) 1140 weight += r.weightY[k]; 1141 for (k = constraints.tempY; weight > 0.0 1142 && k < py; k++) { 1143 double wt = r.weightY[k]; 1144 double dy = (wt * weight_diff) / weight; 1145 r.weightY[k] += dy; 1146 weight_diff -= dy; 1147 weight -= wt; 1148 } 1149 /* Assign the remainder to the bottom cell */ 1150 r.weightY[py-1] += weight_diff; 1151 } 1152 } else if (constraints.tempHeight > i && 1153 constraints.tempHeight < nextSize) 1154 nextSize = constraints.tempHeight; 1155 } 1156 } 1157 1158 /* 1159 * Apply minimum row/column widths. 1160 */ 1161 1162 if (sizeflag == TINYSIZE) { 1163 if (columnWidths != null) { 1164 for (i = 0; i < columnWidths.length; i++) { 1165 if (r.weightX[i] == 0) 1166 r.minWidth[i] = columnWidths[i]; 1167 } 1168 } 1169 if (rowHeights != null) { 1170 for (i = 0; i < rowHeights.length; i++) { 1171 if (r.weightY[i] == 0) 1172 r.minHeight[i] = rowHeights[i]; 1173 } 1174 } 1175 } else { 1176 if (columnWidths != null) 1177 System.arraycopy(columnWidths, 0, r.minWidth, 0, 1178 columnWidths.length); 1179 if (rowHeights != null) 1180 System.arraycopy(rowHeights, 0, r.minHeight, 0, 1181 rowHeights.length); 1182 } 1183 1184 /* 1185 * Pass #4 1186 * 1187 * Distribute the minimum widths. 1188 */ 1189 1190 nextSize = Integer.MAX_VALUE; 1191 1192 for (i = 1; 1193 i != Integer.MAX_VALUE; 1194 i = nextSize, nextSize = Integer.MAX_VALUE) { 1195 for (compindex = 0; compindex < components.length; 1196 compindex++) { 1197 comp = components[compindex]; 1198 if (!comp.isVisible()) 1199 continue; 1200 constraints = lookupConstraints(comp); 1201 1202 if (constraints.tempWidth == i) { 1203 px = constraints.tempX + constraints.tempWidth; 1204 /* right column */ 1205 1206 /* 1207 * Calculate the minWidth array values. 1208 * First, figure out how wide the current 1209 * slave needs to be. 1210 * Then, see if it will fit within the 1211 * current minWidth values. 1212 * If it will not fit, add the difference 1213 * according to the 1214 * weightX array. 1215 */ 1216 1217 if (sizeflag == TINYSIZE && hasWeightX(r, 1218 constraints)) { 1219 pixels_diff = constraints.tinyWidth 1220 + constraints.hardipadx + 1221 constraints.hardinsets.left + 1222 constraints.hardinsets.right; 1223 } else { 1224 pixels_diff = constraints.minsize.width + 1225 constraints.ipadx + constraints.hardipadx + 1226 constraints.insets.left + 1227 constraints.insets.right + 1228 constraints.hardinsets.left + 1229 constraints.hardinsets.right; 1230 } 1231 1232 for (k = constraints.tempX; k < px; k++) 1233 pixels_diff -= r.minWidth[k]; 1234 if (pixels_diff > 0) { 1235 weight = 0.0; 1236 for (k = constraints.tempX; k < px; k++) 1237 weight += r.weightX[k]; 1238 for (k = constraints.tempX; weight > 0.0 && 1239 k < px; k++) { 1240 double wt = r.weightX[k]; 1241 int dx = (int)((wt * ((double) 1242 pixels_diff)) / weight); 1243 r.minWidth[k] += dx; 1244 pixels_diff -= dx; 1245 weight -= wt; 1246 } 1247 1248 /* Any leftovers are evenly distributed */ 1249 int dx = pixels_diff/(px-constraints.tempX); 1250 for (k = constraints.tempX; k < (px-1); k++) { 1251 r.minWidth[k] += dx; 1252 pixels_diff -= dx; 1253 } 1254 r.minWidth[px-1] += pixels_diff; 1255 } 1256 } else if (constraints.tempWidth > i && 1257 constraints.tempWidth < nextSize) 1258 nextSize = constraints.tempWidth; 1259 1260 1261 if (constraints.tempHeight == i) { 1262 py = constraints.tempY + constraints.tempHeight; 1263 /* bottom row */ 1264 1265 /* 1266 * Calculate the minHeight array values. 1267 * First, figure out how tall the current 1268 * slave needs to be. 1269 * Then, see if it will fit within the 1270 * current minHeight values. 1271 * If it will not fit, add the difference 1272 * according to the 1273 * weightY array. 1274 */ 1275 1276 if (sizeflag == TINYSIZE && hasWeightY(r, 1277 constraints)) { 1278 pixels_diff = constraints.tinyHeight + 1279 constraints.hardipady + 1280 constraints.hardinsets.top + 1281 constraints.hardinsets.bottom; 1282 } else { 1283 pixels_diff = constraints.minsize.height + 1284 constraints.ipady + constraints.hardipady + 1285 constraints.insets.top + 1286 constraints.insets.bottom + 1287 constraints.hardinsets.top + 1288 constraints.hardinsets.bottom; 1289 } 1290 1291 for (k = constraints.tempY; k < py; k++) 1292 pixels_diff -= r.minHeight[k]; 1293 if (pixels_diff > 0) { 1294 weight = 0.0; 1295 for (k = constraints.tempY; k < py; k++) 1296 weight += r.weightY[k]; 1297 for (k = constraints.tempY; weight > 0.0 && 1298 k < py; k++) { 1299 double wt = r.weightY[k]; 1300 int dy = (int)((wt * ((double)pixels_diff)) 1301 / weight); 1302 r.minHeight[k] += dy; 1303 pixels_diff -= dy; 1304 weight -= wt; 1305 } 1306 1307 /* Any leftovers are evenly distributed */ 1308 int dy = pixels_diff/(py-constraints.tempY); 1309 for (k = constraints.tempY; k < (py-1); k++) { 1310 r.minHeight[k] += dy; 1311 pixels_diff -= dy; 1312 } 1313 r.minHeight[py-1] += pixels_diff; 1314 } 1315 } else if (constraints.tempHeight > i && 1316 constraints.tempHeight < nextSize) 1317 nextSize = constraints.tempHeight; 1318 } 1319 } 1320 1321 return r; 1322 } 1323 1324 private int[] ensureCapacity(int arr[], int size) { 1325 if (arr.length < size) { 1326 int newSize = arr.length * 2; 1327 if (newSize == 0) 1328 newSize = 1; 1329 while (newSize < size) 1330 newSize = newSize * 2; 1331 1332 int newArr[] = new int[newSize]; 1333 System.arraycopy(arr, 0, newArr, 0, arr.length); 1334 arr = newArr; 1335 } 1336 1337 return arr; 1338 } 1339 1340 private boolean hasWeightX(GBLayoutInfo r, GBConstraints c) { 1341 int gx = c.tempX + c.tempWidth; 1342 for (int i = c.tempX; i < gx; i++) { 1343 if (r.weightX[i] != 0) 1344 return true; 1345 } 1346 return false; 1347 } 1348 1349 private boolean hasWeightY(GBLayoutInfo r, GBConstraints c) { 1350 int gy = c.tempY + c.tempHeight; 1351 for (int i = c.tempY; i < gy; i++) { 1352 if (r.weightY[i] != 0) 1353 return true; 1354 } 1355 return false; 1356 } 1357 1358 /** 1359 * Adjusts the x, y, width, and height fields to the correct 1360 * values according to the constraint geometry and pads. 1361 */ 1362 protected void AdjustForGravity(GBConstraints c, Rectangle r) { 1363 int diffx, diffy, w, h; 1364 Insets insets = (Insets)c.insets.clone(); 1365 1366 w = r.width - 1367 (insets.left + insets.right + c.hardinsets.left + 1368 c.hardinsets.right); 1369 h = r.height - 1370 (insets.top + insets.bottom + c.hardinsets.top + 1371 c.hardinsets.bottom); 1372 1373 if (w < c.tinyWidth) { 1374 if (c.fill == GBConstraints.HORIZONTAL || 1375 c.fill == GBConstraints.BOTH) { 1376 diffx = c.tinyWidth - w; 1377 insets.left -= diffx/2; 1378 insets.right -= diffx/2; 1379 if (insets.left < 0) { 1380 insets.right += insets.left; 1381 insets.left = 0; 1382 } 1383 if (insets.right < 0) { 1384 insets.left += insets.right; 1385 insets.right = 0; 1386 } 1387 } else { 1388 switch (c.anchor) { 1389 case GBConstraints.NORTH: 1390 case GBConstraints.SOUTH: 1391 case GBConstraints.CENTER: 1392 diffx = c.tinyWidth - w; 1393 insets.left -= diffx/2; 1394 insets.right -= diffx/2; 1395 if (insets.left < 0) { 1396 insets.right += insets.left; 1397 insets.left = 0; 1398 } 1399 if (insets.right < 0) { 1400 insets.left += insets.right; 1401 insets.right = 0; 1402 } 1403 break; 1404 1405 case GBConstraints.NORTHWEST: 1406 case GBConstraints.SOUTHWEST: 1407 case GBConstraints.WEST: 1408 diffx = c.tinyWidth - w; 1409 insets.right -= diffx; 1410 if (insets.right < 0) { 1411 insets.left += insets.right; 1412 insets.right = 0; 1413 } 1414 break; 1415 1416 case GBConstraints.NORTHEAST: 1417 case GBConstraints.SOUTHEAST: 1418 case GBConstraints.EAST: 1419 diffx = c.tinyWidth - w; 1420 insets.left -= diffx; 1421 if (insets.left < 0) { 1422 insets.right += insets.left; 1423 insets.left = 0; 1424 } 1425 break; 1426 default: 1427 /* JSTYLED */ 1428 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.4")); 1429 } 1430 } 1431 } 1432 1433 if (h < c.tinyHeight) { 1434 if (c.fill == GBConstraints.VERTICAL || 1435 c.fill == GBConstraints.BOTH) { 1436 diffy = c.tinyHeight - h; 1437 insets.top -= diffy/2; 1438 insets.bottom -= diffy/2; 1439 if (insets.top < 0) { 1440 insets.bottom += insets.top; 1441 insets.top = 0; 1442 } 1443 if (insets.bottom < 0) { 1444 insets.top += insets.bottom; 1445 insets.bottom = 0; 1446 } 1447 } else { 1448 switch (c.anchor) { 1449 case GBConstraints.WEST: 1450 case GBConstraints.EAST: 1451 case GBConstraints.CENTER: 1452 diffy = c.tinyHeight - h; 1453 insets.top -= diffy/2; 1454 insets.bottom -= diffy/2; 1455 if (insets.top < 0) { 1456 insets.bottom += insets.top; 1457 insets.top = 0; 1458 } 1459 if (insets.bottom < 0) { 1460 insets.top += insets.bottom; 1461 insets.bottom = 0; 1462 } 1463 break; 1464 1465 case GBConstraints.NORTHWEST: 1466 case GBConstraints.NORTHEAST: 1467 case GBConstraints.NORTH: 1468 diffy = c.tinyHeight - h; 1469 insets.bottom -= diffy; 1470 if (insets.bottom < 0) { 1471 insets.top += insets.bottom; 1472 insets.bottom = 0; 1473 } 1474 break; 1475 1476 case GBConstraints.SOUTHWEST: 1477 case GBConstraints.SOUTHEAST: 1478 case GBConstraints.SOUTH: 1479 diffy = c.tinyHeight - h; 1480 insets.top -= diffy; 1481 if (insets.top < 0) { 1482 insets.bottom += insets.top; 1483 insets.top = 0; 1484 } 1485 break; 1486 default: 1487 /* JSTYLED */ 1488 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.4")); 1489 } 1490 } 1491 } 1492 1493 r.x += insets.left + c.hardinsets.left; 1494 r.width -= (insets.left + insets.right + 1495 c.hardinsets.left + c.hardinsets.right); 1496 r.y += insets.top + c.hardinsets.top; 1497 r.height -= (insets.top + insets.bottom + 1498 c.hardinsets.top + c.hardinsets.bottom); 1499 1500 diffx = 0; 1501 if ((c.fill != GBConstraints.HORIZONTAL && 1502 c.fill != GBConstraints.BOTH) 1503 && (r.width > (c.minsize.width + c.ipadx + c.hardipadx))) { 1504 diffx = r.width - (c.minsize.width + c.ipadx + 1505 c.hardipadx); 1506 r.width = c.minsize.width + c.ipadx + c.hardipadx; 1507 } 1508 1509 diffy = 0; 1510 if ((c.fill != GBConstraints.VERTICAL && 1511 c.fill != GBConstraints.BOTH) 1512 && (r.height > (c.minsize.height + c.ipady + c.hardipady))) { 1513 diffy = r.height - (c.minsize.height + c.ipady + 1514 c.hardipady); 1515 r.height = c.minsize.height + c.ipady + c.hardipady; 1516 } 1517 1518 switch (c.anchor) { 1519 case GBConstraints.CENTER: 1520 r.x += diffx/2; 1521 r.y += diffy/2; 1522 break; 1523 case GBConstraints.NORTH: 1524 r.x += diffx/2; 1525 break; 1526 case GBConstraints.NORTHEAST: 1527 r.x += diffx; 1528 break; 1529 case GBConstraints.EAST: 1530 r.x += diffx; 1531 r.y += diffy/2; 1532 break; 1533 case GBConstraints.SOUTHEAST: 1534 r.x += diffx; 1535 r.y += diffy; 1536 break; 1537 case GBConstraints.SOUTH: 1538 r.x += diffx/2; 1539 r.y += diffy; 1540 break; 1541 case GBConstraints.SOUTHWEST: 1542 r.y += diffy; 1543 break; 1544 case GBConstraints.WEST: 1545 r.y += diffy/2; 1546 break; 1547 case GBConstraints.NORTHWEST: 1548 break; 1549 default: 1550 /* JSTYLED */ 1551 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.5")); 1552 } 1553 } 1554 1555 /** 1556 * Figure out the minimum size of the 1557 * parent based on the information retrieved from GetLayoutInfo. 1558 */ 1559 protected Dimension GetMinSize(Container parent, 1560 GBLayoutInfo info) { 1561 Dimension d = new Dimension(); 1562 int i, t; 1563 Insets insets = getInsets(parent); 1564 1565 t = 0; 1566 for (i = 0; i < info.width; i++) 1567 t += info.minWidth[i]; 1568 d.width = t + insets.left + insets.right; 1569 1570 t = 0; 1571 for (i = 0; i < info.height; i++) 1572 t += info.minHeight[i]; 1573 d.height = t + insets.top + insets.bottom; 1574 1575 return d; 1576 } 1577 1578 /** 1579 * Lays out the grid. Called directly from layoutContainer. 1580 */ 1581 protected void ArrangeGrid(Container parent) { 1582 ArrangeGrid(parent, true); 1583 } 1584 1585 /** 1586 * Lays out the grid, conditionally reshaping the children. 1587 * The doReshape flag indicates whether or not 1588 * the children should be reshaped. 1589 * 1590 * @see layoutContainerNoReshape 1591 */ 1592 protected void ArrangeGrid(Container parent, boolean doReshape) { 1593 Component comp; 1594 int compindex; 1595 GBConstraints constraints; 1596 Insets insets = getInsets(parent); 1597 Component components[] = parent.getComponents(); 1598 Dimension d; 1599 Rectangle r = new Rectangle(); 1600 int i, diffw, diffh; 1601 double weight; 1602 GBLayoutInfo info, tinyinfo; 1603 1604 /* 1605 * If the parent has no slaves anymore, then don't do anything 1606 * at all: just leave the parent's size as-is. 1607 */ 1608 if (components.length == 0 && 1609 (columnWidths == null || columnWidths.length == 0) && 1610 (rowHeights == null || rowHeights.length == 0)) { 1611 return; 1612 } 1613 1614 /* 1615 * Pass #1: scan all the slaves to figure out the total amount 1616 * of space needed. 1617 */ 1618 1619 info = GetLayoutInfo(parent, PREFERREDSIZE); 1620 d = GetMinSize(parent, info); 1621 1622 Dimension parentSize = parent.getSize(); 1623 1624 if (d.width > parentSize.width || d.height > 1625 parentSize.height) { 1626 info = GetLayoutInfo(parent, MINSIZE); 1627 d = GetMinSize(parent, info); 1628 } 1629 1630 tinyinfo = GetLayoutInfo(parent, TINYSIZE); 1631 1632 layoutInfo = info; 1633 r.width = d.width; 1634 r.height = d.height; 1635 1636 /* BEGIN JSTYLED */ 1637 /* 1638 * DEBUG 1639 * 1640 * DumpLayoutInfo(info); 1641 * for (compindex = 0 ; compindex < components.length ; compindex++) { 1642 * comp = components[compindex]; 1643 * if (!comp.isVisible()) 1644 * continue; 1645 * constraints = lookupConstraints(comp); 1646 * DumpConstraints(constraints); 1647 * } 1648 * System.out.println("minSize " + r.width + " " + r.height); 1649 */ 1650 1651 /* 1652 * If the current dimensions of the window don't match the desired 1653 * dimensions, then adjust the minWidth and minHeight arrays 1654 * according to the weights. 1655 */ 1656 1657 /* END JSTYLED */ 1658 1659 diffw = parentSize.width - r.width; 1660 if (diffw != 0) { 1661 weight = 0.0; 1662 for (i = 0; i < info.width; i++) 1663 weight += info.weightX[i]; 1664 if (weight > 0.0) { 1665 for (i = 0; i < info.width; i++) { 1666 int dx = (int)((((double)diffw) * 1667 info.weightX[i]) / weight); 1668 info.minWidth[i] += dx; 1669 r.width += dx; 1670 if (info.minWidth[i] < tinyinfo.minWidth[i]) { 1671 r.width += tinyinfo.minWidth[i] - 1672 info.minWidth[i]; 1673 info.minWidth[i] = tinyinfo.minWidth[i]; 1674 } 1675 } 1676 } 1677 diffw = parentSize.width - r.width; 1678 } else { 1679 diffw = 0; 1680 } 1681 1682 diffh = parentSize.height - r.height; 1683 if (diffh != 0) { 1684 weight = 0.0; 1685 for (i = 0; i < info.height; i++) 1686 weight += info.weightY[i]; 1687 if (weight > 0.0) { 1688 for (i = 0; i < info.height; i++) { 1689 int dy = (int)((((double)diffh) * 1690 info.weightY[i]) / weight); 1691 info.minHeight[i] += dy; 1692 r.height += dy; 1693 if (info.minHeight[i] < tinyinfo.minHeight[i]) { 1694 r.height += tinyinfo.minHeight[i] - 1695 info.minHeight[i]; 1696 info.minHeight[i] = tinyinfo.minHeight[i]; 1697 } 1698 } 1699 } 1700 diffh = parentSize.height - r.height; 1701 } else { 1702 diffh = 0; 1703 } 1704 1705 /* 1706 * DEBUG 1707 * 1708 * System.out.println("Re-adjusted:"); 1709 * DumpLayoutInfo(info); 1710 */ 1711 1712 /* 1713 * Now do the actual layout of the slaves 1714 * using the layout information 1715 * that has been collected. 1716 */ 1717 1718 int anchorx = anchor; 1719 int anchory = anchor; 1720 1721 if (diffw < 0) 1722 anchorx = clipAnchor; 1723 if (diffh < 0) 1724 anchory = clipAnchor; 1725 1726 switch (anchorx) { 1727 case GBConstraints.CENTER: 1728 case GBConstraints.NORTH: 1729 case GBConstraints.SOUTH: 1730 info.startx = diffw/2; 1731 break; 1732 1733 case GBConstraints.WEST: 1734 case GBConstraints.NORTHWEST: 1735 case GBConstraints.SOUTHWEST: 1736 info.startx = 0; 1737 break; 1738 1739 case GBConstraints.EAST: 1740 case GBConstraints.NORTHEAST: 1741 case GBConstraints.SOUTHEAST: 1742 info.startx = diffw; 1743 break; 1744 1745 default: 1746 /* JSTYLED */ 1747 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.6")); 1748 } 1749 1750 switch (anchory) { 1751 case GBConstraints.CENTER: 1752 case GBConstraints.WEST: 1753 case GBConstraints.EAST: 1754 info.starty = diffh/2; 1755 break; 1756 1757 case GBConstraints.NORTH: 1758 case GBConstraints.NORTHWEST: 1759 case GBConstraints.NORTHEAST: 1760 info.starty = 0; 1761 break; 1762 1763 case GBConstraints.SOUTH: 1764 case GBConstraints.SOUTHWEST: 1765 case GBConstraints.SOUTHEAST: 1766 info.starty = diffh; 1767 break; 1768 1769 default: 1770 /* JSTYLED */ 1771 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.7")); 1772 } 1773 1774 info.startx += insets.left; 1775 info.starty += insets.top; 1776 1777 for (compindex = 0; compindex < components.length; 1778 compindex++) { 1779 comp = components[compindex]; 1780 if (!comp.isVisible()) 1781 continue; 1782 constraints = lookupConstraints(comp); 1783 1784 r.x = info.startx; 1785 for (i = 0; i < constraints.tempX; i++) 1786 r.x += info.minWidth[i]; 1787 1788 r.y = info.starty; 1789 for (i = 0; i < constraints.tempY; i++) 1790 r.y += info.minHeight[i]; 1791 1792 r.width = 0; 1793 for (i = constraints.tempX; 1794 i < (constraints.tempX + constraints.tempWidth); 1795 i++) { 1796 r.width += info.minWidth[i]; 1797 } 1798 1799 r.height = 0; 1800 for (i = constraints.tempY; 1801 i < (constraints.tempY + constraints.tempHeight); 1802 i++) { 1803 r.height += info.minHeight[i]; 1804 } 1805 1806 AdjustForGravity(constraints, r); 1807 1808 /* 1809 * If the window is too small to be interesting then 1810 * unmap it. Otherwise configure it and then make sure 1811 * it's mapped. 1812 */ 1813 1814 if ((r.width <= 0) || (r.height <= 0)) { 1815 if (doReshape) 1816 comp.reshape(-1, -1, 0, 0); 1817 constraints.location = new Point(-1, -1); 1818 constraints.size = new Dimension(0, 0); 1819 } else { 1820 Point loc = comp.getLocation(); 1821 Dimension size = comp.getSize(); 1822 1823 if (loc.x != r.x || loc.y != r.y || 1824 size.width != r.width || size.height != r.height) { 1825 if (doReshape) 1826 comp.reshape(r.x, r.y, r.width, r.height); 1827 constraints.location = new Point(r.x, r.y); 1828 constraints.size = new Dimension(r.width, r.height); 1829 } 1830 } 1831 } 1832 } 1833} 1834