1 22 package com.izforge.izpack.gui; 23 24 import java.awt.Component ; 25 import java.awt.Container ; 26 import java.awt.Dimension ; 27 import java.awt.Insets ; 28 import java.awt.LayoutManager ; 29 import java.awt.LayoutManager2 ; 30 import java.awt.Rectangle ; 31 import java.util.ArrayList ; 32 33 import javax.swing.JCheckBox ; 34 import javax.swing.JComponent ; 35 import javax.swing.JLabel ; 36 import javax.swing.JRadioButton ; 37 import javax.swing.JScrollPane ; 38 import javax.swing.JTextArea ; 39 import javax.swing.text.JTextComponent ; 40 41 import com.izforge.izpack.panels.PathSelectionPanel; 42 import com.izforge.izpack.util.MultiLineLabel; 43 44 50 public class IzPanelLayout implements LayoutManager , LayoutManager2 , LayoutConstants 51 { 52 53 54 private ArrayList components = new ArrayList (); 55 56 57 private int currentYPos = 0; 58 59 60 private int currentXPos = -1; 61 62 63 private Dimension prefLayoutDim; 64 65 private Dimension oldParentSize; 66 67 private Insets oldParentInsets; 68 69 private int columnFillOutRule; 70 71 private double[] overallYStretch = { -1.0, 0.0}; 72 73 protected static int[] DEFAULT_Y_GAPS = { -1, 0, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 12, 74 9, 6, 3, 0}; 75 76 protected static int[] DEFAULT_X_GAPS = { -1, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 15, 77 12, 9, 6, 3, 0}; 78 79 protected static int[] DEFAULT_X_ALIGNMENT = { LEFT, LEFT, LEFT, LEFT}; 80 81 protected static int[] DEFAULT_Y_ALIGNMENT = { CENTER, CENTER, CENTER, CENTER}; 82 83 84 private static IzPanelConstraints DEFAULT_CONSTRAINTS[] = { 85 new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT, DEFAULT_LABEL_ALIGNMENT, NEXT_COLUMN, 87 CURRENT_ROW, 1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP, 0.0, 0.0), 88 new IzPanelConstraints(DEFAULT_TEXT_ALIGNMENT, DEFAULT_TEXT_ALIGNMENT, NEXT_COLUMN, 90 CURRENT_ROW, 1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP, 0.0, 0.0), 91 new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT, DEFAULT_CONTROL_ALIGNMENT, 93 NEXT_COLUMN, CURRENT_ROW, 1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP, 0.0, 0.0), 94 new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT, DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW, 96 Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP, AUTOMATIC_GAP, 97 FULL_LINE_STRETCH, 0.0), 98 new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT, DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW, 101 Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP, AUTOMATIC_GAP, 102 FULL_LINE_STRETCH, FULL_COLUMN_STRETCH), 103 new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT, DEFAULT_LABEL_ALIGNMENT, NEXT_COLUMN, 105 CURRENT_ROW, 1, 1, 0, 0, 0.0, 0.0), 106 new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT, DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW, 108 1, 1, 0, 0, 0.0, 0.0), 109 new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT, DEFAULT_CONTROL_ALIGNMENT, 0, 111 NEXT_ROW, Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP, AUTOMATIC_GAP, 112 FULL_LINE_STRETCH, 0.0), 113 114 }; 115 116 117 private static int ANCHOR = CENTER; 118 119 private static int X_STRETCH_TYPE = RELATIVE_STRETCH; 120 121 private static int Y_STRETCH_TYPE = RELATIVE_STRETCH; 122 123 private static double FULL_LINE_STRETCH_DEFAULT = 1.0; 124 125 private static double FULL_COLUMN_STRETCH_DEFAULT = 1.0; 126 127 private static int DEFAULT_TEXTFIELD_LENGTH = 12; 128 129 private static final int[][] GAP_INTERMEDIAER_LOOKUP = { 130 { LABEL_GAP, LABEL_TO_TEXT_GAP, LABEL_TO_CONTROL_GAP, LABEL_GAP, LABEL_TO_CONTROL_GAP, 131 LABEL_GAP, LABEL_GAP}, 132 { TEXT_TO_LABEL_GAP, TEXT_GAP, TEXT_TO_CONTROL_GAP, TEXT_TO_LABEL_GAP, 133 TEXT_TO_CONTROL_GAP, TEXT_GAP, TEXT_GAP}, 134 { CONTROL_TO_LABEL_GAP, CONTROL_TO_TEXT_GAP, CONTROL_GAP, CONTROL_TO_LABEL_GAP, 135 CONTROL_GAP, CONTROL_GAP, CONTROL_GAP}, 136 { LABEL_GAP, LABEL_TO_TEXT_GAP, LABEL_TO_CONTROL_GAP, LABEL_GAP, LABEL_TO_CONTROL_GAP, 137 LABEL_GAP, LABEL_GAP}, 138 { CONTROL_TO_LABEL_GAP, CONTROL_TO_TEXT_GAP, CONTROL_GAP, CONTROL_TO_LABEL_GAP, 139 CONTROL_GAP, CONTROL_GAP, CONTROL_GAP}, 140 { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP}, 141 { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP}, 142 { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP}}; 143 144 147 public IzPanelLayout() 148 { 149 this(NO_FILL_OUT_COLUMN); 150 } 151 152 158 public IzPanelLayout(int colFillOutRule) 159 { 160 super(); 161 columnFillOutRule = colFillOutRule; 162 } 163 164 171 private static int getYGap(IzPanelConstraints curConst, IzPanelConstraints nextYConst) 172 { 173 174 Class nextClass = (nextYConst != null) ? nextYConst.component.getClass() 175 : FillerComponent.class; 176 int interId = GAP_INTERMEDIAER_LOOKUP[getIntermediarId(curConst.component.getClass(), null)][getIntermediarId( 177 nextClass, null)]; 178 if (interId < 0) interId = -interId; 179 return (DEFAULT_Y_GAPS[interId]); 180 181 } 182 183 190 private static int getXGap(IzPanelConstraints curConst, IzPanelConstraints nextXConst) 191 { 192 193 Class nextClass = (nextXConst != null) ? nextXConst.component.getClass() 194 : FillerComponent.class; 195 int interId = GAP_INTERMEDIAER_LOOKUP[getIntermediarId(curConst.component.getClass(), null)][getIntermediarId( 196 nextClass, null)]; 197 if (interId < 0) interId = -interId; 198 return (DEFAULT_X_GAPS[interId]); 199 200 } 201 202 209 private static int getIntermediarId(Class clazz, Component comp) 210 { 211 212 if (comp != null) 213 { 214 if (MultiLineLabel.class.isAssignableFrom(clazz) 215 || LabelFactory.FullLineLabel.class.isAssignableFrom(clazz)) 216 return (FULL_LINE_COMPONENT_CONSTRAINT); 217 if (PathSelectionPanel.class.isAssignableFrom(clazz) 218 || JCheckBox .class.isAssignableFrom(clazz) 219 || JRadioButton .class.isAssignableFrom(clazz)) 220 return (FULL_LINE_CONTROL_CONSTRAINT); 221 if (FillerComponent.class.isAssignableFrom(clazz) 222 || javax.swing.Box.Filler.class.isAssignableFrom(clazz)) 223 { 224 Dimension size = comp.getPreferredSize(); 225 if (size.height >= Short.MAX_VALUE || size.height <= 0) 226 { 227 size.height = 0; 228 comp.setSize(size); 229 return (XDUMMY_CONSTRAINT); 230 } 231 else if (size.width >= Short.MAX_VALUE || size.width <= 0) 232 { 233 size.width = 0; 234 comp.setSize(size); 235 return (YDUMMY_CONSTRAINT); 236 } 237 } 238 } 239 if (JScrollPane .class.isAssignableFrom(clazz)) return (XY_VARIABLE_CONSTRAINT); 240 if (JLabel .class.isAssignableFrom(clazz)) return (LABEL_CONSTRAINT); 241 if (JTextComponent .class.isAssignableFrom(clazz)) return (TEXT_CONSTRAINT); 242 if (FillerComponent.class.isAssignableFrom(clazz)) return (XDUMMY_CONSTRAINT); 243 if (javax.swing.Box.Filler.class.isAssignableFrom(clazz)) return (XDUMMY_CONSTRAINT); 244 return (CONTROL_CONSTRAINT); } 246 247 252 public void addLayoutComponent(String name, Component comp) 253 { 254 } 256 257 262 public void removeLayoutComponent(Component comp) 263 { 264 } 266 267 272 public Dimension minimumLayoutSize(Container parent) 273 { 274 return preferredLayoutSize(parent); 275 } 276 277 282 public Dimension preferredLayoutSize(Container parent) 283 { 284 return (determineSize()); 285 } 286 287 294 private Dimension determineSize() 295 { 296 if (prefLayoutDim == null) 297 { 298 int width = minimumAllColumnsWidth(); 299 int height = minimumOverallHeight(); 300 prefLayoutDim = new Dimension (width, height); 301 } 302 return (Dimension ) (prefLayoutDim.clone()); 303 } 304 305 310 private int rows() 311 { 312 int maxRows = 0; 313 for (int i = 0; i < components.size(); ++i) 314 { 315 int curRows = ((ArrayList ) components.get(i)).size(); 316 if (curRows > maxRows) maxRows = curRows; 317 318 } 319 return (maxRows); 320 } 321 322 327 private int columns() 328 { 329 return (components.size()); 330 } 331 332 337 private int minimumOverallHeight() 338 { 339 int height = 0; 340 341 for (int i = 0; i < rows(); i++) 342 { 343 height += rowHeight(i); 344 } 345 346 return (height); 347 } 348 349 356 private int rowHeight(int row) 357 { 358 int height = 0; 359 for (int i = 0; i < components.size(); ++i) 360 { 361 int curHeight = getCellSize(i, row, null).height; 362 if (curHeight > height) height = curHeight; 363 } 364 return (height); 365 } 366 367 376 private int rowHeight(int row, int minOverallHeight, int maxOverallHeight) 377 { 378 int height = 0; 380 double[] yStretch = getOverallYStretch(); 381 if (yStretch[0] <= 0.0) return (rowHeight(row)); 382 double maxStretch = 0.0; 383 double[] stretchParts = new double[components.size()]; 384 for (int i = 0; i < components.size(); ++i) 385 { 386 IzPanelConstraints constraints = getConstraints(i, row); 387 double stretch = constraints.getYStretch(); 388 stretchParts[i] = stretch; 389 if (stretch > maxStretch) maxStretch = stretch; 390 int curHeight = getCellSize(i, row, constraints).height; 391 if (curHeight > height) height = curHeight; 392 } 393 if (maxOverallHeight <= minOverallHeight) return (height); 394 int pixels = (int) (maxOverallHeight - yStretch[1] - minOverallHeight); 396 int stretchPart = (int) (pixels * maxStretch); 397 if (stretchPart > 0) 398 { 399 for (int i = 0; i < components.size(); ++i) 400 { 401 if (stretchParts[i] < 0.00000001) continue; 402 IzPanelConstraints constraints = getConstraints(i, row); 403 Dimension size = constraints.component.getPreferredSize(); 404 if (size.height + stretchPart * stretchParts[i] < height) 405 size.height = (int) (height + stretchPart * stretchParts[i]); 406 else 407 size.height = height + stretchPart; 408 if (constraints.component instanceof JScrollPane ) 409 { 412 if (((JScrollPane ) constraints.component).getViewport().getView() instanceof JTextArea ) 413 { 414 if (((JTextArea ) ((JScrollPane ) constraints.component).getViewport() 415 .getView()).getLineWrap()) size.width = 1000; 416 } 417 } 418 ((JComponent ) constraints.component).setPreferredSize(size); 419 420 } 421 height += stretchPart; 422 423 } 424 return (height); 425 } 426 427 432 private double[] getOverallYStretch() 433 { 434 if (overallYStretch[0] >= 0.0) return (overallYStretch); overallYStretch[0] = 0.0; 436 for (int row = 0; row < rows(); ++row) 437 { 438 double maxStretch = 0.0; 439 double maxGap = 0.0; 440 for (int i = 0; i < components.size(); ++i) 441 { 442 IzPanelConstraints constraints = getConstraints(i, row); 443 resolveDefaultSettings(i, row); 444 if (constraints.getYStretch() == FULL_COLUMN_STRETCH) 445 constraints.setYStretch(IzPanelLayout.getFullColumnStretch()); 446 double curStretch = constraints.getYStretch(); 447 if (curStretch > maxStretch) maxStretch = curStretch; 448 double curYGap = constraints.getYGap(); 449 if (curYGap > maxGap) maxGap = curYGap; 450 } 451 overallYStretch[0] += maxStretch; 452 overallYStretch[1] += maxGap; 453 } 454 if (overallYStretch[0] > 0.0) 456 { 457 switch (IzPanelLayout.getYStretchType()) 458 { 459 case RELATIVE_STRETCH: 460 break; 461 case ABSOLUTE_STRETCH: 462 overallYStretch[0] = 1.0; 463 break; 464 case NO_STRETCH: 465 default: 466 overallYStretch[0] = 0.0; 467 break; 468 } 469 } 470 471 return (overallYStretch); 472 } 473 474 483 private Dimension getCellSize(int column, int row, IzPanelConstraints constraints) 484 { 485 Dimension retval = new Dimension (); 486 Component component; 487 488 try 489 { 490 if (constraints == null) constraints = getConstraints(column, row); 491 if (constraints != null) 492 { 493 component = constraints.component; 494 Dimension dim = component.getPreferredSize(); 497 Dimension dim2 = component.getMinimumSize(); 498 retval.height = (dim.height > dim2.height) ? dim.height : dim2.height; 499 retval.width = (dim.width > dim2.width) ? dim.width : dim2.width; 500 if (component instanceof JScrollPane ) 501 { retval.height = dim2.height; 504 retval.width = dim2.width; 505 } 506 if (needsReEvaluation(component)) retval.width = 0; 507 508 } 509 } 510 catch (Throwable exception) 511 { 512 } 519 520 return (retval); 521 } 522 523 530 private int minimumColumnWidth(int column) 531 { 532 int maxWidth = 0; 533 Dimension [] cs = new Dimension [rows()]; 534 for (int i = 0; i < rows(); ++i) 535 { 536 IzPanelConstraints constraints = getConstraints(column, i); 537 cs[i] = getCellSize(column, i, constraints); 538 if (constraints.getXWeight() <= 1) if (maxWidth < cs[i].width) maxWidth = cs[i].width; 539 } 540 if (maxWidth == 0) 541 { 542 for (int i = 0; i < rows(); ++i) 543 { 544 if (maxWidth < cs[i].width) maxWidth = cs[i].width; 545 } 546 } 547 return (maxWidth); 548 } 549 550 555 private int minimumAllColumnsWidth() 556 { 557 int width = 0; 558 for (int i = 0; i < this.components.size(); ++i) 559 width += minimumColumnWidth(i); 560 return (width); 561 } 562 563 570 private IzPanelConstraints getConstraints(int col, int row) 571 { 572 if (col >= columns() || row >= rows()) return (null); 573 Object obj = components.get(col); 574 if (obj != null && obj instanceof ArrayList ) 575 { 576 try 577 { 578 obj = ((ArrayList ) components.get(col)).get(row); 579 } 580 catch (Throwable t) 581 { 582 obj = null; 583 } 584 if (obj != null) return ((IzPanelConstraints) obj); 585 589 ArrayList colA = (ArrayList ) components.get(col); 590 for (int curRow = colA.size(); row >= curRow; ++curRow) 591 { 592 593 IzPanelConstraints currentConst = IzPanelLayout 594 .getDefaultConstraint(XDUMMY_CONSTRAINT); 595 currentConst.setXPos(col); 596 currentConst.setYPos(curRow); 597 currentConst.component = new FillerComponent(); 598 try 599 { 600 ((ArrayList ) components.get(col)).add(row, currentConst); 601 } 602 catch (Throwable t) 603 { 604 return (null); 605 } 606 } 607 return (getConstraints(col, row)); 608 } 609 return (null); 610 } 611 612 private int getAdaptedXPos(int xpos, int curWidth, Dimension curDim, 613 IzPanelConstraints currentConst) 614 { 615 int adaptedXPos = xpos; if ((columnFillOutRule & FILL_OUT_COLUMN_WIDTH) > 0) return (adaptedXPos); 617 switch (currentConst.getXCellAlignment()) 618 { 619 case LEFT: 620 break; 621 case RIGHT: 622 adaptedXPos += curWidth - curDim.width; 623 break; 624 case CENTER: 625 default: 626 adaptedXPos += (curWidth - curDim.width) / 2; 627 break; 628 629 } 630 return (adaptedXPos); 631 } 632 633 private int getAdaptedYPos(int ypos, int curHeight, Dimension curDim, 634 IzPanelConstraints currentConst) 635 { 636 int adaptedYPos = ypos; if ((columnFillOutRule & FILL_OUT_COLUMN_HEIGHT) > 0) return (adaptedYPos); 638 int height = curDim.height; 639 switch (currentConst.getYCellAlignment()) 640 { 641 case TOP: 642 break; 643 case BOTTOM: 644 adaptedYPos += curHeight - height; 645 break; 646 case CENTER: 647 default: 648 adaptedYPos += (curHeight - height) / 2; 649 break; 650 651 } 652 if (adaptedYPos < ypos) return (ypos); 653 return (adaptedYPos); 654 } 655 656 private void resolveDefaultSettings(int col, int row) 657 { 658 IzPanelConstraints currentConst = getConstraints(col, row); 659 IzPanelConstraints nextYConst = getConstraints(col, row + 1); 660 IzPanelConstraints nextXConst = getConstraints(col + 1, row); 661 if (currentConst == null) return; 662 int gap = currentConst.getYGap(); 663 if (gap == AUTOMATIC_GAP) 664 { currentConst.setYGap(getYGap(currentConst, nextYConst)); 666 } 667 else if (gap < 0) 668 { 669 currentConst.setYGap(DEFAULT_Y_GAPS[-gap]); 670 } 671 gap = currentConst.getXGap(); 672 if (gap == AUTOMATIC_GAP) 673 { currentConst.setXGap(getXGap(currentConst, nextXConst)); 675 } 676 else if (gap < 0) 677 { 678 currentConst.setXGap(DEFAULT_X_GAPS[-gap]); 679 } 680 681 if (currentConst.getXCellAlignment() < 0) 682 { 683 currentConst.setXCellAlignment(DEFAULT_X_ALIGNMENT[-currentConst.getXCellAlignment()]); 684 } 685 if (currentConst.getYCellAlignment() < 0) 686 { 687 currentConst.setYCellAlignment(DEFAULT_Y_ALIGNMENT[-currentConst.getYCellAlignment()]); 688 } 689 690 } 691 692 697 public void layoutContainer(Container parent) 698 { 699 if (!needNewLayout(parent)) 700 { 701 fastLayoutContainer(parent); 702 return; 703 } 704 prefLayoutDim = null; 705 preferredLayoutSize(parent); 706 Dimension realSizeDim = parent.getSize(); 707 Insets insets = parent.getInsets(); 708 709 int rowHeight = 0; 710 int onceAgain = 0; 711 int[] generellOffset = new int[] { 0, 0}; 712 int maxWidth = 0; 715 int overallHeight = 0; 716 int anchorNeedsReEval = 0; 717 Rectangle curRect = new Rectangle (); 718 int minOverallHeight = minimumOverallHeight(); 719 int maxOverallHeight = realSizeDim.height - insets.top - insets.bottom; 720 while (anchorNeedsReEval < 2) 721 { 722 int ypos = insets.top; 723 724 int row = 0; 725 int minWidth = 0xffff; 726 int minHeight = 0xffff; 727 maxWidth = 0; 728 overallHeight = 0; 729 while (row < rows()) 730 { 731 int outerRowHeight = 0; 732 int xpos = insets.left; 733 int col = 0; 735 IzPanelConstraints[] colConstraints = new IzPanelConstraints[columns()]; 736 int usedWidth = 0; 737 Dimension curDim; 738 while (col < columns()) 739 { 740 if (col == 0) rowHeight = rowHeight(row, minOverallHeight, maxOverallHeight); 741 IzPanelConstraints currentConst = getConstraints(col, row); 742 colConstraints[col] = currentConst; 743 Component currentComp = currentConst.component; 744 curDim = currentComp.getPreferredSize(); 745 int curWidth = minimumColumnWidth(col); 746 col++; 747 if (currentConst.getXWeight() > 1) 748 { 749 int weight = currentConst.getXWeight(); 750 while (weight > 1 && col < columns()) 751 { 752 colConstraints[col] = getConstraints(col, row); 753 if (!(colConstraints[col].component instanceof FillerComponent)) break; 754 curWidth += minimumColumnWidth(col); 755 col++; 756 weight--; 757 } 758 } 759 int adaptedXPos = getAdaptedXPos(xpos, curWidth, curDim, currentConst); 761 int adaptedYPos = getAdaptedYPos(ypos, rowHeight, curDim, currentConst); 762 int useWidth = curDim.width; 766 int useHeight = curDim.height; 767 if ((columnFillOutRule & FILL_OUT_COLUMN_WIDTH) > 0) useWidth = curWidth; 768 if ((columnFillOutRule & FILL_OUT_COLUMN_HEIGHT) > 0) useHeight = rowHeight; 769 if (curWidth < useWidth) useWidth = curWidth; 770 currentComp.setBounds(adaptedXPos + generellOffset[0], adaptedYPos 772 + generellOffset[1], useWidth, useHeight); 773 currentComp.getBounds(curRect); 774 if (!(currentComp instanceof FillerComponent)) 775 { 776 if (curRect.x < minWidth) minWidth = curRect.x; 777 if (curRect.y < minHeight) minHeight = curRect.y; 778 } 779 int curMax = (int) curRect.getMaxX(); 780 if (curMax - minWidth > maxWidth) maxWidth = curMax - minWidth; 781 curMax = (int) curRect.getMaxY(); 782 currentConst.setBounds(curRect); 783 if (curMax - minHeight > overallHeight) overallHeight = curMax - minHeight; 784 xpos += curWidth + currentConst.getXGap(); 786 usedWidth += curWidth; 787 if (outerRowHeight < rowHeight + currentConst.getYGap()) 788 outerRowHeight = rowHeight + currentConst.getYGap(); 789 } 790 double rowStretch = 0.0; 793 int i; 794 for (i = 0; i < colConstraints.length; ++i) 796 { 797 if (colConstraints[i].getXStretch() == FULL_LINE_STRETCH) 798 colConstraints[i].setXStretch(IzPanelLayout.getFullLineStretch()); 799 rowStretch += colConstraints[i].getXStretch(); 800 } 801 if (rowStretch > 0.0) 803 { 804 switch (IzPanelLayout.getXStretchType()) 805 { 806 case RELATIVE_STRETCH: 807 break; 808 case ABSOLUTE_STRETCH: 809 rowStretch = 1.0; 810 break; 811 case NO_STRETCH: 812 default: 813 rowStretch = 0.0; 814 break; 815 } 816 } 817 if (realSizeDim.width - insets.right != xpos && rowStretch > 0.0) 818 { int pixel = realSizeDim.width - insets.right - xpos; int offset = 0; 823 int oldOnceAgain = onceAgain; 824 for (i = 0; i < colConstraints.length; ++i) 825 { 826 int curPixel = (int) ((colConstraints[i].getXStretch() / rowStretch) * pixel); 827 828 Rectangle curBounds = colConstraints[i].component.getBounds(); 829 int newWidth = curPixel + curBounds.width; 830 colConstraints[i].component.setBounds(curBounds.x + offset, curBounds.y, 831 newWidth, curBounds.height); 832 colConstraints[i].component.getBounds(curRect); 833 if (curRect.x > 0 && curRect.x < minWidth) minWidth = curRect.x; 834 if (curRect.y > 0 && curRect.y < minHeight) minHeight = curRect.y; 835 int curMax = (int) curRect.getMaxX(); 836 if (curMax - minWidth > maxWidth) maxWidth = curMax - minWidth; 837 curMax = (int) curRect.getMaxY(); 838 colConstraints[i].setBounds(curRect); 839 840 if (curMax - minHeight > overallHeight) overallHeight = curMax - minHeight; 841 842 offset += curPixel; 843 if (needsReEvaluation(colConstraints[i].component)) 844 { 845 if (oldOnceAgain == onceAgain) onceAgain++; 846 } 847 } 848 849 } 850 853 if (onceAgain == 1) continue; 854 onceAgain = 0; 855 ypos += outerRowHeight; 856 row++; 857 } 858 anchorNeedsReEval += resolveGenerellOffsets(generellOffset, realSizeDim, insets, 859 maxWidth, overallHeight); 860 861 } 862 } 863 864 private void fastLayoutContainer(Container parent) 865 { 866 for (int row = 0; row < rows(); ++row) 867 { 868 for (int col = 0; col < columns(); ++col) 869 { 870 IzPanelConstraints currentConst = getConstraints(col, row); 871 if (currentConst != null) 872 currentConst.component.setBounds(currentConst.getBounds()); 873 874 } 875 876 } 877 } 878 879 private boolean needNewLayout(Container parent) 880 { 881 Dimension ops = oldParentSize; 882 Insets opi = oldParentInsets; 883 oldParentSize = parent.getSize(); 884 oldParentInsets = parent.getInsets(); 885 if (opi == null || opi == null) return (true); 886 if (ops.equals(parent.getSize()) && opi.equals(parent.getInsets())) return (false); 887 return (true); 888 889 } 890 891 private int resolveGenerellOffsets(int[] generellOffset, Dimension realSizeDim, Insets insets, 892 int maxWidth, int overallHeight) 893 { 894 int retval = 1; 895 switch (getAnchor()) 896 { 897 case CENTER: 898 generellOffset[0] = (realSizeDim.width - insets.left - insets.right - maxWidth) / 2; 899 generellOffset[1] = (realSizeDim.height - insets.top - insets.bottom - overallHeight) / 2; 900 break; 901 case WEST: 902 generellOffset[0] = 0; 903 generellOffset[1] = (realSizeDim.height - insets.top - insets.bottom - overallHeight) / 2; 904 break; 905 case EAST: 906 generellOffset[0] = realSizeDim.width - insets.left - insets.right - maxWidth; 907 generellOffset[1] = (realSizeDim.height - insets.top - insets.bottom - overallHeight) / 2; 908 break; 909 case NORTH: 910 generellOffset[0] = (realSizeDim.width - insets.left - insets.right - maxWidth) / 2; 911 generellOffset[1] = 0; 912 break; 913 case SOUTH: 914 generellOffset[0] = (realSizeDim.width - insets.left - insets.right - maxWidth) / 2; 915 generellOffset[1] = realSizeDim.height - insets.top - insets.bottom - overallHeight; 916 break; 917 case NORTH_WEST: 918 generellOffset[0] = 0; 919 generellOffset[1] = 0; 920 retval = 2; 921 break; 922 case NORTH_EAST: 923 generellOffset[0] = realSizeDim.width - insets.left - insets.right - maxWidth; 924 generellOffset[1] = 0; 925 break; 926 case SOUTH_WEST: 927 generellOffset[0] = 0; 928 generellOffset[1] = realSizeDim.height - insets.top - insets.bottom - overallHeight; 929 break; 930 case SOUTH_EAST: 931 generellOffset[0] = realSizeDim.width - insets.left - insets.right - maxWidth; 932 generellOffset[1] = realSizeDim.height - insets.top - insets.bottom - overallHeight; 933 break; 934 935 } 936 if(generellOffset[0] < 0 ) generellOffset[0] = 0; 937 if(generellOffset[1] < 0 ) generellOffset[1] = 0; 938 return (retval); 939 } 940 941 947 private boolean needsReEvaluation(Component comp) 948 { 949 if ((comp instanceof com.izforge.izpack.util.MultiLineLabel) 950 || (comp instanceof com.izforge.izpack.panels.PathSelectionPanel)) return (true); 951 return (false); 952 } 953 954 959 public float getLayoutAlignmentX(Container target) 960 { 961 return 0; 962 } 963 964 969 public float getLayoutAlignmentY(Container target) 970 { 971 return 0; 972 } 973 974 979 public void invalidateLayout(Container target) 980 { 981 } 983 984 989 public Dimension maximumLayoutSize(Container target) 990 { 991 return (minimumLayoutSize(target)); 992 } 993 994 999 public void addLayoutComponent(Component comp, Object constraints) 1000 { 1001 if (comp == null) throw new NullPointerException ("component has to be not null"); 1002 IzPanelConstraints cc; 1003 if (!(constraints instanceof IzPanelConstraints)) 1004 { 1005 if ((comp instanceof FillerComponent) 1006 && ((FillerComponent) comp).getConstraints() != null) 1007 cc = (IzPanelConstraints) ((FillerComponent) comp).getConstraints().clone(); 1008 else 1009 cc = (IzPanelConstraints) IzPanelLayout.DEFAULT_CONSTRAINTS[getIntermediarId(comp 1010 .getClass(), comp)].clone(); 1011 if (NEXT_LINE.equals(constraints)) 1012 { 1013 cc.setXPos(0); 1014 cc.setYPos(NEXT_ROW); 1015 } 1016 } 1017 else 1018 cc = (IzPanelConstraints) ((IzPanelConstraints) constraints).clone(); 1019 cc.component = comp; 1020 int i; 1021 int yPos = cc.getYPos(); 1023 if (yPos == LayoutConstants.NEXT_ROW) yPos = currentYPos + 1; 1024 if (yPos == LayoutConstants.CURRENT_ROW) yPos = currentYPos; 1025 cc.setYPos(yPos); 1026 int xPos = cc.getXPos(); 1027 if (xPos == LayoutConstants.NEXT_COLUMN) xPos = currentXPos + 1; 1028 if (xPos == LayoutConstants.CURRENT_COLUMN) xPos = currentXPos; 1029 cc.setXPos(xPos); 1030 int perfCol = cc.getXWeight() < Byte.MAX_VALUE ? cc.getXWeight() : 1; 1033 if (components.size() < cc.getXPos() + perfCol) 1034 { 1035 for (i = components.size() - 1; i < cc.getXPos() + perfCol - 1; ++i) 1036 components.add(new ArrayList ()); 1037 } 1038 IzPanelConstraints curConst = cc; 1039 for (int j = 0; j < perfCol; ++j) 1040 { 1041 ArrayList xComp = (ArrayList ) components.get(xPos); 1042 if (xComp.size() < yPos) 1043 { 1044 for (i = xComp.size() - 1; i < yPos - 1; ++i) 1045 { 1046 IzPanelConstraints dc = getDefaultConstraint(XDUMMY_CONSTRAINT); 1047 dc.component = new FillerComponent(); 1048 xComp.add(dc); 1049 1050 } 1051 } 1052 1053 xComp.add(yPos, curConst); 1054 if (j < perfCol - 1) 1055 { 1056 curConst = getDefaultConstraint(XDUMMY_CONSTRAINT); 1057 curConst.component = new FillerComponent(); 1058 xPos++; 1059 } 1060 } 1061 int xcsize = ((ArrayList ) components.get(xPos)).size() - 1; 1062 if (currentYPos < xcsize) currentYPos = xcsize; 1063 currentXPos = xPos; 1064 1065 } 1066 1067 1076 public static Component createHorizontalStrut(int width) 1077 { 1078 return (new FillerComponent(new Dimension (width, 0))); 1079 } 1080 1081 1092 public static Component createVerticalStrut(int height) 1093 { 1094 return (new FillerComponent(new Dimension (0, height))); 1095 } 1096 1097 1105 public static Component createParagraphGap() 1106 { 1107 return (createGap(PARAGRAPH_GAP, VERTICAL)); 1108 } 1109 1110 1122 public static Component createVerticalFiller(int fillerNumber) 1123 { 1124 return (createGap(FILLER1_GAP + 1 - fillerNumber, VERTICAL)); 1127 } 1128 1129 1140 public static Component createHorizontalFiller(int fillerNumber) 1141 { 1142 return (createGap(FILLER1_GAP + 1 - fillerNumber, HORIZONTAL)); 1145 } 1146 1147 1160 1161 public static Component createGap(int gapType, int direction) 1162 { 1163 if (direction == HORIZONTAL) 1164 return (new FillerComponent(new Dimension (0, 0), new IzPanelConstraints( 1165 DEFAULT_CONTROL_ALIGNMENT, DEFAULT_CONTROL_ALIGNMENT, NEXT_COLUMN, CURRENT_ROW, 1166 1, 1, gapType, 0, 0.0, 0.0))); 1167 return (new FillerComponent(new Dimension (0, 0), new IzPanelConstraints( 1168 DEFAULT_CONTROL_ALIGNMENT, DEFAULT_CONTROL_ALIGNMENT, 0, NEXT_ROW, 10, 10, 0, 1169 gapType, 1.0, 0.0))); 1170 } 1171 1172 1180 public static IzPanelConstraints getDefaultConstraint(int type) 1181 { 1182 return ((IzPanelConstraints) DEFAULT_CONSTRAINTS[type].clone()); 1183 } 1184 1185 1192 public static class FillerComponent extends Component 1193 { 1194 1195 private Dimension size; 1196 1197 private IzPanelConstraints constraints; 1198 1199 1202 public FillerComponent() 1203 { 1204 this(new Dimension (0, 0)); 1205 } 1206 1207 1212 public FillerComponent(Dimension size) 1213 { 1214 this(size, null); 1215 } 1216 1217 1223 public FillerComponent(Dimension size, IzPanelConstraints constraints) 1224 { 1225 super(); 1226 this.size = size; 1227 this.constraints = constraints; 1228 } 1229 1230 public Dimension getMinimumSize() 1231 { 1232 return (Dimension ) (size.clone()); 1233 } 1234 1235 1240 public Dimension getPreferredSize() 1241 { 1242 return getMinimumSize(); 1243 } 1244 1245 1250 public Dimension getMaximumSize() 1251 { 1252 return getMinimumSize(); 1253 } 1254 1255 1260 public Rectangle getBounds() 1261 { 1262 return (getBounds(new Rectangle ())); 1263 } 1264 1265 1270 public Rectangle getBounds(Rectangle rect) 1271 { 1272 Rectangle rv = (rect != null) ? rect : new Rectangle (); 1273 rv.setBounds(0, 0, size.width, size.height); 1274 return (rv); 1275 } 1276 1277 1282 public IzPanelConstraints getConstraints() 1283 { 1284 return constraints; 1285 } 1286 1287 1292 public void setConstraints(IzPanelConstraints constraints) 1293 { 1294 this.constraints = constraints; 1295 } 1296 } 1297 1298 1303 public static int getAnchor() 1304 { 1305 return ANCHOR; 1306 } 1307 1308 1313 public static void setAnchor(int anchor) 1314 { 1315 ANCHOR = anchor; 1316 } 1317 1318 1324 public static int getXStretchType() 1325 { 1326 return X_STRETCH_TYPE; 1327 } 1328 1329 1335 public static void setXStretchType(int x_stretch) 1336 { 1337 X_STRETCH_TYPE = x_stretch; 1338 } 1339 1340 1346 public static int getYStretchType() 1347 { 1348 return Y_STRETCH_TYPE; 1349 } 1350 1351 1357 public static void setYStretchType(int y_stretch) 1358 { 1359 Y_STRETCH_TYPE = y_stretch; 1360 } 1361 1362 1367 public static double getFullLineStretch() 1368 { 1369 return FULL_LINE_STRETCH_DEFAULT; 1370 } 1371 1372 1377 public static void setFullLineStretch(double fullLineStretch) 1378 { 1379 FULL_LINE_STRETCH_DEFAULT = fullLineStretch; 1380 1381 } 1382 1383 1388 public static double getFullColumnStretch() 1389 { 1390 return FULL_COLUMN_STRETCH_DEFAULT; 1391 } 1392 1393 1398 public static void setFullColumnStretch(double fullStretch) 1399 { 1400 FULL_COLUMN_STRETCH_DEFAULT = fullStretch; 1401 1402 } 1403 1404 1412 public static int verifyGapId(int gapId) 1413 { 1414 if (gapId < 0) gapId = -gapId; 1415 if (gapId >= DEFAULT_X_GAPS.length) 1416 throw new IndexOutOfBoundsException ("gapId is not in the default gap container."); 1417 return (gapId); 1418 } 1419 1420 1426 public static int getDefaultXGap(int gapId) 1427 { 1428 gapId = verifyGapId(gapId); 1429 return DEFAULT_X_GAPS[gapId]; 1430 } 1431 1432 1438 public static void setDefaultXGap(int gap, int gapId) 1439 { 1440 gapId = verifyGapId(gapId); 1441 DEFAULT_X_GAPS[gapId] = gap; 1442 } 1443 1444 1450 public static int getDefaultYGap(int gapId) 1451 { 1452 gapId = verifyGapId(gapId); 1453 return DEFAULT_Y_GAPS[gapId]; 1454 } 1455 1456 1462 public static void setDefaultYGap(int gap, int gapId) 1463 { 1464 gapId = verifyGapId(gapId); 1465 DEFAULT_Y_GAPS[gapId] = gap; 1466 } 1467 1468 1473 public static int getDefaultTextfieldLength() 1474 { 1475 return DEFAULT_TEXTFIELD_LENGTH; 1476 } 1477 1478 1483 public static void setDefaultTextfieldLength(int val) 1484 { 1485 DEFAULT_TEXTFIELD_LENGTH = val; 1486 } 1487 1488} 1489 | Popular Tags |