0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package java.awt;
0019:
0020: import java.io.Serializable;
0021: import java.util.ArrayList;
0022: import java.util.Arrays;
0023: import java.util.Enumeration;
0024: import java.util.HashMap;
0025: import java.util.Hashtable;
0026:
0027: import org.apache.harmony.awt.internal.nls.Messages;
0028:
0029: public class GridBagLayout implements LayoutManager2, Serializable {
0030: private static final long serialVersionUID = 8838754796412211005L;
0031:
0032: protected static final int MAXGRIDSIZE = 512;
0033:
0034: protected static final int MINSIZE = 1;
0035:
0036: protected static final int PREFERREDSIZE = 2;
0037:
0038: private final Toolkit toolkit = Toolkit.getDefaultToolkit();
0039:
0040: // Direct modification is forbidden
0041: protected volatile Hashtable<Component, GridBagConstraints> comptable;
0042:
0043: protected volatile GridBagConstraints defaultConstraints;
0044:
0045: protected volatile GridBagLayoutInfo layoutInfo;
0046:
0047: public volatile double columnWeights[];
0048:
0049: public volatile double rowWeights[];
0050:
0051: public volatile int columnWidths[];
0052:
0053: public volatile int rowHeights[];
0054:
0055: private ParentInfo lastParentInfo;
0056:
0057: public GridBagLayout() {
0058: toolkit.lockAWT();
0059: try {
0060: comptable = new Hashtable<Component, GridBagConstraints>();
0061: defaultConstraints = new GridBagConstraints();
0062: columnWeights = rowWeights = null;
0063: columnWidths = rowHeights = null;
0064: layoutInfo = null;
0065: lastParentInfo = null;
0066: } finally {
0067: toolkit.unlockAWT();
0068: }
0069: }
0070:
0071: @Override
0072: public String toString() {
0073: toolkit.lockAWT();
0074: try {
0075: return getClass().getName();
0076: } finally {
0077: toolkit.unlockAWT();
0078: }
0079: }
0080:
0081: public void addLayoutComponent(String name, Component comp) {
0082: toolkit.lockAWT();
0083: try {
0084: // has no effect
0085: } finally {
0086: toolkit.unlockAWT();
0087: }
0088: }
0089:
0090: public void addLayoutComponent(Component comp, Object constraints) {
0091: toolkit.lockAWT();
0092: try {
0093: // awt.7F=AddLayoutComponent: attempt to add null component
0094: assert comp != null : Messages.getString("awt.7F"); //$NON-NLS-1$
0095: GridBagConstraints cons;
0096: if (constraints != null) {
0097: if (!GridBagConstraints.class.isInstance(constraints)) {
0098: // awt.80=AddLayoutComponent: constraint object must be GridBagConstraints
0099: throw new IllegalArgumentException(Messages
0100: .getString("awt.80")); //$NON-NLS-1$
0101: }
0102: cons = (GridBagConstraints) constraints;
0103: } else {
0104: if (comptable.containsKey(comp)) {
0105: // don't replace constraints with default ones
0106: return;
0107: }
0108: cons = defaultConstraints;
0109: }
0110: try {
0111: //cons.verify();
0112: } catch (IllegalArgumentException e) {
0113: // awt.81=AddLayoutComponent: {0}
0114: throw new IllegalArgumentException(Messages.getString(
0115: "awt.81", e.getMessage())); //$NON-NLS-1$
0116: }
0117: GridBagConstraints consClone = (GridBagConstraints) cons
0118: .clone();
0119: comptable.put(comp, consClone);
0120: Container parent = comp.getParent();
0121: updateParentInfo(parent, consClone);
0122: } finally {
0123: toolkit.unlockAWT();
0124: }
0125: }
0126:
0127: public void removeLayoutComponent(Component comp) {
0128: toolkit.lockAWT();
0129: try {
0130: // awt.82=RemoveLayoutComponent: attempt to remove null component
0131: assert comp != null : Messages.getString("awt.82"); //$NON-NLS-1$
0132: Container parent = comp.getParent();
0133: if (parent != null) {
0134: getParentInfo(parent).consTable.remove(comptable
0135: .get(comp));
0136: }
0137: comptable.remove(comp);
0138: } finally {
0139: toolkit.unlockAWT();
0140: }
0141: }
0142:
0143: public GridBagConstraints getConstraints(Component comp) {
0144: toolkit.lockAWT();
0145: try {
0146: GridBagConstraints cons = comptable.get(comp);
0147: if (cons == null) {
0148: cons = defaultConstraints;
0149: comptable.put(comp, (GridBagConstraints) cons.clone());
0150: }
0151: return (GridBagConstraints) cons.clone();
0152: } finally {
0153: toolkit.unlockAWT();
0154: }
0155: }
0156:
0157: public void setConstraints(Component comp,
0158: GridBagConstraints constraints) {
0159: toolkit.lockAWT();
0160: try {
0161: // awt.83=SetConstraints: attempt to get constraints of null component
0162: assert comp != null : Messages.getString("awt.83"); //$NON-NLS-1$
0163: // awt.84=SetConstraints: attempt to set null constraints
0164: assert constraints != null : Messages.getString("awt.84"); //$NON-NLS-1$
0165: GridBagConstraints consClone = (GridBagConstraints) constraints
0166: .clone();
0167: try {
0168: // consClone.verify();
0169: } catch (IllegalArgumentException e) {
0170: // awt.85=SetConstraints: {0}
0171: throw new IllegalArgumentException(Messages.getString(
0172: "awt.85", e.getMessage())); //$NON-NLS-1$
0173: }
0174: ParentInfo info = getParentInfo(comp.getParent());
0175: if (info != null) {
0176: GridBagConstraints cons = comptable.get(comp);
0177: info.allConstraints.remove(info.consTable.get(cons)); //?
0178: info.consTable.remove(cons);
0179: }
0180: // add component if it's not there yet
0181: comptable.put(comp, consClone);
0182: if (info != null) {
0183: MixedConstraints mixCons = new MixedConstraints(
0184: consClone);
0185: info.consTable.put(consClone, mixCons);
0186: info.allConstraints.add(mixCons);
0187: }
0188: } finally {
0189: toolkit.unlockAWT();
0190: }
0191: }
0192:
0193: public float getLayoutAlignmentX(Container parent) {
0194: toolkit.lockAWT();
0195: try {
0196: return Component.CENTER_ALIGNMENT;
0197: } finally {
0198: toolkit.unlockAWT();
0199: }
0200: }
0201:
0202: public float getLayoutAlignmentY(Container parent) {
0203: toolkit.lockAWT();
0204: try {
0205: return Component.CENTER_ALIGNMENT;
0206: } finally {
0207: toolkit.unlockAWT();
0208: }
0209: }
0210:
0211: public void invalidateLayout(Container target) {
0212: toolkit.lockAWT();
0213: try {
0214: if (target == null) {
0215: return;
0216: }
0217: getParentInfo(target).valid = false;
0218: } finally {
0219: toolkit.unlockAWT();
0220: }
0221: }
0222:
0223: public Dimension minimumLayoutSize(Container parent) {
0224: toolkit.lockAWT();
0225: try {
0226: ParentInfo info = lastParentInfo = getParentInfo(parent);
0227: if (getComponentsNumber(parent) == 0) {
0228: return parent.addInsets(new Dimension(0, 0));
0229: }
0230: try {
0231: validate(parent, info);
0232: } catch (RuntimeException e) {
0233: // awt.86=MinimumLayoutSize: {0}
0234: throw new IllegalArgumentException(Messages.getString(
0235: "awt.86", e.getMessage())); //$NON-NLS-1$
0236: }
0237: return parent.addInsets(info.grid.minimumSize());
0238: //return addInsets(grid.minimumSize(), parent);
0239: } finally {
0240: toolkit.unlockAWT();
0241: }
0242: }
0243:
0244: public Dimension preferredLayoutSize(Container parent) {
0245: toolkit.lockAWT();
0246: try {
0247: ParentInfo info = lastParentInfo = getParentInfo(parent);
0248: if (getComponentsNumber(parent) == 0) {
0249: return parent.addInsets(new Dimension(0, 0));
0250: }
0251: try {
0252: validate(parent, info);
0253: } catch (RuntimeException e) {
0254: // awt.87=PreferredLayoutSize: {0}
0255: throw new IllegalArgumentException(Messages.getString(
0256: "awt.87", e.getMessage())); //$NON-NLS-1$
0257: }
0258: return parent.addInsets(info.grid.preferredSize());
0259: //return addInsets(grid.preferredSize(), parent);
0260: } finally {
0261: toolkit.unlockAWT();
0262: }
0263: }
0264:
0265: public Dimension maximumLayoutSize(Container target) {
0266: toolkit.lockAWT();
0267: try {
0268: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
0269: } finally {
0270: toolkit.unlockAWT();
0271: }
0272: }
0273:
0274: public void layoutContainer(Container parent) {
0275: toolkit.lockAWT();
0276: try {
0277: ParentInfo info = lastParentInfo = getParentInfo(parent);
0278: if (getComponentsNumber(parent) == 0) {
0279: return;
0280: }
0281: try {
0282: arrangeGridImpl(parent, info);
0283: } catch (RuntimeException e) {
0284: // awt.88=LayoutContainer: {0}
0285: throw new IllegalArgumentException(Messages.getString(
0286: "awt.88", e.getMessage())); //$NON-NLS-1$
0287: }
0288: setComponentsBounds(info);
0289: } finally {
0290: toolkit.unlockAWT();
0291: }
0292: }
0293:
0294: public int[][] getLayoutDimensions() {
0295: toolkit.lockAWT();
0296: try {
0297: if (lastParentInfo == null) {
0298: return new int[][] { new int[0], new int[0] };
0299: }
0300: return new int[][] { lastParentInfo.grid.getWidths(),
0301: lastParentInfo.grid.getHeights() };
0302: } finally {
0303: toolkit.unlockAWT();
0304: }
0305: }
0306:
0307: public double[][] getLayoutWeights() {
0308: toolkit.lockAWT();
0309: try {
0310: if (lastParentInfo == null) {
0311: return new double[][] { new double[0], new double[0] };
0312: }
0313: return lastParentInfo.grid.getWeights();
0314: } finally {
0315: toolkit.unlockAWT();
0316: }
0317: }
0318:
0319: public Point getLayoutOrigin() {
0320: toolkit.lockAWT();
0321: try {
0322: if (lastParentInfo == null) {
0323: return new Point();
0324: }
0325: return lastParentInfo.grid.getOrigin();
0326: } finally {
0327: toolkit.unlockAWT();
0328: }
0329: }
0330:
0331: public Point location(int x, int y) {
0332: toolkit.lockAWT();
0333: try {
0334: if (lastParentInfo == null) {
0335: return new Point();
0336: }
0337: return lastParentInfo.grid.location(x, y,
0338: lastParentInfo.orientation.isLeftToRight());
0339: } finally {
0340: toolkit.unlockAWT();
0341: }
0342: }
0343:
0344: protected Dimension GetMinSize(Container parent,
0345: GridBagLayoutInfo info) {
0346: toolkit.lockAWT();
0347: try {
0348: int w = 0;
0349: int h = 0;
0350: for (int i = 0; i < MAXGRIDSIZE; i++) {
0351: w += info.widths[i];
0352: h += info.heights[i];
0353: }
0354: return new Dimension(w, h);
0355: } finally {
0356: toolkit.unlockAWT();
0357: }
0358: }
0359:
0360: protected GridBagLayoutInfo GetLayoutInfo(Container parent,
0361: int sizeflag) {
0362: toolkit.lockAWT();
0363: try {
0364: ParentInfo parentInfo = getParentInfo(parent);
0365: if (sizeflag == PREFERREDSIZE) {
0366: return new GridBagLayoutInfo(parentInfo.grid
0367: .lookupPrefWidths(), parentInfo.grid
0368: .lookupPrefHeights());
0369: }
0370: // MINSIZE
0371: return new GridBagLayoutInfo(parentInfo.grid
0372: .lookupMinWidths(), parentInfo.grid
0373: .lookupMinHeights());
0374: } finally {
0375: toolkit.unlockAWT();
0376: }
0377: }
0378:
0379: protected void ArrangeGrid(Container parent) {
0380: toolkit.lockAWT();
0381: try {
0382: ParentInfo info = lastParentInfo = getParentInfo(parent);
0383: if (getComponentsNumber(parent) == 0) {
0384: return;
0385: }
0386: try {
0387: arrangeGridImpl(parent, info);
0388: } catch (RuntimeException e) {
0389: // awt.86=MinimumLayoutSize: {0}
0390: throw new IllegalArgumentException(Messages.getString(
0391: "awt.86", e.getMessage())); //$NON-NLS-1$
0392: }
0393: } finally {
0394: toolkit.unlockAWT();
0395: }
0396: }
0397:
0398: protected GridBagConstraints lookupConstraints(Component comp) {
0399: toolkit.lockAWT();
0400: try {
0401: // awt.89=LookupConstraints: attempt to get constraints of null component
0402: assert comp != null : Messages.getString("awt.89"); //$NON-NLS-1$
0403: GridBagConstraints cons = comptable.get(comp);
0404: if (cons == null) {
0405: // if comp is not in the layout, return a copy of default constraints
0406: cons = (GridBagConstraints) defaultConstraints.clone();
0407: }
0408: return cons;
0409: } finally {
0410: toolkit.unlockAWT();
0411: }
0412: }
0413:
0414: protected void adjustForGravity(GridBagConstraints constraints,
0415: Rectangle r) {
0416: toolkit.lockAWT();
0417: try {
0418: AdjustForGravity(constraints, r);
0419: } finally {
0420: toolkit.unlockAWT();
0421: }
0422: }
0423:
0424: protected void arrangeGrid(Container parent) {
0425: toolkit.lockAWT();
0426: try {
0427: ArrangeGrid(parent);
0428: } finally {
0429: toolkit.unlockAWT();
0430: }
0431: }
0432:
0433: protected GridBagLayoutInfo getLayoutInfo(Container parent,
0434: int sizeflag) {
0435: toolkit.lockAWT();
0436: try {
0437: return GetLayoutInfo(parent, sizeflag);
0438: } finally {
0439: toolkit.unlockAWT();
0440: }
0441: }
0442:
0443: protected Dimension getMinSize(Container parent,
0444: GridBagLayoutInfo info) {
0445: toolkit.lockAWT();
0446: try {
0447: return GetMinSize(parent, info);
0448: } finally {
0449: toolkit.unlockAWT();
0450: }
0451: }
0452:
0453: protected void AdjustForGravity(GridBagConstraints constraints,
0454: Rectangle r) {
0455: toolkit.lockAWT();
0456: try {
0457: // awt.8A=AdjustForGravity: attempt to use null constraints
0458: assert constraints != null : Messages.getString("awt.8A"); //$NON-NLS-1$
0459: // awt.8B=AdjustForGravity: attempt to use null rectangle
0460: assert r != null : Messages.getString("awt.8B"); //$NON-NLS-1$
0461: try {
0462: // ((GridBagConstraints) constraints).verify();
0463: } catch (IllegalArgumentException e) {
0464: // awt.8C=AdjustForGravity: {0}
0465: throw new IllegalArgumentException(Messages.getString(
0466: "awt.8C", e.getMessage())); //$NON-NLS-1$
0467: }
0468: //Don't get parent as param, so have to use older info if exists
0469: if (layoutInfo == null) {
0470: r.setBounds(0, 0, 0, 0);
0471: return;
0472: }
0473: GridBagConstraints consClone = (GridBagConstraints) constraints
0474: .clone();
0475: consClone.fill = GridBagConstraints.BOTH;
0476: ComponentSide horSide = new ComponentSide();
0477: ComponentSide vertSide = new ComponentSide();
0478: Dimension dummySize = new Dimension(0, 0);
0479: initHorCompSide(horSide, consClone, dummySize, dummySize,
0480: lastParentInfo);
0481: initVertCompSide(vertSide, consClone, dummySize, dummySize,
0482: lastParentInfo);
0483: calculateComponentBounds(horSide, vertSide, r,
0484: lastParentInfo.grid);
0485: } finally {
0486: toolkit.unlockAWT();
0487: }
0488: }
0489:
0490: private ParentInfo getParentInfo(Container parent) {
0491: if (parent == null) {
0492: return null;
0493: }
0494: if ((parent.layoutData == null)
0495: || !(parent.layoutData instanceof ParentInfo)) {
0496: parent.layoutData = new ParentInfo();
0497: }
0498: return (ParentInfo) parent.layoutData;
0499: }
0500:
0501: private void arrangeGridImpl(Container parent, ParentInfo info) {
0502: validate(parent, info);
0503: // Do not check clientRect for emptiness. Grid mus be updated anyway
0504: Rectangle clientRect = parent.getClient();
0505: info.grid.fit2Client(clientRect);
0506: }
0507:
0508: private void setComponentsBounds(ParentInfo info) {
0509: for (int i = 0; i < info.components.length; i++) {
0510: Rectangle r = new Rectangle();
0511: calculateComponentBounds(info.horCompSides[i],
0512: info.vertCompSides[i], r, info.grid);
0513: info.components[i].setBounds(r);
0514: }
0515: }
0516:
0517: private void calculateComponentBounds(ComponentSide horSide,
0518: ComponentSide vertSide, Rectangle r, Grid grid) {
0519: Rectangle dispArea = grid.componentDisplayArea(horSide,
0520: vertSide);
0521: r.width = fillDisplaySide(dispArea.width, horSide);
0522: r.height = fillDisplaySide(dispArea.height, vertSide);
0523: r.x = anchorComponentSide(dispArea.x, dispArea.width, horSide,
0524: r.width);
0525: r.y = anchorComponentSide(dispArea.y, dispArea.height,
0526: vertSide, r.height);
0527: }
0528:
0529: private int fillDisplaySide(int dispLength, ComponentSide compSide) {
0530: int l = Math.max(dispLength - compSide.start_inset
0531: - compSide.end_inset, 0);
0532: if (l < compSide.minLength) {
0533: l = Math.min(compSide.minLength, dispLength);
0534: } else if (!compSide.stretch) {
0535: l = Math.min(l, compSide.prefLength);
0536: }
0537: return l;
0538: }
0539:
0540: private int anchorComponentSide(int dispStart, int dispLength,
0541: ComponentSide compSide, int compLength) {
0542: // if (compLength == 0) {
0543: // return 0;
0544: // }
0545: int insDispLength = dispLength - compSide.start_inset
0546: - compSide.end_inset;
0547: if (compLength <= insDispLength) {
0548: int s = dispStart + compSide.start_inset;
0549: switch (compSide.position) {
0550: case ComponentSide.POS_START:
0551: break;
0552: case ComponentSide.POS_CENTER:
0553: s += (insDispLength - compLength) / 2;
0554: break;
0555: case ComponentSide.POS_END:
0556: s += insDispLength - compLength;
0557: break;
0558: }
0559: return s;
0560: }
0561: float insetFactor = (float) (dispLength - compLength)
0562: / (float) (compSide.start_inset + compSide.end_inset);
0563: return (dispStart + (int) (compSide.start_inset * insetFactor));
0564: }
0565:
0566: private void initHorCompSide(ComponentSide side,
0567: GridBagConstraints cons, Dimension minSize,
0568: Dimension prefSize, ParentInfo info) {
0569: MixedConstraints mixCons = info.consTable.get(cons);
0570: side.gridStart = mixCons.mapped.x;
0571: side.gridLength = mixCons.mapped.width;
0572: side.weight = cons.weightx;
0573: side.start_inset = cons.insets.left;
0574: side.end_inset = cons.insets.right;
0575: int anchor = translateRelativeAnchor(cons.anchor,
0576: info.orientation.isLeftToRight());
0577: switch (anchor) {
0578: case GridBagConstraints.NORTHWEST:
0579: case GridBagConstraints.WEST:
0580: case GridBagConstraints.SOUTHWEST:
0581: side.position = ComponentSide.POS_START;
0582: break;
0583: case GridBagConstraints.NORTH:
0584: case GridBagConstraints.CENTER:
0585: case GridBagConstraints.SOUTH:
0586: side.position = ComponentSide.POS_CENTER;
0587: break;
0588: default:
0589: side.position = ComponentSide.POS_END;
0590: }
0591: if ((cons.fill == GridBagConstraints.BOTH)
0592: || (cons.fill == GridBagConstraints.HORIZONTAL)) {
0593: side.stretch = true;
0594: } else {
0595: side.stretch = false;
0596: }
0597: side.minLength = minSize.width + cons.ipadx;
0598: side.prefLength = prefSize.width + cons.ipadx;
0599: }
0600:
0601: private void initVertCompSide(ComponentSide side,
0602: GridBagConstraints cons, Dimension minSize,
0603: Dimension prefSize, ParentInfo info) {
0604: MixedConstraints mixCons = info.consTable.get(cons);
0605: side.gridStart = mixCons.mapped.y;
0606: side.gridLength = mixCons.mapped.height;
0607: side.weight = cons.weighty;
0608: side.start_inset = cons.insets.top;
0609: side.end_inset = cons.insets.bottom;
0610: int anchor = translateRelativeAnchor(cons.anchor,
0611: info.orientation.isLeftToRight());
0612: switch (anchor) {
0613: case GridBagConstraints.NORTHWEST:
0614: case GridBagConstraints.NORTH:
0615: case GridBagConstraints.NORTHEAST:
0616: side.position = ComponentSide.POS_START;
0617: break;
0618: case GridBagConstraints.WEST:
0619: case GridBagConstraints.CENTER:
0620: case GridBagConstraints.EAST:
0621: side.position = ComponentSide.POS_CENTER;
0622: break;
0623: default:
0624: side.position = ComponentSide.POS_END;
0625: }
0626: if ((cons.fill == GridBagConstraints.BOTH)
0627: || (cons.fill == GridBagConstraints.VERTICAL)) {
0628: side.stretch = true;
0629: } else {
0630: side.stretch = false;
0631: }
0632: side.minLength = minSize.height + cons.ipady;
0633: side.prefLength = prefSize.height + cons.ipady;
0634: }
0635:
0636: private int translateRelativeAnchor(int relAnchor, boolean l2r) {
0637: int absAnchor = relAnchor;
0638: switch (relAnchor) {
0639: case GridBagConstraints.PAGE_START:
0640: absAnchor = GridBagConstraints.NORTH;
0641: break;
0642: case GridBagConstraints.PAGE_END:
0643: absAnchor = GridBagConstraints.SOUTH;
0644: break;
0645: case GridBagConstraints.LINE_START:
0646: absAnchor = l2r ? GridBagConstraints.WEST
0647: : GridBagConstraints.EAST;
0648: break;
0649: case GridBagConstraints.LINE_END:
0650: absAnchor = l2r ? GridBagConstraints.EAST
0651: : GridBagConstraints.WEST;
0652: break;
0653: case GridBagConstraints.FIRST_LINE_START:
0654: absAnchor = l2r ? GridBagConstraints.NORTHWEST
0655: : GridBagConstraints.NORTHEAST;
0656: break;
0657: case GridBagConstraints.FIRST_LINE_END:
0658: absAnchor = l2r ? GridBagConstraints.NORTHEAST
0659: : GridBagConstraints.NORTHWEST;
0660: break;
0661: case GridBagConstraints.LAST_LINE_START:
0662: absAnchor = l2r ? GridBagConstraints.SOUTHWEST
0663: : GridBagConstraints.SOUTHEAST;
0664: break;
0665: case GridBagConstraints.LAST_LINE_END:
0666: absAnchor = l2r ? GridBagConstraints.SOUTHEAST
0667: : GridBagConstraints.SOUTHWEST;
0668: break;
0669: }
0670: return absAnchor;
0671: }
0672:
0673: private void validate(Container parent, ParentInfo info) {
0674: if (info.valid) {
0675: return;
0676: }
0677: info.valid = true;
0678: resetCache(parent, info);
0679: info.orientation = parent.getComponentOrientation();
0680: Dimension maxSize = initCompsArray(parent, info.components);
0681: new RelativeTranslator(maxSize.width, maxSize.height)
0682: .translate(info);
0683: initCompSides(info);
0684: info.grid.validate(info);
0685: if (layoutInfo == null) {
0686: layoutInfo = new GridBagLayoutInfo(
0687: info.grid.lookupWidths(), info.grid.lookupHeights());
0688: } else {
0689: layoutInfo.update(info.grid.lookupWidths(), info.grid
0690: .lookupHeights());
0691: }
0692: }
0693:
0694: private void initCompSides(ParentInfo info) {
0695: for (int i = 0; i < info.components.length; i++) {
0696: Component comp = info.components[i];
0697: info.horCompSides[i] = new ComponentSide();
0698: initHorCompSide(info.horCompSides[i], comptable.get(comp),
0699: comp.getMinimumSize(), comp.getPreferredSize(),
0700: info);
0701: info.vertCompSides[i] = new ComponentSide();
0702: initVertCompSide(info.vertCompSides[i],
0703: comptable.get(comp), comp.getMinimumSize(), comp
0704: .getPreferredSize(), info);
0705: }
0706: }
0707:
0708: private Dimension initCompsArray(Container parent,
0709: Component[] components) {
0710: int maxW = 0;
0711: int maxH = 0;
0712: int i = 0;
0713: for (Enumeration<Component> keys = comptable.keys(); keys
0714: .hasMoreElements();) {
0715: Component comp = keys.nextElement();
0716: GridBagConstraints cons = comptable.get(comp);
0717: if ((comp.getParent() == parent) && comp.isVisible()) {
0718: components[i++] = comp;
0719: }
0720: if ((cons.gridx != GridBagConstraints.RELATIVE)
0721: && (cons.gridy != GridBagConstraints.RELATIVE)) {
0722: maxW = Math.max(maxW, cons.gridx + cons.gridwidth);
0723: maxH = Math.max(maxH, cons.gridy + cons.gridheight);
0724: }
0725: }
0726: return new Dimension(maxW, maxH);
0727: }
0728:
0729: private int getComponentsNumber(Container parent) {
0730: int componentsNumber = 0;
0731: for (Enumeration<Component> keys = comptable.keys(); keys
0732: .hasMoreElements();) {
0733: Component comp = keys.nextElement();
0734: if ((comp.getParent() == parent) && comp.isVisible()) {
0735: componentsNumber++;
0736: }
0737: }
0738: return componentsNumber;
0739: }
0740:
0741: private void resetCache(Container parent, ParentInfo info) {
0742: int componentsNumber = getComponentsNumber(parent);
0743: info.components = new Component[componentsNumber];
0744: info.horCompSides = new ComponentSide[componentsNumber];
0745: info.vertCompSides = new ComponentSide[componentsNumber];
0746: updateParentInfo(parent);
0747: }
0748:
0749: private void updateParentInfo(Container parent,
0750: GridBagConstraints gbc) {
0751: if (parent == null) {
0752: return;
0753: }
0754: ParentInfo info = getParentInfo(parent);
0755: if (!info.consTable.containsKey(gbc)) {
0756: MixedConstraints mixCons = new MixedConstraints(gbc);
0757: info.consTable.put(gbc, mixCons);
0758: info.allConstraints.add(mixCons);
0759: }
0760: }
0761:
0762: private void updateParentInfo(Container parent) {
0763: Component[] comps = parent.getComponents();
0764: for (Component element : comps) {
0765: GridBagConstraints gbc = comptable.get(element);
0766: updateParentInfo(parent, gbc);
0767: }
0768: }
0769:
0770: private class RelativeTranslator {
0771: private int curY; //Left-to-right (or vice versa)
0772:
0773: private final int curX[]; // up-to-down
0774:
0775: private int maxW; //Common for relative
0776:
0777: private int maxH; // and absolute components
0778:
0779: private boolean relWComp;
0780:
0781: private boolean relHComp;
0782:
0783: private int relEndY;
0784:
0785: private int relEndX;
0786:
0787: public RelativeTranslator(int maxW, int maxH) {
0788: this .maxW = maxW;
0789: this .maxH = maxH;
0790: curY = 0;
0791: curX = new int[MAXGRIDSIZE]; //All = 0, hope so
0792: relWComp = false;
0793: relHComp = false;
0794: relEndY = 0;
0795: relEndX = 0;
0796: }
0797:
0798: public void translate(ParentInfo info) {
0799: spreadComponents(info.allConstraints);
0800: recalculateRemainders(info.allConstraints);
0801: applyOrientation(info);
0802: }
0803:
0804: private void spreadComponents(
0805: ArrayList<MixedConstraints> allConstraints) {
0806: for (int i = 0; i < allConstraints.size(); i++) {
0807: MixedConstraints mixCons = allConstraints.get(i);
0808: // awt.8D=REMINDER component expected after RELATIVE one
0809: assert !((relWComp && (mixCons.initial.width != GridBagConstraints.REMAINDER)) || (relHComp && (mixCons.initial.height != GridBagConstraints.REMAINDER))) : Messages
0810: .getString("awt.8D"); //$NON-NLS-1$
0811: if (curY == MAXGRIDSIZE) {
0812: // awt.8E=component is out of grid's range
0813: throw new RuntimeException(Messages
0814: .getString("awt.8E")); //$NON-NLS-1$
0815: }
0816: translateHor(mixCons, translateVert(mixCons, i,
0817: allConstraints));
0818: }
0819: // awt.8D=REMINDER component expected after RELATIVE one
0820: assert !(relWComp || relHComp) : Messages
0821: .getString("awt.8D"); //$NON-NLS-1$
0822: }
0823:
0824: private void applyOrientation(ParentInfo info) {
0825: if (!info.orientation.isLeftToRight()) {
0826: for (int i = 0; i < info.allConstraints.size(); i++) {
0827: MixedConstraints mixCons = info.allConstraints
0828: .get(i);
0829: if (mixCons.relative) {
0830: mixCons.mapped.x = maxW - mixCons.mapped.x
0831: - mixCons.mapped.width;
0832: }
0833: }
0834: }
0835: }
0836:
0837: private int translateVert(MixedConstraints mixCons, int i,
0838: ArrayList<MixedConstraints> allConstraints) {
0839: int endY;
0840: if (mixCons.initial.y != GridBagConstraints.RELATIVE) {
0841: curY = mixCons.initial.y;
0842: }
0843: mixCons.mapped.y = curY;
0844: mixCons.mapped.height = Math.max(mixCons.initial.height, 1);
0845: if (mixCons.initial.height == GridBagConstraints.REMAINDER) {
0846: if (relHComp) {
0847: mixCons.mapped.y = allConstraints.get(i - 1).mapped.y + 1;
0848: relHComp = false;
0849: }
0850: endY = MAXGRIDSIZE;
0851: } else if (mixCons.initial.height == GridBagConstraints.RELATIVE) {
0852: relHComp = true;
0853: if (mixCons.initial.width != GridBagConstraints.REMAINDER) {
0854: relEndX = curX[curY] + mixCons.initial.width;
0855: } else {
0856: relEndX = MAXGRIDSIZE;
0857: }
0858: endY = mixCons.mapped.y + 1;
0859: } else {
0860: endY = mixCons.mapped.y + mixCons.mapped.height;
0861: }
0862: if (endY > MAXGRIDSIZE) {
0863: // awt.8E=component is out of grid's range
0864: throw new RuntimeException(Messages.getString("awt.8E")); //$NON-NLS-1$
0865: }
0866: maxH = Math.max(maxH, mixCons.mapped.y
0867: + mixCons.mapped.height);
0868: return endY;
0869: }
0870:
0871: private void translateHor(MixedConstraints mixCons, int endY) {
0872: int trueCurY = curY;
0873: if (mixCons.initial.x != GridBagConstraints.RELATIVE) {
0874: for (;; trueCurY++) {
0875: if (trueCurY == MAXGRIDSIZE) {
0876: // awt.8E=component is out of grid's range
0877: throw new RuntimeException(Messages
0878: .getString("awt.8E")); //$NON-NLS-1$
0879: }
0880: if (curX[trueCurY] <= mixCons.initial.x) {
0881: break;
0882: }
0883: }
0884: mixCons.mapped.y = trueCurY;
0885: mixCons.mapped.x = mixCons.initial.x;
0886: endY += trueCurY - curY;
0887: } else {
0888: mixCons.mapped.x = curX[trueCurY];
0889: }
0890: mixCons.mapped.width = Math.max(mixCons.initial.width, 1);
0891: if (mixCons.initial.width == GridBagConstraints.REMAINDER) {
0892: if (relWComp) {
0893: endY = Math.max(endY, relEndY);
0894: relWComp = false;
0895: relEndY = 0;
0896: }
0897: curY = endY;
0898: } else if (mixCons.initial.width == GridBagConstraints.RELATIVE) {
0899: relWComp = true;
0900: relEndY = endY;
0901: curX[curY]++;
0902: } else {
0903: if (!relHComp) {
0904: int endX = Math.max(curX[trueCurY]
0905: + mixCons.mapped.width, relEndX);
0906: for (int j = trueCurY; j < endY; j++) {
0907: curX[j] = endX;
0908: }
0909: relEndX = 0;
0910: }
0911: }
0912: if ((mixCons.mapped.x + mixCons.mapped.width) > MAXGRIDSIZE) {
0913: // awt.8E=component is out of grid's range
0914: throw new RuntimeException(Messages.getString("awt.8E")); //$NON-NLS-1$
0915: }
0916: maxW = Math.max(maxW, mixCons.mapped.x
0917: + mixCons.mapped.width);
0918: // if (curYBackup >= 0) { //FIX
0919: // curY = curYBackup;
0920: // curYBackup = -1;
0921: // }
0922: }
0923:
0924: private void recalculateRemainders(
0925: ArrayList<MixedConstraints> allConstraints) {
0926: for (int i = 0; i < allConstraints.size(); i++) {
0927: MixedConstraints mixCons = allConstraints.get(i);
0928: if (mixCons.initial.width == GridBagConstraints.REMAINDER) {
0929: mixCons.mapped.width = maxW - mixCons.mapped.x;
0930: } else if (mixCons.initial.width == GridBagConstraints.RELATIVE) {
0931: int reserve = maxW - mixCons.mapped.x - 2;
0932: if (reserve > 0) {
0933: mixCons.mapped.width += reserve;
0934: if ((i + 1) < allConstraints.size()) {
0935: allConstraints.get(i + 1).mapped.x += reserve;
0936: }
0937: }
0938: }
0939: if (mixCons.initial.height == GridBagConstraints.REMAINDER) {
0940: mixCons.mapped.height = maxH - mixCons.mapped.y;
0941: } else if (mixCons.initial.height == GridBagConstraints.RELATIVE) {
0942: int reserve = maxH - mixCons.mapped.y - 2;
0943: mixCons.mapped.height += reserve;
0944: if ((i + 1) < allConstraints.size()) {
0945: allConstraints.get(i + 1).mapped.y += reserve;
0946: }
0947: }
0948: }
0949: }
0950: }
0951:
0952: private class ComponentSide {
0953: public static final int POS_START = 1;
0954:
0955: public static final int POS_CENTER = 2;
0956:
0957: public static final int POS_END = 3;
0958:
0959: public int gridStart;
0960:
0961: public int gridLength;
0962:
0963: public int start_inset;
0964:
0965: public int end_inset;
0966:
0967: public int position;
0968:
0969: public int minLength;
0970:
0971: public int prefLength;
0972:
0973: public double weight;
0974:
0975: public boolean stretch;
0976: }
0977:
0978: private class Grid {
0979: private final GridSide cols = new GridSide();
0980:
0981: private final GridSide rows = new GridSide();
0982:
0983: public void validate(ParentInfo info) {
0984: cols.validate(info.horCompSides, columnWidths,
0985: columnWeights);
0986: rows.validate(info.vertCompSides, rowHeights, rowWeights);
0987: }
0988:
0989: public Dimension minimumSize() {
0990: return new Dimension(cols.getMinLength(), rows
0991: .getMinLength());
0992: }
0993:
0994: public Dimension preferredSize() {
0995: return new Dimension(cols.getPrefLength(), rows
0996: .getPrefLength());
0997: }
0998:
0999: public Rectangle componentDisplayArea(ComponentSide horSide,
1000: ComponentSide vertSide) {
1001: Segment hor = cols.componentDisplaySide(horSide.gridStart,
1002: horSide.gridLength);
1003: Segment vert = rows.componentDisplaySide(
1004: vertSide.gridStart, vertSide.gridLength);
1005: return new Rectangle(hor.start, vert.start, hor.length,
1006: vert.length);
1007: }
1008:
1009: public void fit2Client(Rectangle clientRect) {
1010: Segment horSeg = new Segment(clientRect.x, clientRect.width);
1011: cols.fit2Client(horSeg);
1012: clientRect.x = horSeg.start;
1013: clientRect.width = horSeg.length;
1014: Segment vertSeg = new Segment(clientRect.y,
1015: clientRect.height);
1016: rows.fit2Client(vertSeg);
1017: clientRect.y = vertSeg.start;
1018: clientRect.height = vertSeg.length;
1019: }
1020:
1021: public int[] getWidths() {
1022: return cols.getLengths();
1023: }
1024:
1025: public int[] getHeights() {
1026: return rows.getLengths();
1027: }
1028:
1029: public int[] lookupWidths() {
1030: return cols.lookupLengths();
1031: }
1032:
1033: public int[] lookupHeights() {
1034: return rows.lookupLengths();
1035: }
1036:
1037: public int[] lookupMinWidths() {
1038: return cols.lookupMinLengths();
1039: }
1040:
1041: public int[] lookupMinHeights() {
1042: return rows.lookupMinLengths();
1043: }
1044:
1045: public int[] lookupPrefWidths() {
1046: return cols.lookupPrefLengths();
1047: }
1048:
1049: public int[] lookupPrefHeights() {
1050: return rows.lookupPrefLengths();
1051: }
1052:
1053: public double[][] getWeights() {
1054: return new double[][] { cols.getWeights(),
1055: rows.getWeights() };
1056: }
1057:
1058: public Point getOrigin() {
1059: return new Point(cols.getOrigin(), rows.getOrigin());
1060: }
1061:
1062: public Point location(int x, int y, boolean l2r) {
1063: int col = cols.location(x);
1064: int row = Math.max(Math.min(rows.location(y),
1065: MAXGRIDSIZE - 1), 0);
1066: if (col == MAXGRIDSIZE) {
1067: col = l2r ? MAXGRIDSIZE - 1 : 0;
1068: } else if (col == -1) {
1069: col = l2r ? 0 : MAXGRIDSIZE - 1;
1070: }
1071: return new Point(col, row);
1072: }
1073:
1074: private class GridSide {
1075: private final int coordinates[] = new int[MAXGRIDSIZE];
1076:
1077: private final int lengths[] = new int[MAXGRIDSIZE];
1078:
1079: /*Cashed data. Validation controlled by parent class*/
1080: private final int minLengths[] = new int[MAXGRIDSIZE];
1081:
1082: private int minLength = 0;
1083:
1084: private final int prefLengths[] = new int[MAXGRIDSIZE];
1085:
1086: private int prefLength = 0;
1087:
1088: private final double weights[] = new double[MAXGRIDSIZE];
1089:
1090: private double weight = 0.;
1091:
1092: private int weightlessPrefLength = 0;
1093:
1094: private int weightlessMinLength = 0;
1095:
1096: private int weightyPartsNum = 0;
1097:
1098: public void validate(ComponentSide compSides[],
1099: int lengthsOverride[], double weightsOverride[]) {
1100: resetCache();
1101: spreadComponents(compSides);
1102: applyOverrides(lengthsOverride, weightsOverride);
1103: calculateIntegrals();
1104: }
1105:
1106: public int getMinLength() {
1107: return minLength;
1108: }
1109:
1110: public int getPrefLength() {
1111: return prefLength;
1112: }
1113:
1114: public Segment componentDisplaySide(int startPart,
1115: int partsNum) {
1116: int l = 0;
1117: for (int part = startPart; part < (startPart + partsNum); part++) {
1118: l += lengths[part];
1119: }
1120: return new Segment(coordinates[startPart], l);
1121: }
1122:
1123: public void fit2Client(Segment clientSide) {
1124: int start = clientSide.start;
1125: if (clientSide.length > weightlessPrefLength) {
1126: if (weight > 0.) {
1127: if (clientSide.length >= prefLength) {
1128: divideExtraWeightyLength(clientSide);
1129: } else {
1130: //divideExtraLength(clientSide);
1131: divideInsufWeightyLength(clientSide);
1132: }
1133: } else {
1134: start = centerSide(clientSide);
1135: }
1136: } else if (weightlessMinLength > clientSide.length) {
1137: divideInsufficientLength(clientSide);
1138: } else {
1139: // divideSufficientLength(clientSide);
1140: divideInsufWeightyLength(clientSide);
1141: }
1142: calculateCoordinates(start);
1143: }
1144:
1145: public int[] getLengths() {
1146: int res[] = new int[MAXGRIDSIZE];
1147: for (int i = 0; i < MAXGRIDSIZE; i++) {
1148: res[i] = lengths[i];
1149: }
1150: return res;
1151: }
1152:
1153: public int[] lookupLengths() {
1154: return lengths;
1155: }
1156:
1157: public int[] lookupMinLengths() {
1158: return minLengths;
1159: }
1160:
1161: public int[] lookupPrefLengths() {
1162: return prefLengths;
1163: }
1164:
1165: public double[] getWeights() {
1166: double res[] = new double[MAXGRIDSIZE];
1167: for (int i = 0; i < MAXGRIDSIZE; i++) {
1168: res[i] = weights[i];
1169: }
1170: return res;
1171: }
1172:
1173: public int getOrigin() {
1174: return coordinates[0];
1175: }
1176:
1177: public int location(int p) {
1178: if (p < coordinates[0]) {
1179: return -1;
1180: } else if (p >= (coordinates[MAXGRIDSIZE - 1] + lengths[MAXGRIDSIZE - 1])) {
1181: return MAXGRIDSIZE;
1182: }
1183: int i = 0;
1184: while (!((coordinates[i] <= p) && ((coordinates[i] + lengths[i]) > p))) {
1185: i++;
1186: }
1187: return i;
1188: }
1189:
1190: private void calculateIntegrals() {
1191: for (int i = 0; i < MAXGRIDSIZE; i++) {
1192: prefLength += prefLengths[i];
1193: minLength += minLengths[i];
1194: weight += weights[i];
1195: if (weights[i] == 0.) {
1196: weightlessPrefLength += prefLengths[i];
1197: weightlessMinLength += minLengths[i];
1198: weightyPartsNum++;
1199: }
1200: }
1201: }
1202:
1203: private void applyOverrides(int lengthsOverride[],
1204: double weightsOverride[]) {
1205: if (weightsOverride != null) {
1206: if (weightsOverride.length > MAXGRIDSIZE) {
1207: // awt.8F=Weights' overrides array is too long
1208: throw new RuntimeException(Messages
1209: .getString("awt.8F")); //$NON-NLS-1$
1210: }
1211: for (int i = 0; i < weightsOverride.length; i++) {
1212: weights[i] = Math.max(weights[i],
1213: weightsOverride[i]);
1214: }
1215: }
1216: if (lengthsOverride != null) {
1217: if (lengthsOverride.length > MAXGRIDSIZE) {
1218: // awt.90=Lengths' overrides array is too long
1219: throw new RuntimeException(Messages
1220: .getString("awt.90")); //$NON-NLS-1$
1221: }
1222: for (int i = 0; i < lengthsOverride.length; i++) {
1223: minLengths[i] = lengthsOverride[i];
1224: prefLengths[i] = Math.max(prefLengths[i],
1225: lengthsOverride[i]);
1226: }
1227: }
1228: }
1229:
1230: private void spreadComponents(ComponentSide compSides[]) {
1231: for (ComponentSide element : compSides) {
1232: if (element.gridLength == 1) {
1233: int insets = element.start_inset
1234: + element.end_inset;
1235: spreadUnicellularComponent(element.gridStart,
1236: element.minLength + insets,
1237: element.prefLength + insets,
1238: element.weight);
1239: }
1240: }
1241: for (ComponentSide element : compSides) {
1242: if (element.gridLength > 1) {
1243: int insets = element.start_inset
1244: + element.end_inset;
1245: spreadMulticellularComponent(element.gridStart,
1246: element.gridLength, element.minLength
1247: + insets, element.prefLength
1248: + insets, element.weight);
1249: }
1250: }
1251: }
1252:
1253: private void spreadUnicellularComponent(int part,
1254: int minCompLength, int prefCompLength,
1255: double compWeight) {
1256: minLengths[part] = Math.max(minLengths[part],
1257: minCompLength);
1258: prefLengths[part] = Math.max(prefLengths[part],
1259: prefCompLength);
1260: weights[part] = Math.max(weights[part], compWeight);
1261: }
1262:
1263: private void spreadMulticellularComponent(int startPart,
1264: int partsNum, int minCompLength,
1265: int prefCompLength, double compWeight) {
1266: double sumWeight = spreadComponentWeight(weights,
1267: startPart, partsNum, compWeight);
1268: spreadComponentLength(minLengths, startPart, partsNum,
1269: minCompLength, sumWeight);
1270: spreadComponentLength(prefLengths, startPart, partsNum,
1271: prefCompLength, sumWeight);
1272: }
1273:
1274: private void resetCache() {
1275: Arrays.fill(minLengths, 0);
1276: minLength = 0;
1277: Arrays.fill(prefLengths, 0);
1278: prefLength = 0;
1279: Arrays.fill(weights, 0.);
1280: weight = 0.;
1281: weightlessPrefLength = 0;
1282: weightlessMinLength = 0;
1283: weightyPartsNum = 0;
1284: }
1285:
1286: private void spreadComponentLength(int arr[],
1287: int startPart, int partsNum, int compLength,
1288: double sumWeight) {
1289: int rest = compLength;
1290: int lastPart = startPart + partsNum - 1;
1291: for (int part = startPart; part < lastPart; part++) {
1292: rest -= arr[part];
1293: }
1294: if (sumWeight != 0.0) {
1295: rest -= arr[lastPart];
1296: // divide extra length using weights
1297: int sharedExtraL = 0;
1298: double accumWeight = 0.0;
1299: for (int part = startPart; part <= lastPart; part++) {
1300: accumWeight += weights[part];
1301: int curExtraL = (int) (rest * (accumWeight / sumWeight))
1302: - sharedExtraL;
1303: arr[part] = Math.max(arr[part], arr[part]
1304: + curExtraL);
1305: sharedExtraL += curExtraL;
1306: }
1307: } else {
1308: // just put all extra
1309: // length into the last part
1310: arr[lastPart] = Math.max(arr[lastPart], rest);
1311: }
1312: }
1313:
1314: private double spreadComponentWeight(double arr[],
1315: int startPart, int partsNum, double compWeight) {
1316: int lastPart = startPart + partsNum - 1;
1317: double sumWeight = .0;
1318: for (int part = startPart; part <= lastPart; part++) {
1319: sumWeight += arr[part];
1320: }
1321: if ((compWeight > sumWeight) && (sumWeight > 0)) {
1322: for (int part = startPart; part < (startPart + partsNum); part++) {
1323: arr[part] = compWeight * arr[part] / sumWeight;
1324: }
1325: } else if (sumWeight == 0) {
1326: arr[lastPart] = compWeight;
1327: }
1328: return sumWeight;
1329: }
1330:
1331: private void divideExtraWeightyLength(Segment clientSide) {
1332: int extraL = clientSide.length - prefLength;
1333: int sharedExtraL = 0;
1334: double accumWeight = 0.;
1335: for (int i = 0; i < MAXGRIDSIZE; i++) {
1336: if (weights[i] > 0.) {
1337: accumWeight += weights[i];
1338: int curExtraL = (int) (extraL * (accumWeight / weight))
1339: - sharedExtraL;
1340: lengths[i] = prefLengths[i] + curExtraL;
1341: sharedExtraL += curExtraL;
1342: } else {
1343: lengths[i] = prefLengths[i];
1344: }
1345: }
1346: }
1347:
1348: private void divideInsufWeightyLength(Segment clientSide) {
1349: int extraL = clientSide.length - minLength;
1350: int sharedExtraL = 0;
1351: double accumWeight = 0.;
1352: for (int i = 0; i < MAXGRIDSIZE; i++) {
1353: if (weights[i] > 0.) {
1354: accumWeight += weights[i];
1355: int curExtraL = (int) (extraL * (accumWeight / weight))
1356: - sharedExtraL;
1357: lengths[i] = minLengths[i] + curExtraL;
1358: sharedExtraL += curExtraL;
1359: } else {
1360: lengths[i] = minLengths[i];
1361: }
1362: }
1363: }
1364:
1365: private int centerSide(Segment clientSide) {
1366: for (int i = 0; i < MAXGRIDSIZE; i++) {
1367: lengths[i] = prefLengths[i];
1368: }
1369: return (clientSide.start + (clientSide.length - prefLength) / 2);
1370: }
1371:
1372: private void divideInsufficientLength(Segment clientSide) {
1373: int sharedL = (weightlessMinLength - clientSide.length) / 2;
1374: if (sharedL < 0) {
1375: sharedL = 0;
1376: }
1377: for (int i = 0; i < MAXGRIDSIZE; i++) {
1378: if (weights[i] > 0.) {
1379: lengths[i] = 0;
1380: } else {
1381: int minL = minLengths[i];
1382: if (sharedL >= minL) {
1383: sharedL -= minL;
1384: lengths[i] = 0;
1385: } else {
1386: lengths[i] = minL - sharedL;
1387: sharedL = 0;
1388: }
1389: }
1390: }
1391: }
1392:
1393: private void calculateCoordinates(int start) {
1394: coordinates[0] = start;
1395: for (int i = 1; i < MAXGRIDSIZE; i++) {
1396: coordinates[i] = coordinates[i - 1]
1397: + lengths[i - 1];
1398: }
1399: }
1400: }
1401: }
1402:
1403: private class Segment {
1404: public int start;
1405:
1406: public int length;
1407:
1408: Segment(int start, int length) {
1409: this .start = start;
1410: this .length = length;
1411: }
1412: }
1413:
1414: private class MixedConstraints {
1415: public Rectangle initial; //Relative/Absolute
1416:
1417: public Rectangle mapped; //Absolute
1418:
1419: public boolean relative;
1420:
1421: MixedConstraints(GridBagConstraints cons) {
1422: initial = new Rectangle(cons.gridx, cons.gridy,
1423: cons.gridwidth, cons.gridheight);
1424: mapped = new Rectangle();
1425: relative = (cons.gridx == GridBagConstraints.RELATIVE)
1426: || (cons.gridy == GridBagConstraints.RELATIVE);
1427: }
1428: }
1429:
1430: private class ParentInfo {
1431: final HashMap<GridBagConstraints, MixedConstraints> consTable; // Components' constraints to relative constraints
1432:
1433: final ArrayList<MixedConstraints> allConstraints; // Only mapped rectangle is a part of cache
1434:
1435: final Grid grid;
1436:
1437: boolean valid;
1438:
1439: ComponentSide horCompSides[];
1440:
1441: ComponentSide vertCompSides[];
1442:
1443: Component components[]; // Hashtable is too slow
1444:
1445: ComponentOrientation orientation;
1446:
1447: ParentInfo() {
1448: valid = false;
1449: consTable = new HashMap<GridBagConstraints, MixedConstraints>();
1450: allConstraints = new ArrayList<MixedConstraints>();
1451: grid = new Grid();
1452: orientation = ComponentOrientation.LEFT_TO_RIGHT;
1453: horCompSides = vertCompSides = null;
1454: components = null;
1455: }
1456: }
1457: }
|